Build fix for Qt, Gtk, and Wx.
[WebKit-https.git] / WebCore / platform / qt / ClipboardQt.cpp
1 /*
2  * Copyright (C) 2007 Apple Inc.  All rights reserved.
3  * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
4  * Copyright (C) 2007 Trolltech ASA
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
16  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
19  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
26  */
27
28 #include "config.h"
29 #include "ClipboardQt.h"
30
31 #include "CachedImage.h"
32 #include "CSSHelper.h"
33 #include "DeprecatedString.h"
34 #include "Document.h"
35 #include "Element.h"
36 #include "Frame.h"
37 #include "HTMLNames.h"
38 #include "Image.h"
39 #include "IntPoint.h"
40 #include "KURL.h"
41 #include "markup.h"
42 #include "PlatformString.h"
43 #include "Range.h"
44 #include "RenderImage.h"
45 #include "StringHash.h"
46 #include <QList>
47 #include <QMimeData>
48 #include <QStringList>
49 #include <QUrl>
50 #include <QApplication>
51 #include <QClipboard>
52 #include <qdebug.h>
53
54 #define methodDebug() qDebug("ClipboardQt: %s", __FUNCTION__)
55
56 namespace WebCore {
57
58 ClipboardQt::ClipboardQt(ClipboardAccessPolicy policy, const QMimeData* readableClipboard)
59     : Clipboard(policy, true)
60     , m_readableData(readableClipboard)
61     , m_writableData(0)
62
63     Q_ASSERT(policy == ClipboardReadable || policy == ClipboardTypesReadable);
64 }    
65
66 ClipboardQt::ClipboardQt(ClipboardAccessPolicy policy, bool forDragging)
67     : Clipboard(policy, forDragging)
68     , m_readableData(0)
69     , m_writableData(0)
70 {
71     Q_ASSERT(policy == ClipboardReadable || policy == ClipboardWritable || policy == ClipboardNumb);
72
73     if (policy != ClipboardWritable) {
74         Q_ASSERT(!forDragging);
75         m_readableData = QApplication::clipboard()->mimeData();
76     } 
77 }
78
79 ClipboardQt::~ClipboardQt()
80 {
81     if (m_writableData && !isForDragging())
82         m_writableData = 0;
83     else
84         delete m_writableData;
85     m_readableData = 0;
86 }
87
88 void ClipboardQt::clearData(const String& type)
89 {
90     if (policy() != ClipboardWritable)
91         return;
92
93     if (m_writableData) {
94 #if QT_VERSION >= 0x040400
95         m_writableData->removeFormat(type);
96 #else
97         const QString toClearType = type;
98         QMap<QString, QByteArray> formats;
99         foreach (QString format, m_writableData->formats()) {
100             if (format != toClearType)
101                 formats[format] = m_writableData->data(format);
102         }
103         
104         m_writableData->clear();
105         QMap<QString, QByteArray>::const_iterator it, end = formats.constEnd();
106         for (it = formats.begin(); it != end; ++it)
107             m_writableData->setData(it.key(), it.value());
108 #endif
109         if (m_writableData->formats().isEmpty()) {
110             if (isForDragging())
111                 delete m_writableData;
112             m_writableData = 0;
113         }
114     }
115     if (!isForDragging())
116         QApplication::clipboard()->setMimeData(m_writableData);
117 }
118
119 void ClipboardQt::clearAllData() 
120 {
121     if (policy() != ClipboardWritable)
122         return;
123     
124     if (!isForDragging())
125         QApplication::clipboard()->setMimeData(0);
126     else
127         delete m_writableData;
128     m_writableData = 0;
129 }
130
131 String ClipboardQt::getData(const String& type, bool& success) const 
132 {
133
134     if (policy() != ClipboardReadable) {
135         success = false;
136         return String();
137     }
138     
139     ASSERT(m_readableData);
140     QByteArray data = m_readableData->data(QString(type));
141     success = !data.isEmpty();
142     return String(data.data(), data.size());
143 }
144
145 bool ClipboardQt::setData(const String& type, const String& data) 
146 {
147     if (policy() != ClipboardWritable)
148         return false;
149
150     if (!m_writableData)
151         m_writableData = new QMimeData;
152     QByteArray array(reinterpret_cast<const char*>(data.characters()),
153                      data.length()*2);
154     m_writableData->setData(QString(type), array);
155     if (!isForDragging())
156         QApplication::clipboard()->setMimeData(m_writableData);
157     return true;
158 }
159
160 // extensions beyond IE's API
161 HashSet<String> ClipboardQt::types() const
162 {
163     if (policy() != ClipboardReadable && policy() != ClipboardTypesReadable)
164         return HashSet<String>();
165
166     ASSERT(m_readableData);
167     HashSet<String> result;
168     QStringList formats = m_readableData->formats();
169     for (int i = 0; i < formats.count(); ++i)
170         result.add(formats.at(i));
171     return result;
172 }
173
174 void ClipboardQt::setDragImage(CachedImage* image, const IntPoint& point) 
175 {
176     setDragImage(image, 0, point);
177 }
178
179 void ClipboardQt::setDragImageElement(Node* node, const IntPoint& point)
180 {
181     setDragImage(0, node, point);
182 }
183
184 void ClipboardQt::setDragImage(CachedImage* image, Node *node, const IntPoint &loc)
185 {
186     if (policy() != ClipboardImageWritable && policy() != ClipboardWritable)
187         return;
188
189     if (m_dragImage)
190         m_dragImage->deref(this);
191     m_dragImage = image;
192     if (m_dragImage)
193         m_dragImage->ref(this);
194     
195     m_dragLoc = loc;
196     m_dragImageElement = node;
197 }
198
199 DragImageRef ClipboardQt::createDragImage(IntPoint& dragLoc) const
200 {
201     if (!m_dragImage)
202         return 0;
203     dragLoc = m_dragLoc;
204     return m_dragImage->image()->getPixmap();
205 }
206
207
208 static CachedImage* getCachedImage(Element* element)
209 {
210     // Attempt to pull CachedImage from element
211     ASSERT(element);
212     RenderObject* renderer = element->renderer();
213     if (!renderer || !renderer->isImage()) 
214         return 0;
215     
216     RenderImage* image = static_cast<RenderImage*>(renderer);
217     if (image->cachedImage() && !image->cachedImage()->errorOccurred())
218         return image->cachedImage();
219
220     return 0;
221 }
222
223 void ClipboardQt::declareAndWriteDragImage(Element* element, const KURL& url, const String& title, Frame* frame) 
224 {
225     ASSERT(frame);
226     Q_UNUSED(url);
227     Q_UNUSED(title);
228
229     //WebCore::writeURL(m_writableDataObject.get(), url, title, true, false);
230     if (!m_writableData)
231         m_writableData = new QMimeData;
232
233     CachedImage* cachedImage = getCachedImage(element);
234     if (!cachedImage || !cachedImage->image() || !cachedImage->isLoaded())
235         return;
236     QPixmap *pixmap = cachedImage->image()->getPixmap();
237     if (pixmap)
238         m_writableData->setImageData(pixmap);
239
240     AtomicString imageURL = element->getAttribute(HTMLNames::srcAttr);
241     if (imageURL.isEmpty()) 
242         return;
243
244     String fullURL = frame->document()->completeURL(parseURL(imageURL));
245     if (fullURL.isEmpty()) 
246         return;
247
248     QList<QUrl> urls;
249     urls.append(QUrl(fullURL));
250
251     m_writableData->setUrls(urls);
252     if (!isForDragging())
253         QApplication::clipboard()->setMimeData(m_writableData);
254 }
255
256 void ClipboardQt::writeURL(const KURL& url, const String&, Frame* frame) 
257 {
258     ASSERT(frame);
259     
260     QList<QUrl> urls;
261     urls.append(QUrl(frame->document()->completeURL(url.deprecatedString())));
262     if (!m_writableData)
263         m_writableData = new QMimeData;
264     m_writableData->setUrls(urls);
265     if (!isForDragging())
266         QApplication::clipboard()->setMimeData(m_writableData);
267 }
268
269 void ClipboardQt::writeRange(Range* range, Frame* frame) 
270 {
271     ASSERT(range);
272     ASSERT(frame);
273     
274     if (!m_writableData)
275         m_writableData = new QMimeData;
276     QString text = frame->selectedText();
277     text.replace(QChar(0xa0), QLatin1Char(' '));
278     m_writableData->setText(text);
279     m_writableData->setHtml(createMarkup(range, 0, AnnotateForInterchange));
280     if (!isForDragging())
281         QApplication::clipboard()->setMimeData(m_writableData);
282 }
283
284 bool ClipboardQt::hasData() 
285 {
286     const QMimeData *data = m_readableData ? m_readableData : m_writableData;
287     if (!data)
288         return false;
289     return data->formats().count() > 0;
290 }
291
292 }