c9e7c1e12fe269dc400bf3c885aad062dfbb5fe9
[WebKit-https.git] / Source / WebCore / platform / qt / PasteboardQt.cpp
1 /*
2  * Copyright (C) 2006 Zack Rusin <zack@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, ResolveNonLocalURLs);
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);
156
157     if (!(node->renderer() && node->renderer()->isImage()))
158         return;
159
160 #ifndef QT_NO_CLIPBOARD
161     CachedImage* cachedImage = toRenderImage(node->renderer())->cachedImage();
162     if (!cachedImage || cachedImage->errorOccurred())
163         return;
164
165     Image* image = cachedImage->imageForRenderer(node->renderer());
166     ASSERT(image);
167
168     QPixmap* pixmap = image->nativeImageForCurrentFrame();
169     if (!pixmap)
170         return;
171     QApplication::clipboard()->setPixmap(*pixmap, QClipboard::Clipboard);
172 #endif
173 }
174
175 /* This function is called from Editor::tryDHTMLCopy before actually set the clipboard
176  * It introduce a race condition with klipper, which will try to grab the clipboard 
177  * It's not required to clear it anyway, since QClipboard take care about replacing the clipboard
178  */
179 void Pasteboard::clear()
180 {
181 }
182
183 bool Pasteboard::isSelectionMode() const
184 {
185     return m_selectionMode;
186 }
187
188 void Pasteboard::setSelectionMode(bool selectionMode)
189 {
190     m_selectionMode = selectionMode;
191 }
192
193 }