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 "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
Pasteboard()48 Pasteboard::Pasteboard()
49 : m_selectionMode(false)
50 {
51 }
52
generalPasteboard()53 Pasteboard* Pasteboard::generalPasteboard()
54 {
55 static Pasteboard* pasteboard = 0;
56 if (!pasteboard)
57 pasteboard = new Pasteboard();
58 return pasteboard;
59 }
60
writeSelection(Range * selectedRange,bool,Frame * frame)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
canSmartReplace()79 bool Pasteboard::canSmartReplace()
80 {
81 return false;
82 }
83
plainText(Frame *)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
documentFragment(Frame * frame,PassRefPtr<Range> context,bool allowPlainText,bool & chosePlainText)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, "");
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
writeURL(const KURL & _url,const String &,Frame *)122 void Pasteboard::writeURL(const KURL& _url, const String&, Frame*)
123 {
124 ASSERT(!_url.isEmpty());
125
126 #ifndef QT_NO_CLIPBOARD
127 QMimeData* md = new QMimeData;
128 QString url = _url.string();
129 md->setText(url);
130 md->setUrls(QList<QUrl>() << QUrl(url));
131 QApplication::clipboard()->setMimeData(md, m_selectionMode ?
132 QClipboard::Selection : QClipboard::Clipboard);
133 #endif
134 }
135
writeImage(Node * node,const KURL &,const String &)136 void Pasteboard::writeImage(Node* node, const KURL&, const String&)
137 {
138 ASSERT(node && node->renderer() && node->renderer()->isImage());
139
140 #ifndef QT_NO_CLIPBOARD
141 CachedImage* cachedImage = toRenderImage(node->renderer())->cachedImage();
142 ASSERT(cachedImage);
143
144 Image* image = cachedImage->image();
145 ASSERT(image);
146
147 QPixmap* pixmap = image->nativeImageForCurrentFrame();
148 ASSERT(pixmap);
149
150 QApplication::clipboard()->setPixmap(*pixmap, QClipboard::Clipboard);
151 #endif
152 }
153
154 /* This function is called from Editor::tryDHTMLCopy before actually set the clipboard
155 * It introduce a race condition with klipper, which will try to grab the clipboard
156 * It's not required to clear it anyway, since QClipboard take care about replacing the clipboard
157 */
clear()158 void Pasteboard::clear()
159 {
160 }
161
isSelectionMode() const162 bool Pasteboard::isSelectionMode() const
163 {
164 return m_selectionMode;
165 }
166
setSelectionMode(bool selectionMode)167 void Pasteboard::setSelectionMode(bool selectionMode)
168 {
169 m_selectionMode = selectionMode;
170 }
171
172 }
173