Home | History | Annotate | Download | only in qt
      1 /*
      2  * Copyright (C) 2006 Zack Rusin <zack (at) kde.org>
      3  * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
      4  * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
      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 "Pasteboard.h"
     30 
     31 #include "DocumentFragment.h"
     32 #include "Editor.h"
     33 #include "Frame.h"
     34 #include "Image.h"
     35 #include "RenderImage.h"
     36 #include "markup.h"
     37 #include <qapplication.h>
     38 #include <qclipboard.h>
     39 #include <qdebug.h>
     40 #include <qmimedata.h>
     41 #include <qurl.h>
     42 
     43 #define methodDebug() qDebug() << "PasteboardQt: " << __FUNCTION__;
     44 
     45 namespace WebCore {
     46 
     47 Pasteboard::Pasteboard()
     48     : m_selectionMode(false)
     49 {
     50 }
     51 
     52 Pasteboard* Pasteboard::generalPasteboard()
     53 {
     54     static Pasteboard* pasteboard = 0;
     55     if (!pasteboard)
     56         pasteboard = new Pasteboard();
     57     return pasteboard;
     58 }
     59 
     60 void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete, Frame* frame)
     61 {
     62     QMimeData* md = new QMimeData;
     63     QString text = frame->editor()->selectedText();
     64     text.replace(QChar(0xa0), QLatin1Char(' '));
     65     md->setText(text);
     66 
     67     QString markup = createMarkup(selectedRange, 0, AnnotateForInterchange, false, AbsoluteURLs);
     68 #ifdef Q_OS_MAC
     69     markup.prepend(QLatin1String("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /></head><body>"));
     70     markup.append(QLatin1String("</body></html>"));
     71     md->setData(QLatin1String("text/html"), markup.toUtf8());
     72 #else
     73     md->setHtml(markup);
     74 #endif
     75 
     76 #ifndef QT_NO_CLIPBOARD
     77     QApplication::clipboard()->setMimeData(md, m_selectionMode ? QClipboard::Selection : QClipboard::Clipboard);
     78 #endif
     79     if (canSmartCopyOrDelete)
     80         md->setData(QLatin1String("application/vnd.qtwebkit.smartpaste"), QByteArray());
     81 }
     82 
     83 bool Pasteboard::canSmartReplace()
     84 {
     85 #ifndef QT_NO_CLIPBOARD
     86     if (QApplication::clipboard()->mimeData()->hasFormat((QLatin1String("application/vnd.qtwebkit.smartpaste"))))
     87         return true;
     88 #endif
     89     return false;
     90 }
     91 
     92 String Pasteboard::plainText(Frame*)
     93 {
     94 #ifndef QT_NO_CLIPBOARD
     95     return QApplication::clipboard()->text(m_selectionMode ? QClipboard::Selection : QClipboard::Clipboard);
     96 #else
     97     return String();
     98 #endif
     99 }
    100 
    101 PassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame* frame, PassRefPtr<Range> context,
    102                                                           bool allowPlainText, bool& chosePlainText)
    103 {
    104 #ifndef QT_NO_CLIPBOARD
    105     const QMimeData* mimeData = QApplication::clipboard()->mimeData(
    106             m_selectionMode ? QClipboard::Selection : QClipboard::Clipboard);
    107 
    108     chosePlainText = false;
    109 
    110     if (mimeData->hasHtml()) {
    111         QString html = mimeData->html();
    112         if (!html.isEmpty()) {
    113             RefPtr<DocumentFragment> fragment = createFragmentFromMarkup(frame->document(), html, "", FragmentScriptingNotAllowed);
    114             if (fragment)
    115                 return fragment.release();
    116         }
    117     }
    118 
    119     if (allowPlainText && mimeData->hasText()) {
    120         chosePlainText = true;
    121         RefPtr<DocumentFragment> fragment = createFragmentFromText(context.get(), mimeData->text());
    122         if (fragment)
    123             return fragment.release();
    124     }
    125 #endif
    126     return 0;
    127 }
    128 
    129 void Pasteboard::writePlainText(const String& text)
    130 {
    131 #ifndef QT_NO_CLIPBOARD
    132     QMimeData* md = new QMimeData;
    133     QString qtext = text;
    134     qtext.replace(QChar(0xa0), QLatin1Char(' '));
    135     md->setText(qtext);
    136     QApplication::clipboard()->setMimeData(md, m_selectionMode ? QClipboard::Selection : QClipboard::Clipboard);
    137 #endif
    138 }
    139 
    140 void Pasteboard::writeURL(const KURL& url, const String&, Frame*)
    141 {
    142     ASSERT(!url.isEmpty());
    143 
    144 #ifndef QT_NO_CLIPBOARD
    145     QMimeData* md = new QMimeData;
    146     QString urlString = url.string();
    147     md->setText(urlString);
    148     md->setUrls(QList<QUrl>() << url);
    149     QApplication::clipboard()->setMimeData(md, m_selectionMode ? QClipboard::Selection : QClipboard::Clipboard);
    150 #endif
    151 }
    152 
    153 void Pasteboard::writeImage(Node* node, const KURL&, const String&)
    154 {
    155     ASSERT(node && node->renderer() && node->renderer()->isImage());
    156 
    157 #ifndef QT_NO_CLIPBOARD
    158     CachedImage* cachedImage = toRenderImage(node->renderer())->cachedImage();
    159     if (!cachedImage || cachedImage->errorOccurred())
    160         return;
    161 
    162     Image* image = cachedImage->image();
    163     ASSERT(image);
    164 
    165     QPixmap* pixmap = image->nativeImageForCurrentFrame();
    166     if (!pixmap)
    167         return;
    168     QApplication::clipboard()->setPixmap(*pixmap, QClipboard::Clipboard);
    169 #endif
    170 }
    171 
    172 /* This function is called from Editor::tryDHTMLCopy before actually set the clipboard
    173  * It introduce a race condition with klipper, which will try to grab the clipboard
    174  * It's not required to clear it anyway, since QClipboard take care about replacing the clipboard
    175  */
    176 void Pasteboard::clear()
    177 {
    178 }
    179 
    180 bool Pasteboard::isSelectionMode() const
    181 {
    182     return m_selectionMode;
    183 }
    184 
    185 void Pasteboard::setSelectionMode(bool selectionMode)
    186 {
    187     m_selectionMode = selectionMode;
    188 }
    189 
    190 }
    191