18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2006 Zack Rusin <zack@kde.org> 38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. 48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) 58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met: 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer. 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * documentation and/or other materials provided with the distribution. 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h" 298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Pasteboard.h" 308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "DocumentFragment.h" 328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Editor.h" 338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Frame.h" 348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Image.h" 358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderImage.h" 3665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "markup.h" 3765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <qapplication.h> 388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <qclipboard.h> 3965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <qdebug.h> 408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <qmimedata.h> 418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <qurl.h> 428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define methodDebug() qDebug() << "PasteboardQt: " << __FUNCTION__; 448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore { 460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochPasteboard::Pasteboard() 488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project : m_selectionMode(false) 498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPasteboard* Pasteboard::generalPasteboard() 538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project static Pasteboard* pasteboard = 0; 558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!pasteboard) 568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project pasteboard = new Pasteboard(); 578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return pasteboard; 588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 6021939df44de1705786c545cd1bf519d47250322dBen Murdochvoid Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete, Frame* frame) 618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project QMimeData* md = new QMimeData; 635abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick QString text = frame->editor()->selectedText(); 648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project text.replace(QChar(0xa0), QLatin1Char(' ')); 658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project md->setText(text); 668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 67cad810f21b803229eb11403f9209855525a25d57Steve Block QString markup = createMarkup(selectedRange, 0, AnnotateForInterchange, false, AbsoluteURLs); 68cad810f21b803229eb11403f9209855525a25d57Steve Block#ifdef Q_OS_MAC 69cad810f21b803229eb11403f9209855525a25d57Steve Block markup.prepend(QLatin1String("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /></head><body>")); 70cad810f21b803229eb11403f9209855525a25d57Steve Block markup.append(QLatin1String("</body></html>")); 71cad810f21b803229eb11403f9209855525a25d57Steve Block md->setData(QLatin1String("text/html"), markup.toUtf8()); 72cad810f21b803229eb11403f9209855525a25d57Steve Block#else 73cad810f21b803229eb11403f9209855525a25d57Steve Block md->setHtml(markup); 74cad810f21b803229eb11403f9209855525a25d57Steve Block#endif 758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef QT_NO_CLIPBOARD 7765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch QApplication::clipboard()->setMimeData(md, m_selectionMode ? QClipboard::Selection : QClipboard::Clipboard); 788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 7921939df44de1705786c545cd1bf519d47250322dBen Murdoch if (canSmartCopyOrDelete) 802bde8e466a4451c7319e3a072d118917957d6554Steve Block md->setData(QLatin1String("application/vnd.qtwebkit.smartpaste"), QByteArray()); 818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool Pasteboard::canSmartReplace() 848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 854576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang#ifndef QT_NO_CLIPBOARD 8621939df44de1705786c545cd1bf519d47250322dBen Murdoch if (QApplication::clipboard()->mimeData()->hasFormat((QLatin1String("application/vnd.qtwebkit.smartpaste")))) 8721939df44de1705786c545cd1bf519d47250322dBen Murdoch return true; 884576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang#endif 898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectString Pasteboard::plainText(Frame*) 938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef QT_NO_CLIPBOARD 9565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return QApplication::clipboard()->text(m_selectionMode ? QClipboard::Selection : QClipboard::Clipboard); 968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#else 978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return String(); 988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame* frame, PassRefPtr<Range> context, 1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool allowPlainText, bool& chosePlainText) 1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef QT_NO_CLIPBOARD 1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const QMimeData* mimeData = QApplication::clipboard()->mimeData( 1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_selectionMode ? QClipboard::Selection : QClipboard::Clipboard); 1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project chosePlainText = false; 1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (mimeData->hasHtml()) { 1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project QString html = mimeData->html(); 1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!html.isEmpty()) { 113d0825bca7fe65beaee391d30da42e937db621564Steve Block RefPtr<DocumentFragment> fragment = createFragmentFromMarkup(frame->document(), html, "", FragmentScriptingNotAllowed); 1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (fragment) 1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return fragment.release(); 1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (allowPlainText && mimeData->hasText()) { 1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project chosePlainText = true; 1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RefPtr<DocumentFragment> fragment = createFragmentFromText(context.get(), mimeData->text()); 1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (fragment) 1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return fragment.release(); 1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 129231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid Pasteboard::writePlainText(const String& text) 130231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 131231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#ifndef QT_NO_CLIPBOARD 132231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block QMimeData* md = new QMimeData; 133231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block QString qtext = text; 134231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block qtext.replace(QChar(0xa0), QLatin1Char(' ')); 135231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block md->setText(qtext); 13665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch QApplication::clipboard()->setMimeData(md, m_selectionMode ? QClipboard::Selection : QClipboard::Clipboard); 137231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#endif 138231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 139231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 14065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid Pasteboard::writeURL(const KURL& url, const String&, Frame*) 1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 14265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch ASSERT(!url.isEmpty()); 1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef QT_NO_CLIPBOARD 1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project QMimeData* md = new QMimeData; 14665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch QString urlString = url.string(); 14765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch md->setText(urlString); 14865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch md->setUrls(QList<QUrl>() << url); 14965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch QApplication::clipboard()->setMimeData(md, m_selectionMode ? QClipboard::Selection : QClipboard::Clipboard); 1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Pasteboard::writeImage(Node* node, const KURL&, const String&) 1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(node && node->renderer() && node->renderer()->isImage()); 1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef QT_NO_CLIPBOARD 1580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch CachedImage* cachedImage = toRenderImage(node->renderer())->cachedImage(); 159692e5dbf12901edacf14812a6fae25462920af42Steve Block if (!cachedImage || cachedImage->errorOccurred()) 160692e5dbf12901edacf14812a6fae25462920af42Steve Block return; 1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Image* image = cachedImage->image(); 1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(image); 1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project QPixmap* pixmap = image->nativeImageForCurrentFrame(); 166545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch if (!pixmap) 167545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch return; 1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project QApplication::clipboard()->setPixmap(*pixmap, QClipboard::Clipboard); 1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* This function is called from Editor::tryDHTMLCopy before actually set the clipboard 1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * It introduce a race condition with klipper, which will try to grab the clipboard 1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * It's not required to clear it anyway, since QClipboard take care about replacing the clipboard 1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Pasteboard::clear() 1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool Pasteboard::isSelectionMode() const 1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return m_selectionMode; 1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Pasteboard::setSelectionMode(bool selectionMode) 1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_selectionMode = selectionMode; 1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 191