1/*
2 *  Copyright (C) 2007 Holger Hans Peter Freyther
3 *  Copyright (C) 2007 Alp Toker <alp@atoker.com>
4 *
5 *  This library is free software; you can redistribute it and/or
6 *  modify it under the terms of the GNU Lesser General Public
7 *  License as published by the Free Software Foundation; either
8 *  version 2 of the License, or (at your option) any later version.
9 *
10 *  This library is distributed in the hope that it will be useful,
11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 *  Lesser General Public License for more details.
14 *
15 *  You should have received a copy of the GNU Lesser General Public
16 *  License along with this library; if not, write to the Free Software
17 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18 */
19
20#include "config.h"
21#include "Pasteboard.h"
22
23#include "DataObjectGtk.h"
24#include "DocumentFragment.h"
25#include "Frame.h"
26#include "NotImplemented.h"
27#include "PlatformString.h"
28#include "TextResourceDecoder.h"
29#include "Image.h"
30#include "RenderImage.h"
31#include "KURL.h"
32#include "markup.h"
33#include <wtf/gobject/GRefPtr.h>
34#include <wtf/text/CString.h>
35
36#include <gtk/gtk.h>
37
38namespace WebCore {
39
40Pasteboard* Pasteboard::generalPasteboard()
41{
42    static Pasteboard* pasteboard = new Pasteboard();
43    return pasteboard;
44}
45
46Pasteboard::Pasteboard()
47{
48    notImplemented();
49}
50
51Pasteboard::~Pasteboard()
52{
53    delete m_helper;
54}
55
56PasteboardHelper* Pasteboard::helper()
57{
58    return m_helper;
59}
60
61void Pasteboard::setHelper(PasteboardHelper* helper)
62{
63    m_helper = helper;
64}
65
66void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete, Frame* frame)
67{
68    GtkClipboard* clipboard = m_helper->getClipboard(frame);
69    DataObjectGtk* dataObject = DataObjectGtk::forClipboard(clipboard);
70    dataObject->setText(frame->editor()->selectedText());
71    dataObject->setMarkup(createMarkup(selectedRange, 0, AnnotateForInterchange, false, AbsoluteURLs));
72    m_helper->writeClipboardContents(clipboard);
73}
74
75void Pasteboard::writePlainText(const String& text)
76{
77    GtkClipboard* clipboard = gtk_clipboard_get_for_display(gdk_display_get_default(), GDK_SELECTION_CLIPBOARD);
78    DataObjectGtk* dataObject = DataObjectGtk::forClipboard(clipboard);
79    dataObject->setText(text);
80    m_helper->writeClipboardContents(clipboard);
81}
82
83void Pasteboard::writeURL(const KURL& url, const String& label, Frame* frame)
84{
85    if (url.isEmpty())
86        return;
87
88    GtkClipboard* clipboard = m_helper->getClipboard(frame);
89    DataObjectGtk* dataObject = DataObjectGtk::forClipboard(clipboard);
90    dataObject->setURL(url, label);
91    m_helper->writeClipboardContents(clipboard);
92}
93
94void Pasteboard::writeImage(Node* node, const KURL&, const String&)
95{
96    GtkClipboard* clipboard = gtk_clipboard_get_for_display(gdk_display_get_default(), GDK_SELECTION_CLIPBOARD);
97
98    ASSERT(node && node->renderer() && node->renderer()->isImage());
99    RenderImage* renderer = toRenderImage(node->renderer());
100    CachedImage* cachedImage = renderer->cachedImage();
101    if (!cachedImage || cachedImage->errorOccurred())
102        return;
103    Image* image = cachedImage->image();
104    ASSERT(image);
105
106    GRefPtr<GdkPixbuf> pixbuf = adoptGRef(image->getGdkPixbuf());
107    DataObjectGtk* dataObject = DataObjectGtk::forClipboard(clipboard);
108    dataObject->setImage(pixbuf.get());
109    m_helper->writeClipboardContents(clipboard);
110}
111
112void Pasteboard::clear()
113{
114    gtk_clipboard_clear(gtk_clipboard_get_for_display(gdk_display_get_default(), GDK_SELECTION_CLIPBOARD));
115}
116
117bool Pasteboard::canSmartReplace()
118{
119    notImplemented();
120    return false;
121}
122
123PassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame* frame, PassRefPtr<Range> context,
124                                                          bool allowPlainText, bool& chosePlainText)
125{
126    GtkClipboard* clipboard = m_helper->getCurrentClipboard(frame);
127    DataObjectGtk* dataObject = DataObjectGtk::forClipboard(clipboard);
128    m_helper->getClipboardContents(clipboard);
129
130    chosePlainText = false;
131
132    if (dataObject->hasMarkup()) {
133        RefPtr<DocumentFragment> fragment = createFragmentFromMarkup(frame->document(), dataObject->markup(), "", FragmentScriptingNotAllowed);
134        if (fragment)
135            return fragment.release();
136    }
137
138    if (!allowPlainText)
139        return 0;
140
141    if (dataObject->hasText()) {
142        chosePlainText = true;
143        RefPtr<DocumentFragment> fragment = createFragmentFromText(context.get(), dataObject->text());
144        if (fragment)
145            return fragment.release();
146    }
147
148    return 0;
149}
150
151String Pasteboard::plainText(Frame* frame)
152{
153    GtkClipboard* clipboard = m_helper->getCurrentClipboard(frame);
154    DataObjectGtk* dataObject = DataObjectGtk::forClipboard(clipboard);
155
156    m_helper->getClipboardContents(clipboard);
157    return dataObject->text();
158}
159
160}
161