Home | History | Annotate | Download | only in gtk
      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 
     26 namespace WebCore {
     27 
     28 static void replaceNonBreakingSpaceWithSpace(String& str)
     29 {
     30     static const UChar NonBreakingSpaceCharacter = 0xA0;
     31     static const UChar SpaceCharacter = ' ';
     32     str.replace(NonBreakingSpaceCharacter, SpaceCharacter);
     33 }
     34 
     35 String DataObjectGtk::text()
     36 {
     37     if (m_range)
     38         return m_range->text();
     39     return m_text;
     40 }
     41 
     42 String DataObjectGtk::markup()
     43 {
     44     if (m_range)
     45         return createMarkup(m_range.get(), 0, AnnotateForInterchange, false, AbsoluteURLs);
     46     return m_markup;
     47 }
     48 
     49 void DataObjectGtk::setText(const String& newText)
     50 {
     51     m_range = 0;
     52     m_text = newText;
     53     replaceNonBreakingSpaceWithSpace(m_text);
     54 }
     55 
     56 void DataObjectGtk::setMarkup(const String& newMarkup)
     57 {
     58     m_range = 0;
     59     m_markup = newMarkup;
     60 }
     61 
     62 void 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 
    103 void 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 
    123 void DataObjectGtk::clearText()
    124 {
    125     m_range = 0;
    126     m_text = "";
    127 }
    128 
    129 void DataObjectGtk::clearMarkup()
    130 {
    131     m_range = 0;
    132     m_markup = "";
    133 }
    134 
    135 String DataObjectGtk::urlLabel()
    136 {
    137     if (hasText())
    138         return text();
    139 
    140     if (hasURL())
    141         return url();
    142 
    143     return String();
    144 }
    145 
    146 void 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 
    161 DataObjectGtk* 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