1/*
2 * Copyright (C) 2009, Martin Robinson
3 *
4 *  This library is free software; you can redistribute it and/or
5 *  modify it under the terms of the GNU Lesser General Public
6 *  License as published by the Free Software Foundation; either
7 *  version 2 of the License, or (at your option) any later version.
8 *
9 *  This library is distributed in the hope that it will be useful,
10 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 *  Lesser General Public License for more details.
13 *
14 *  You should have received a copy of the GNU Lesser General Public
15 *  License along with this library; if not, write to the Free Software
16 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17 */
18
19#include "config.h"
20#include "DataObjectGtk.h"
21
22#include "markup.h"
23#include <gtk/gtk.h>
24#include <wtf/gobject/GOwnPtr.h>
25
26namespace WebCore {
27
28static void replaceNonBreakingSpaceWithSpace(String& str)
29{
30    static const UChar NonBreakingSpaceCharacter = 0xA0;
31    static const UChar SpaceCharacter = ' ';
32    str.replace(NonBreakingSpaceCharacter, SpaceCharacter);
33}
34
35String DataObjectGtk::text()
36{
37    if (m_range)
38        return m_range->text();
39    return m_text;
40}
41
42String DataObjectGtk::markup()
43{
44    if (m_range)
45        return createMarkup(m_range.get(), 0, AnnotateForInterchange, false, AbsoluteURLs);
46    return m_markup;
47}
48
49void DataObjectGtk::setText(const String& newText)
50{
51    m_range = 0;
52    m_text = newText;
53    replaceNonBreakingSpaceWithSpace(m_text);
54}
55
56void DataObjectGtk::setMarkup(const String& newMarkup)
57{
58    m_range = 0;
59    m_markup = newMarkup;
60}
61
62void DataObjectGtk::setURIList(const String& uriListString)
63{
64    m_uriList = uriListString;
65
66    // This code is originally from: platform/chromium/ChromiumDataObject.cpp.
67    // FIXME: We should make this code cross-platform eventually.
68
69    // Line separator is \r\n per RFC 2483 - however, for compatibility
70    // reasons we also allow just \n here.
71    Vector<String> uriList;
72    uriListString.split('\n', uriList);
73
74    // Process the input and copy the first valid URL into the url member.
75    // In case no URLs can be found, subsequent calls to getData("URL")
76    // will get an empty string. This is in line with the HTML5 spec (see
77    // "The DragEvent and DataTransfer interfaces"). Also extract all filenames
78    // from the URI list.
79    bool setURL = false;
80    for (size_t i = 0; i < uriList.size(); ++i) {
81        String& line = uriList[i];
82        line = line.stripWhiteSpace();
83        if (line.isEmpty())
84            continue;
85        if (line[0] == '#')
86            continue;
87
88        KURL url = KURL(KURL(), line);
89        if (url.isValid()) {
90            if (!setURL) {
91                m_url = url;
92                setURL = true;
93            }
94
95            GOwnPtr<GError> error;
96            GOwnPtr<gchar> filename(g_filename_from_uri(line.utf8().data(), 0, &error.outPtr()));
97            if (!error && filename)
98                m_filenames.append(String::fromUTF8(filename.get()));
99        }
100    }
101}
102
103void DataObjectGtk::setURL(const KURL& url, const String& label)
104{
105    m_url = url;
106    m_uriList = url;
107    setText(url.string());
108
109    String actualLabel(label);
110    if (actualLabel.isEmpty())
111        actualLabel = url;
112
113    Vector<UChar> markup;
114    append(markup, "<a href=\"");
115    append(markup, url.string());
116    append(markup, "\">");
117    GOwnPtr<gchar> escaped(g_markup_escape_text(actualLabel.utf8().data(), -1));
118    append(markup, String::fromUTF8(escaped.get()));
119    append(markup, "</a>");
120    setMarkup(String::adopt(markup));
121}
122
123void DataObjectGtk::clearText()
124{
125    m_range = 0;
126    m_text = "";
127}
128
129void DataObjectGtk::clearMarkup()
130{
131    m_range = 0;
132    m_markup = "";
133}
134
135String DataObjectGtk::urlLabel()
136{
137    if (hasText())
138        return text();
139
140    if (hasURL())
141        return url();
142
143    return String();
144}
145
146void DataObjectGtk::clear()
147{
148    m_text = "";
149    m_markup = "";
150    m_uriList = "";
151    m_url = KURL();
152    m_image = 0;
153    m_range = 0;
154
155    // We do not clear filenames. According to the spec: "The clearData() method
156    // does not affect whether any files were included in the drag, so the types
157    // attribute's list might still not be empty after calling clearData() (it would
158    // still contain the "Files" string if any files were included in the drag)."
159}
160
161DataObjectGtk* DataObjectGtk::forClipboard(GtkClipboard* clipboard)
162{
163    static HashMap<GtkClipboard*, RefPtr<DataObjectGtk> > objectMap;
164
165    if (!objectMap.contains(clipboard)) {
166        RefPtr<DataObjectGtk> dataObject = DataObjectGtk::create();
167        objectMap.set(clipboard, dataObject);
168        return dataObject.get();
169    }
170
171    HashMap<GtkClipboard*, RefPtr<DataObjectGtk> >::iterator it = objectMap.find(clipboard);
172    return it->second.get();
173}
174
175}
176