2 * This library is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU Lesser General Public
4 * License as published by the Free Software Foundation; either
5 * version 2 of the License, or (at your option) any later version.
7 * This library is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * Lesser General Public License for more details.
12 * You should have received a copy of the GNU Lesser General Public
13 * License along with this library; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 #include "ClipboardGtk.h"
20 #include "CachedImage.h"
26 #include "HTMLNames.h"
28 #include "NotImplemented.h"
29 #include "Pasteboard.h"
30 #include "PasteboardHelper.h"
31 #include "RenderImage.h"
32 #include "ScriptExecutionContext.h"
34 #include <wtf/text/CString.h>
35 #include <wtf/text/StringHash.h>
40 enum ClipboardDataType {
41 ClipboardDataTypeText,
42 ClipboardDataTypeMarkup,
43 ClipboardDataTypeURIList,
45 ClipboardDataTypeImage,
46 ClipboardDataTypeUnknown
49 PassRefPtr<Clipboard> Editor::newGeneralClipboard(ClipboardAccessPolicy policy, Frame* frame)
51 return ClipboardGtk::create(policy, gtk_clipboard_get_for_display(gdk_display_get_default(), GDK_SELECTION_CLIPBOARD), frame);
54 PassRefPtr<Clipboard> Clipboard::create(ClipboardAccessPolicy policy, DragData* dragData, Frame* frame)
56 return ClipboardGtk::create(policy, dragData->platformData(), DragAndDrop, frame);
59 ClipboardGtk::ClipboardGtk(ClipboardAccessPolicy policy, GtkClipboard* clipboard, Frame* frame)
60 : Clipboard(policy, CopyAndPaste)
61 , m_dataObject(DataObjectGtk::forClipboard(clipboard))
62 , m_clipboard(clipboard)
63 , m_helper(Pasteboard::generalPasteboard()->helper())
68 ClipboardGtk::ClipboardGtk(ClipboardAccessPolicy policy, PassRefPtr<DataObjectGtk> dataObject, ClipboardType clipboardType, Frame* frame)
69 : Clipboard(policy, clipboardType)
70 , m_dataObject(dataObject)
72 , m_helper(Pasteboard::generalPasteboard()->helper())
77 ClipboardGtk::~ClipboardGtk()
81 static ClipboardDataType dataObjectTypeFromHTMLClipboardType(const String& rawType)
83 String type(rawType.stripWhiteSpace());
85 // Two special cases for IE compatibility
86 if (type == "Text" || type == "text")
87 return ClipboardDataTypeText;
89 return ClipboardDataTypeURL;
91 // From the Mac port: Ignore any trailing charset - JS strings are
92 // Unicode, which encapsulates the charset issue.
93 if (type == "text/plain" || type.startsWith("text/plain;"))
94 return ClipboardDataTypeText;
95 if (type == "text/html" || type.startsWith("text/html;"))
96 return ClipboardDataTypeMarkup;
97 if (type == "Files" || type == "text/uri-list" || type.startsWith("text/uri-list;"))
98 return ClipboardDataTypeURIList;
100 // Not a known type, so just default to using the text portion.
101 return ClipboardDataTypeUnknown;
104 void ClipboardGtk::clearData(const String& typeString)
106 if (policy() != ClipboardWritable)
109 ClipboardDataType type = dataObjectTypeFromHTMLClipboardType(typeString);
111 case ClipboardDataTypeURIList:
112 case ClipboardDataTypeURL:
113 m_dataObject->clearURIList();
115 case ClipboardDataTypeMarkup:
116 m_dataObject->clearMarkup();
118 case ClipboardDataTypeText:
119 m_dataObject->clearText();
121 case ClipboardDataTypeUnknown:
123 m_dataObject->clear();
127 m_helper->writeClipboardContents(m_clipboard);
131 void ClipboardGtk::clearAllData()
133 if (policy() != ClipboardWritable)
136 m_dataObject->clear();
139 m_helper->writeClipboardContents(m_clipboard);
142 String ClipboardGtk::getData(const String& typeString, bool& success) const
144 success = true; // According to http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html
145 // "The getData(format) method must return the data that is associated with the type format converted
146 // to ASCII lowercase, if any, and must return the empty string otherwise." Since success == false
147 // results in an 'undefined' return value, we always want to return success == true. This parameter
148 // should eventually be removed.
149 if (policy() != ClipboardReadable || !m_dataObject)
153 m_helper->getClipboardContents(m_clipboard);
155 ClipboardDataType type = dataObjectTypeFromHTMLClipboardType(typeString);
156 if (type == ClipboardDataTypeURIList)
157 return m_dataObject->uriList();
158 if (type == ClipboardDataTypeURL)
159 return m_dataObject->url();
160 if (type == ClipboardDataTypeMarkup)
161 return m_dataObject->markup();
162 if (type == ClipboardDataTypeText)
163 return m_dataObject->text();
168 bool ClipboardGtk::setData(const String& typeString, const String& data)
170 if (policy() != ClipboardWritable)
173 bool success = false;
174 ClipboardDataType type = dataObjectTypeFromHTMLClipboardType(typeString);
175 if (type == ClipboardDataTypeURIList || type == ClipboardDataTypeURL) {
176 m_dataObject->setURIList(data);
178 } else if (type == ClipboardDataTypeMarkup) {
179 m_dataObject->setMarkup(data);
181 } else if (type == ClipboardDataTypeText) {
182 m_dataObject->setText(data);
186 if (success && m_clipboard)
187 m_helper->writeClipboardContents(m_clipboard);
192 HashSet<String> ClipboardGtk::types() const
194 if (policy() != ClipboardReadable && policy() != ClipboardTypesReadable)
195 return HashSet<String>();
198 m_helper->getClipboardContents(m_clipboard);
200 HashSet<String> types;
201 if (m_dataObject->hasText()) {
202 types.add("text/plain");
207 if (m_dataObject->hasMarkup())
208 types.add("text/html");
210 if (m_dataObject->hasURIList()) {
211 types.add("text/uri-list");
215 if (m_dataObject->hasFilenames())
221 PassRefPtr<FileList> ClipboardGtk::files() const
223 if (policy() != ClipboardReadable)
224 return FileList::create();
227 m_helper->getClipboardContents(m_clipboard);
229 RefPtr<FileList> fileList = FileList::create();
230 const Vector<String>& filenames = m_dataObject->filenames();
231 for (size_t i = 0; i < filenames.size(); i++)
232 fileList->append(File::create(filenames[i]));
233 return fileList.release();
236 void ClipboardGtk::setDragImage(CachedImage* image, const IntPoint& location)
238 setDragImage(image, 0, location);
241 void ClipboardGtk::setDragImageElement(Node* element, const IntPoint& location)
243 setDragImage(0, element, location);
246 void ClipboardGtk::setDragImage(CachedImage* image, Node* element, const IntPoint& location)
248 if (policy() != ClipboardImageWritable && policy() != ClipboardWritable)
252 m_dragImage->removeClient(this);
255 m_dragImage->addClient(this);
257 m_dragLoc = location;
258 m_dragImageElement = element;
261 DragImageRef ClipboardGtk::createDragImage(IntPoint& location) const
263 location = m_dragLoc;
267 return createDragImageFromImage(m_dragImage->image());
270 static CachedImage* getCachedImage(Element* element)
272 // Attempt to pull CachedImage from element
274 RenderObject* renderer = element->renderer();
275 if (!renderer || !renderer->isImage())
278 RenderImage* image = static_cast<RenderImage*>(renderer);
279 if (image->cachedImage() && !image->cachedImage()->errorOccurred())
280 return image->cachedImage();
285 void ClipboardGtk::declareAndWriteDragImage(Element* element, const KURL& url, const String& label, Frame* frame)
287 m_dataObject->setURL(url, label);
288 m_dataObject->setMarkup(createMarkup(element, IncludeNode, 0, AbsoluteURLs));
290 CachedImage* image = getCachedImage(element);
291 if (!image || !image->isLoaded())
294 GRefPtr<GdkPixbuf> pixbuf = adoptGRef(image->image()->getGdkPixbuf());
298 m_dataObject->setImage(pixbuf.get());
301 void ClipboardGtk::writeURL(const KURL& url, const String& label, Frame*)
303 m_dataObject->setURL(url, label);
305 m_helper->writeClipboardContents(m_clipboard);
308 void ClipboardGtk::writeRange(Range* range, Frame* frame)
312 m_dataObject->setText(frame->editor()->selectedText());
313 m_dataObject->setMarkup(createMarkup(range, 0, AnnotateForInterchange, false, AbsoluteURLs));
316 m_helper->writeClipboardContents(m_clipboard);
319 void ClipboardGtk::writePlainText(const String& text)
321 m_dataObject->setText(text);
324 m_helper->writeClipboardContents(m_clipboard);
327 bool ClipboardGtk::hasData()
330 m_helper->getClipboardContents(m_clipboard);
332 return m_dataObject->hasText() || m_dataObject->hasMarkup()
333 || m_dataObject->hasURIList() || m_dataObject->hasImage();