diff options
Diffstat (limited to 'Source/WebCore/platform/qt/ClipboardQt.cpp')
-rw-r--r-- | Source/WebCore/platform/qt/ClipboardQt.cpp | 362 |
1 files changed, 362 insertions, 0 deletions
diff --git a/Source/WebCore/platform/qt/ClipboardQt.cpp b/Source/WebCore/platform/qt/ClipboardQt.cpp new file mode 100644 index 0000000..c14d362 --- /dev/null +++ b/Source/WebCore/platform/qt/ClipboardQt.cpp @@ -0,0 +1,362 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) + * Copyright (C) 2010 Sencha, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "ClipboardQt.h" + +#include "CachedImage.h" +#include "Document.h" +#include "DragData.h" +#include "Element.h" +#include "FileList.h" +#include "Frame.h" +#include "HTMLNames.h" +#include "HTMLParserIdioms.h" +#include "Image.h" +#include "IntPoint.h" +#include "KURL.h" +#include "NotImplemented.h" +#include "PlatformString.h" +#include "Range.h" +#include "RenderImage.h" +#include "markup.h" +#include <wtf/text/StringHash.h> + +#include <QApplication> +#include <QClipboard> +#include <QList> +#include <QMimeData> +#include <QStringList> +#include <QTextCodec> +#include <QUrl> +#include <qdebug.h> + +#define methodDebug() qDebug("ClipboardQt: %s", __FUNCTION__) + +namespace WebCore { + +static bool isTextMimeType(const String& type) +{ + return type == "text/plain" || type.startsWith("text/plain;"); +} + +static bool isHtmlMimeType(const String& type) +{ + return type == "text/html" || type.startsWith("text/html;"); +} + +PassRefPtr<Clipboard> Clipboard::create(ClipboardAccessPolicy policy, DragData* dragData, Frame*) +{ + return ClipboardQt::create(policy, dragData->platformData()); +} + +ClipboardQt::ClipboardQt(ClipboardAccessPolicy policy, const QMimeData* readableClipboard) + : Clipboard(policy, DragAndDrop) + , m_readableData(readableClipboard) + , m_writableData(0) +{ + Q_ASSERT(policy == ClipboardReadable || policy == ClipboardTypesReadable); +} + +ClipboardQt::ClipboardQt(ClipboardAccessPolicy policy, ClipboardType clipboardType) + : Clipboard(policy, clipboardType) + , m_readableData(0) + , m_writableData(0) +{ + Q_ASSERT(policy == ClipboardReadable || policy == ClipboardWritable || policy == ClipboardNumb); + +#ifndef QT_NO_CLIPBOARD + if (policy != ClipboardWritable) { + Q_ASSERT(isForCopyAndPaste()); + m_readableData = QApplication::clipboard()->mimeData(); + } +#endif +} + +ClipboardQt::~ClipboardQt() +{ + if (m_writableData && isForCopyAndPaste()) + m_writableData = 0; + else + delete m_writableData; + m_readableData = 0; +} + +void ClipboardQt::clearData(const String& type) +{ + if (policy() != ClipboardWritable) + return; + + if (m_writableData) { + m_writableData->removeFormat(type); + if (m_writableData->formats().isEmpty()) { + if (isForDragAndDrop()) + delete m_writableData; + m_writableData = 0; + } + } +#ifndef QT_NO_CLIPBOARD + if (isForCopyAndPaste()) + QApplication::clipboard()->setMimeData(m_writableData); +#endif +} + +void ClipboardQt::clearAllData() +{ + if (policy() != ClipboardWritable) + return; + +#ifndef QT_NO_CLIPBOARD + if (isForCopyAndPaste()) + QApplication::clipboard()->setMimeData(0); + else +#endif + delete m_writableData; + m_writableData = 0; +} + +String ClipboardQt::getData(const String& type, bool& success) const +{ + + if (policy() != ClipboardReadable) { + success = false; + return String(); + } + + if (isHtmlMimeType(type) && m_readableData->hasHtml()) { + success = true; + return m_readableData->html(); + } + + if (isTextMimeType(type) && m_readableData->hasText()) { + success = true; + return m_readableData->text(); + } + + ASSERT(m_readableData); + QByteArray rawData = m_readableData->data(type); + QString data = QTextCodec::codecForName("UTF-16")->toUnicode(rawData); + success = !data.isEmpty(); + return data; +} + +bool ClipboardQt::setData(const String& type, const String& data) +{ + if (policy() != ClipboardWritable) + return false; + + if (!m_writableData) + m_writableData = new QMimeData; + + if (isTextMimeType(type)) + m_writableData->setText(QString(data)); + else if (isHtmlMimeType(type)) + m_writableData->setHtml(QString(data)); + else { + QByteArray array(reinterpret_cast<const char*>(data.characters()), data.length() * 2); + m_writableData->setData(QString(type), array); + } + +#ifndef QT_NO_CLIPBOARD + if (isForCopyAndPaste()) + QApplication::clipboard()->setMimeData(m_writableData); +#endif + return true; +} + +// extensions beyond IE's API +HashSet<String> ClipboardQt::types() const +{ + if (policy() != ClipboardReadable && policy() != ClipboardTypesReadable) + return HashSet<String>(); + + ASSERT(m_readableData); + HashSet<String> result; + QStringList formats = m_readableData->formats(); + for (int i = 0; i < formats.count(); ++i) + result.add(formats.at(i)); + return result; +} + +PassRefPtr<FileList> ClipboardQt::files() const +{ + if (policy() != ClipboardReadable || !m_readableData->hasUrls()) + return FileList::create(); + + RefPtr<FileList> fileList = FileList::create(); + QList<QUrl> urls = m_readableData->urls(); + + for (int i = 0; i < urls.size(); i++) { + QUrl url = urls[i]; + if (url.scheme() != QLatin1String("file")) + continue; + fileList->append(File::create(url.toLocalFile())); + } + + return fileList.release(); +} + +void ClipboardQt::setDragImage(CachedImage* image, const IntPoint& point) +{ + setDragImage(image, 0, point); +} + +void ClipboardQt::setDragImageElement(Node* node, const IntPoint& point) +{ + setDragImage(0, node, point); +} + +void ClipboardQt::setDragImage(CachedImage* image, Node *node, const IntPoint &loc) +{ + if (policy() != ClipboardImageWritable && policy() != ClipboardWritable) + return; + + if (m_dragImage) + m_dragImage->removeClient(this); + m_dragImage = image; + if (m_dragImage) + m_dragImage->addClient(this); + + m_dragLoc = loc; + m_dragImageElement = node; +} + +DragImageRef ClipboardQt::createDragImage(IntPoint& dragLoc) const +{ + if (!m_dragImage) + return 0; + dragLoc = m_dragLoc; + return m_dragImage->image()->nativeImageForCurrentFrame(); +} + + +static CachedImage* getCachedImage(Element* element) +{ + // Attempt to pull CachedImage from element + ASSERT(element); + RenderObject* renderer = element->renderer(); + if (!renderer || !renderer->isImage()) + return 0; + + RenderImage* image = toRenderImage(renderer); + if (image->cachedImage() && !image->cachedImage()->errorOccurred()) + return image->cachedImage(); + + return 0; +} + +void ClipboardQt::declareAndWriteDragImage(Element* element, const KURL& url, const String& title, Frame* frame) +{ + ASSERT(frame); + + // WebCore::writeURL(m_writableDataObject.get(), url, title, true, false); + if (!m_writableData) + m_writableData = new QMimeData; + + CachedImage* cachedImage = getCachedImage(element); + if (!cachedImage || !cachedImage->image() || !cachedImage->isLoaded()) + return; + QPixmap* pixmap = cachedImage->image()->nativeImageForCurrentFrame(); + if (pixmap) + m_writableData->setImageData(*pixmap); + + AtomicString imageURL = element->getAttribute(HTMLNames::srcAttr); + if (imageURL.isEmpty()) + return; + + KURL fullURL = frame->document()->completeURL(stripLeadingAndTrailingHTMLSpaces(imageURL)); + if (fullURL.isEmpty()) + return; + + QList<QUrl> urls; + urls.append(url); + urls.append(fullURL); + + m_writableData->setText(title); + m_writableData->setUrls(urls); +#ifndef QT_NO_CLIPBOARD + if (isForCopyAndPaste()) + QApplication::clipboard()->setMimeData(m_writableData); +#endif +} + +void ClipboardQt::writeURL(const KURL& url, const String& title, Frame* frame) +{ + ASSERT(frame); + + QList<QUrl> urls; + urls.append(frame->document()->completeURL(url.string())); + if (!m_writableData) + m_writableData = new QMimeData; + m_writableData->setUrls(urls); + m_writableData->setText(title); +#ifndef QT_NO_CLIPBOARD + if (isForCopyAndPaste()) + QApplication::clipboard()->setMimeData(m_writableData); +#endif +} + +void ClipboardQt::writeRange(Range* range, Frame* frame) +{ + ASSERT(range); + ASSERT(frame); + + if (!m_writableData) + m_writableData = new QMimeData; + QString text = frame->editor()->selectedText(); + text.replace(QChar(0xa0), QLatin1Char(' ')); + m_writableData->setText(text); + m_writableData->setHtml(createMarkup(range, 0, AnnotateForInterchange, false, AbsoluteURLs)); +#ifndef QT_NO_CLIPBOARD + if (isForCopyAndPaste()) + QApplication::clipboard()->setMimeData(m_writableData); +#endif +} + +void ClipboardQt::writePlainText(const String& str) +{ + if (!m_writableData) + m_writableData = new QMimeData; + QString text = str; + text.replace(QChar(0xa0), QLatin1Char(' ')); + m_writableData->setText(text); +#ifndef QT_NO_CLIPBOARD + if (isForCopyAndPaste()) + QApplication::clipboard()->setMimeData(m_writableData); +#endif +} + +bool ClipboardQt::hasData() +{ + const QMimeData *data = m_readableData ? m_readableData : m_writableData; + if (!data) + return false; + return data->formats().count() > 0; +} + +} |