First implementation of QT clipboard
authortero.turtiainen
Sat, 19 Apr 2008 18:40:33 +0300
changeset 16833 9cb864376c9bee8048111d805a257d986feb898b
parent 16832 599de3e69d9343dcbe428d1b3c7c4c9ab36f099c
child 16834 da845b1dacca369f7b813a9a40ba2c354252c537
push id1298
push userpavlov@mozilla.com
push dateSun, 17 Aug 2008 05:03:09 +0000
treeherderautoland@4a506fa751d8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone2.0a1pre
First implementation of QT clipboard
widget/src/qt/Makefile.in
widget/src/qt/nsClipboard.cpp
widget/src/qt/nsClipboard.h
widget/src/qt/nsWidgetFactory.cpp
--- a/widget/src/qt/Makefile.in
+++ b/widget/src/qt/Makefile.in
@@ -88,16 +88,17 @@ CPPSRCS	= \
 		nsWidgetFactory.cpp \
 		nsCommonWidget.cpp \
 		nsWindow.cpp \
 		nsLookAndFeel.cpp \
 		nsToolkit.cpp \
 		nsScreenQt.cpp \
 		nsScreenManagerQt.cpp \
 		nsQtKeyUtils.cpp \
+		nsClipboard.cpp \
 		mozqwidget.cpp \
 		$(NULL)
 
 SHARED_LIBRARY_LIBS = ../xpwidgets/libxpwidgets_s.a
 
 EXTRA_DSO_LDOPTS = \
 		$(MOZ_COMPONENT_LIBS) \
 		-lgkgfx \
new file mode 100644
--- /dev/null
+++ b/widget/src/qt/nsClipboard.cpp
@@ -0,0 +1,405 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Lars Knoll <knoll@kde.org>
+ *   Zack Rusin <zack@kde.org>
+ *   Denis Issoupov <denis@macadamian.com>
+ *   John C. Griggs <johng@corel.com>
+ *   Dan Rosen <dr@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsClipboard.h"
+#include "nsISupportsPrimitives.h"
+#include "nsXPIDLString.h"
+#include "nsPrimitiveHelpers.h"
+
+#include <qapplication.h>
+#include <qmime.h>
+#include <qstring.h>
+#include <qstringlist.h>
+
+NS_IMPL_ISUPPORTS1(nsClipboard, nsIClipboard)
+
+//-------------------------------------------------------------------------
+//
+// nsClipboard constructor
+//
+//-------------------------------------------------------------------------
+nsClipboard::nsClipboard() : nsIClipboard(),
+                             mSelectionOwner(nsnull),
+                             mGlobalOwner(nsnull),
+                             mSelectionTransferable(nsnull),
+                             mGlobalTransferable(nsnull)
+{
+    qDebug("nsClipboard constructor");
+}
+
+//-------------------------------------------------------------------------
+//
+// nsClipboard destructor
+//
+//-------------------------------------------------------------------------
+nsClipboard::~nsClipboard()
+{
+}
+
+
+// nsClipboard::SetNativeClipboardData ie. Copy
+
+NS_IMETHODIMP
+nsClipboard::SetNativeClipboardData( nsITransferable *aTransferable,
+                                     QClipboard::Mode clipboardMode )
+{
+    qDebug("SetNativeClipboardData");
+
+    if (nsnull == aTransferable)
+    {
+        qDebug("nsClipboard::SetNativeClipboardData(): no transferable!");
+        return NS_ERROR_FAILURE;
+    }
+
+    // get flavor list that includes all flavors that can be written (including
+    // ones obtained through conversion)
+    nsCOMPtr<nsISupportsArray> flavorList;
+    nsresult errCode = aTransferable->FlavorsTransferableCanExport( getter_AddRefs(flavorList) );
+
+    if (NS_FAILED(errCode))
+    {
+        qDebug("nsClipboard::SetNativeClipboardData(): no FlavorsTransferable !");
+        return NS_ERROR_FAILURE;
+    }
+
+    QClipboard *cb = QApplication::clipboard();
+    PRUint32 flavorCount = 0;
+    flavorList->Count(&flavorCount);
+
+    for (PRUint32 i = 0; i < flavorCount; ++i)
+    {
+        nsCOMPtr<nsISupports> genericFlavor;
+        flavorList->GetElementAt(i,getter_AddRefs(genericFlavor));
+        nsCOMPtr<nsISupportsCString> currentFlavor(do_QueryInterface(genericFlavor));
+        
+        if (currentFlavor)
+        {
+            // flavorStr is the mime type
+            nsXPIDLCString flavorStr;
+            currentFlavor->ToString(getter_Copies(flavorStr));
+
+            // Clip is the data which will be sent to the clipboard
+            nsCOMPtr<nsISupports> clip;
+            // len is the length of the data
+            PRUint32 len;
+
+            // Unicode text?
+            if (!strcmp(flavorStr.get(), kUnicodeMime))
+            {
+                aTransferable->GetTransferData(flavorStr,getter_AddRefs(clip),&len);
+                nsCOMPtr<nsISupportsString> wideString;
+                wideString = do_QueryInterface(clip);
+                if (!wideString)
+                {
+                    return NS_ERROR_FAILURE;
+                }
+
+                nsAutoString utf16string;
+                wideString->GetData(utf16string);
+                QString str = QString::fromUtf16(utf16string.get());
+
+                // Set the date to the clipboard
+                cb->setText(str, clipboardMode);
+                break;
+            }
+
+            if ( !strcmp(flavorStr.get(), kNativeImageMime)
+              || !strcmp(flavorStr.get(), kPNGImageMime)
+              || !strcmp(flavorStr.get(), kJPEGImageMime)
+              || !strcmp(flavorStr.get(), kGIFImageMime))
+            {
+                qDebug("nsClipboard::SetNativeClipboardData(): Copying image data not implemented!");
+            }
+        }
+    }
+
+    return NS_OK;
+}
+
+// nsClipboard::GetNativeClipboardData ie. Paste
+//
+NS_IMETHODIMP
+nsClipboard::GetNativeClipboardData(nsITransferable *aTransferable,
+                                    QClipboard::Mode clipboardMode)
+{
+    qDebug("GetNativeClipboardData");
+    
+    if (nsnull == aTransferable)
+    {
+        qDebug("  GetNativeClipboardData: Transferable is null!");
+        return NS_ERROR_FAILURE;
+    }
+
+    // get flavor list that includes all acceptable flavors (including
+    // ones obtained through conversion)
+    nsCOMPtr<nsISupportsArray> flavorList;
+    nsresult errCode = aTransferable->FlavorsTransferableCanImport(
+        getter_AddRefs(flavorList));
+
+    if (NS_FAILED(errCode))
+    {
+        qDebug("nsClipboard::GetNativeClipboardData(): no FlavorsTransferable %i !",
+               errCode);
+        return NS_ERROR_FAILURE;
+    }
+
+    QClipboard *cb = QApplication::clipboard();
+    const QMimeData *mimeData = cb->mimeData(clipboardMode);
+
+    // Walk through flavors and see which flavor matches the one being pasted
+    PRUint32 flavorCount;
+    flavorList->Count(&flavorCount);
+    nsCAutoString foundFlavor;
+
+    for (PRUint32 i = 0; i < flavorCount; ++i)
+    {
+        nsCOMPtr<nsISupports> genericFlavor;
+        flavorList->GetElementAt(i,getter_AddRefs(genericFlavor));
+        nsCOMPtr<nsISupportsCString> currentFlavor(do_QueryInterface( genericFlavor) );
+
+        if (currentFlavor)
+        {
+            nsXPIDLCString flavorStr;
+            currentFlavor->ToString(getter_Copies(flavorStr));
+
+            // Ok, so which flavor the data being pasted could be?
+            // Text?
+            if (!strcmp(flavorStr.get(), kUnicodeMime)) 
+            {
+                if (mimeData->hasText())
+                {
+                    // Clipboard has text and flavor accepts text, so lets
+                    // handle the data as text
+                    foundFlavor = nsCAutoString(flavorStr);
+
+                    // Copy the text data from clipboard to byte array
+                    QString text = mimeData->text();
+                    QByteArray ba = text.toUtf8();
+                    PRUint32 len = (PRUint32) ba.size();
+
+                    qDebug("Size of byte array for pasted data: %d", len);
+
+                    // And then to genericDataWrapper
+                    nsCOMPtr<nsISupports> genericDataWrapper;
+                    nsPrimitiveHelpers::CreatePrimitiveForData(
+                        foundFlavor.get(),
+                        (void*)ba.data(),len,
+                        getter_AddRefs(genericDataWrapper));
+
+                    // Data is good, set it to the transferable
+                    aTransferable->SetTransferData(foundFlavor.get(),
+                                                   genericDataWrapper,len);
+                    // And thats all
+                    break;
+                }
+            }
+
+            // Image?
+            if (!strcmp(flavorStr.get(), kJPEGImageMime)
+             || !strcmp(flavorStr.get(), kPNGImageMime)
+             || !strcmp(flavorStr.get(), kGIFImageMime))
+            {
+                qDebug("nsClipboard::GetNativeClipboardData(): Pasting image data not implemented!");
+                break;
+            }
+        }
+    }
+
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsClipboard::HasDataMatchingFlavors(const char** aFlavorList, PRUint32 aLength,
+                                    PRInt32 aWhichClipboard, PRBool *_retval)
+{
+    qDebug("HasDataMatchingFlavors");
+    *_retval = PR_FALSE;
+    if (aWhichClipboard != kGlobalClipboard)
+        return NS_OK;
+
+    // Which kind of data in the clipboard
+    QClipboard *cb = QApplication::clipboard();
+    const QMimeData *mimeData = cb->mimeData();
+    const char *flavor=NULL;
+    QStringList formats = mimeData->formats();
+
+    // And is there matching flavor?
+    for (PRUint32 i = 0; i < aLength; ++i)
+    {
+        if ((flavor == aFlavorList[i]))
+        {
+            QString qflavor(flavor);
+
+            if (strcmp(flavor,kTextMime) == 0)
+            {
+                NS_WARNING("DO NOT USE THE text/plain DATA FLAVOR ANY MORE. USE text/unicode INSTEAD");
+            }
+
+            if (formats.contains(qflavor))
+            {
+                // A match has been found, return
+                *_retval = PR_TRUE;
+                break;
+            }
+        }
+    }
+    return NS_OK;
+}
+
+/**
+ * Sets the transferable object
+ */
+NS_IMETHODIMP
+nsClipboard::SetData(nsITransferable *aTransferable,
+                     nsIClipboardOwner *aOwner,
+                     PRInt32 aWhichClipboard)
+{
+    qDebug("SetData");
+
+    // See if we can short cut
+    if (
+        (aWhichClipboard == kGlobalClipboard
+           && aTransferable == mGlobalTransferable.get()
+           && aOwner == mGlobalOwner.get()
+        )
+       ||
+        (aWhichClipboard == kSelectionClipboard
+         && aTransferable == mSelectionTransferable.get()
+         && aOwner == mSelectionOwner.get()
+        )
+       )
+    {
+        return NS_OK;
+    }
+
+    EmptyClipboard(aWhichClipboard);
+
+    QClipboard::Mode mode;
+
+    if (kGlobalClipboard == aWhichClipboard)
+    {
+        mGlobalOwner = aOwner;
+        mGlobalTransferable = aTransferable;
+
+        mode = QClipboard::Clipboard;
+    }
+    else
+    {
+        mSelectionOwner = aOwner;
+        mSelectionTransferable = aTransferable;
+
+        mode = QClipboard::Selection;
+    }
+    return SetNativeClipboardData( aTransferable, mode );
+}
+
+/**
+ * Gets the transferable object
+ */
+NS_IMETHODIMP
+nsClipboard::GetData(nsITransferable *aTransferable, PRInt32 aWhichClipboard)
+{
+    qDebug("GetData");
+    if (nsnull != aTransferable)
+    {
+        QClipboard::Mode mode;
+        if (kGlobalClipboard == aWhichClipboard)
+        {
+            mode = QClipboard::Clipboard;
+        }
+        else
+        {
+            mode = QClipboard::Selection;
+        }
+        return GetNativeClipboardData(aTransferable, mode);
+    }
+    else
+    {
+        qDebug("  nsClipboard::GetData(), aTransferable is NULL.");
+    }
+    return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsClipboard::EmptyClipboard(PRInt32 aWhichClipboard)
+{
+    qDebug("EmptyClipoard");
+
+    if (aWhichClipboard == kSelectionClipboard)
+    {
+        if (mSelectionOwner)
+        {
+            mSelectionOwner->LosingOwnership(mSelectionTransferable);
+            mSelectionOwner = nsnull;
+        }
+        mSelectionTransferable = nsnull;
+    }
+    else
+    {
+        if (mGlobalOwner)
+        {
+            mGlobalOwner->LosingOwnership(mGlobalTransferable);
+            mGlobalOwner = nsnull;
+        }
+        mGlobalTransferable = nsnull;
+    }
+
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsClipboard::SupportsSelectionClipboard(PRBool *_retval)
+{
+    qDebug("SuppotsSelectionClipboard");
+    NS_ENSURE_ARG_POINTER(_retval);
+
+    QClipboard *cb = QApplication::clipboard();
+    if (cb->supportsSelection())
+    {
+        *_retval = PR_TRUE; // we support the selection clipboard 
+    }
+    else
+    {
+        *_retval = PR_FALSE;
+    }
+
+    return NS_OK;
+}
new file mode 100644
--- /dev/null
+++ b/widget/src/qt/nsClipboard.h
@@ -0,0 +1,73 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Denis Issoupov <denis@macadamian.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+#ifndef nsClipboard_h__
+#define nsClipboard_h__
+
+#include "nsIClipboard.h"
+#include "nsITransferable.h"
+#include "nsIClipboardOwner.h"
+#include "nsCOMPtr.h"
+
+#include <qclipboard.h>
+
+/* Native Qt Clipboard wrapper */
+class nsClipboard : public nsIClipboard
+{
+public:
+    nsClipboard();
+    virtual ~nsClipboard();
+
+    //nsISupports
+    NS_DECL_ISUPPORTS
+
+    // nsIClipboard
+    NS_DECL_NSICLIPBOARD
+
+protected:
+    NS_IMETHOD SetNativeClipboardData(nsITransferable *aTransferable,
+                                      QClipboard::Mode cbMode);
+    NS_IMETHOD GetNativeClipboardData(nsITransferable *aTransferable,
+                                      QClipboard::Mode cbMode);
+
+    nsCOMPtr<nsIClipboardOwner> mSelectionOwner;
+    nsCOMPtr<nsIClipboardOwner> mGlobalOwner;
+    nsCOMPtr<nsITransferable>   mSelectionTransferable;
+    nsCOMPtr<nsITransferable>   mGlobalTransferable;
+};
+
+#endif // nsClipboard_h__
--- a/widget/src/qt/nsWidgetFactory.cpp
+++ b/widget/src/qt/nsWidgetFactory.cpp
@@ -54,18 +54,18 @@
 #include "nsScreenManagerQt.h"
 
 // #include "nsIComponentRegistrar.h"
 // #include "nsComponentManagerUtils.h"
 // #include "nsAutoPtr.h"
 // 
 
 
-// #include "nsClipboard.h"
-// #include "nsClipboardHelper.h"
+#include "nsClipboard.h"
+#include "nsClipboardHelper.h"
 // #include "nsDragService.h"
 // #include "nsScrollbar.h"
 // #include "nsFilePicker.h"
 // #include "nsSound.h"
 // 
 // #include "nsGUIEvent.h"
 // #include "nsQtEventDispatcher.h"
 // #include "nsIRenderingContext.h"
@@ -83,23 +83,23 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsPopupWi
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsToolkit)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsHTMLFormatConverter)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsTransferable)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsLookAndFeel)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsScreenManagerQt)
 
 /*
 static NS_DEFINE_CID(kNativeScrollCID, NS_NATIVESCROLLBAR_CID);
-
+*/
 
 
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboard)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboardHelper)
-
+/*
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsDragService)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsBidiKeyboard)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsNativeScrollbar)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSound)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsFilePicker)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsNativeThemeQt)
 */
 static const nsModuleComponentInfo components[] =
@@ -134,30 +134,32 @@ static const nsModuleComponentInfo compo
       nsToolkitConstructor },
     { "Transferrable",
       NS_TRANSFERABLE_CID,
       "@mozilla.org/widget/transferable;1",
       nsTransferableConstructor },
     { "Qt Screen Manager",
       NS_SCREENMANAGER_CID,
       "@mozilla.org/gfx/screenmanager;1",
-      nsScreenManagerQtConstructor }
+      nsScreenManagerQtConstructor },
 /*
     { "Qt Native Scrollbar",
       NS_NATIVESCROLLBAR_CID,
       "@mozilla.org/widget/nativescrollbar/qt;1",
       nsNativeScrollbarConstructor},
+*/
     { "Qt Clipboard",
       NS_CLIPBOARD_CID,
       "@mozilla.org/widget/clipboard;1",
       nsClipboardConstructor },
     { "Clipboard Helper",
       NS_CLIPBOARDHELPER_CID,
       "@mozilla.org/widget/clipboardhelper;1",
-      nsClipboardHelperConstructor },
+      nsClipboardHelperConstructor }
+/*
     { "Qt Drag Service",
       NS_DRAGSERVICE_CID,
       "@mozilla.org/widget/dragservice;1",
       nsDragServiceConstructor },
     { "Qt Bidi Keyboard",
       NS_BIDIKEYBOARD_CID,
       "@mozilla.org/widget/bidikeyboard;1",
       nsBidiKeyboardConstructor },