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