From 76a66d02dfe0ff62b94af32a0b81ca359b5d2e74 Mon Sep 17 00:00:00 2001
From: shibakaneki <ShibaKaneki@MacBook-Pro-de-Shiba.local>
Date: Mon, 14 Nov 2011 17:35:24 +0100
Subject: [PATCH] Drag and drop support from Safari done

---
 src/board/UBBoardController.cpp          |  13 ++
 src/frameworks/UBPlatformUtils.h         | 229 +++++++++++------------
 src/frameworks/UBPlatformUtils_linux.cpp |   9 +
 src/frameworks/UBPlatformUtils_mac.mm    |  16 ++
 src/frameworks/UBPlatformUtils_win.cpp   |   9 +-
 src/gui/UBLibraryWidget.cpp              |  14 ++
 src/gui/UBLibraryWidget.h                |   1 +
 7 files changed, 169 insertions(+), 122 deletions(-)

diff --git a/src/board/UBBoardController.cpp b/src/board/UBBoardController.cpp
index 3aa16d7d..4a34529b 100644
--- a/src/board/UBBoardController.cpp
+++ b/src/board/UBBoardController.cpp
@@ -1886,6 +1886,19 @@ void UBBoardController::processMimeData(const QMimeData* pMimeData, const QPoint
         if("" != pMimeData->text()){
             mActiveScene->addText(pMimeData->text(), pPos);
         }
+        else{
+#ifdef Q_WS_MACX
+                //  With Safari, in 95% of the drops, the mime datas are hidden in Apple Web Archive pasteboard type.
+                //  This is due to the way Safari is working so we have to dig into the pasteboard in order to retrieve
+                //  the data.
+                QString qsUrl = UBPlatformUtils::urlFromClipboard();
+                if("" != qsUrl){
+                    // We finally got the url of the dropped ressource! Let's import it!
+                    downloadURL(qsUrl, pPos);
+                    return;
+                }
+#endif
+        }
     }
 }
 
diff --git a/src/frameworks/UBPlatformUtils.h b/src/frameworks/UBPlatformUtils.h
index 311d6d9b..74d97dce 100644
--- a/src/frameworks/UBPlatformUtils.h
+++ b/src/frameworks/UBPlatformUtils.h
@@ -12,124 +12,111 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
-
-#ifndef UBPLATFORMUTILS_H_
-#define UBPLATFORMUTILS_H_
-
-#include <QtCore>
-#include <QIcon>
-
-class QMainWindow;
-
-#define SYMBOL_KEYS_COUNT 47
-
-struct KEYBT
-{
-	const QChar symbol1;
-	const int code1;
-	const QChar symbol2;
-    const int code2;
-
-	KEYBT(unsigned int _symbol1,
-		unsigned int _symbol2):
-        symbol1(_symbol1),
-        code1(_symbol1),
-        symbol2(_symbol2),
-        code2(_symbol2){}
-
-
-    KEYBT(QChar _symbol1,
-		int _code1,
-		QChar _symbol2,
-		int _code2):
-			symbol1(_symbol1),
-            code1(_code1),
-            symbol2(_symbol2),
-            code2(_code2){}
-    };
-
-	class UBKeyboardLocale
-	{
-	public:
-		UBKeyboardLocale(const QString& _fullName,
-			const QString& _name,
-			const QString& _id,
-			QIcon* _icon,
-			KEYBT** _symbols)
-			:fullName(_fullName),name(_name), id(_id), icon(_icon),
-                        constSymbols(NULL), varSymbols(_symbols)
-		{}
-		UBKeyboardLocale(const QString& _fullName,
-			const QString& _name,
-			const QString& _id,
-			QIcon* _icon,
-			const KEYBT _symbols[])
-			:fullName(_fullName),name(_name),  id(_id), icon(_icon),
-                        constSymbols(_symbols), varSymbols(NULL)
-		{}
-
-		~UBKeyboardLocale();
-
-		const QString fullName;
-		const QString name;
-		const QString id;
-		QIcon* icon;
-		const KEYBT* operator[] (int index) const
-		{
-			return (varSymbols==NULL)? constSymbols + index : varSymbols[index];
-		}
-	private:
-		const KEYBT* constSymbols;
-		KEYBT** varSymbols;
-	};
-
-
-class UBPlatformUtils
-{
-    private:
-        UBPlatformUtils();
-        virtual ~UBPlatformUtils();
-
-		static void initializeKeyboardLayouts();
-		static void destroyKeyboardLayouts();
-		static int nKeyboardLayouts;
-		static UBKeyboardLocale** keyboardLayouts;
-
-    public:
-        static void init();
-		static void destroy();
-
-        static QString applicationResourcesDirectory();
-
-        static void hideFile(const QString &filePath);
-        static void setFileType(const QString &filePath, unsigned long fileType);
-
-        static void fadeDisplayOut();
-        static void fadeDisplayIn();
-
-        static QString preferredTranslation();
-        static QString preferredLanguage();
-
-        static bool hasVirtualKeyboard();
-        //static void showVirtualKeyboard();
-
-        static void runInstaller(const QString &installerFilePath);
-
-        static void bringPreviousProcessToFront();
-
-        static QString osUserLoginName();
-
-        static void setDesktopMode(bool desktop);
-
-		static void setWindowNonActivableFlag(QWidget* widget, bool nonAcivable);
-
-        static QString computerName();
-
-		static UBKeyboardLocale** getKeyboardLayouts(int& nCount);
-
-
-};
-
-
-
-#endif /* UBPLATFORMUTILS_H_ */
+
+#ifndef UBPLATFORMUTILS_H_
+#define UBPLATFORMUTILS_H_
+
+#include <QtCore>
+#include <QIcon>
+
+class QMainWindow;
+
+#define SYMBOL_KEYS_COUNT 47
+
+struct KEYBT
+{
+	const QChar symbol1;
+	const int code1;
+	const QChar symbol2;
+    const int code2;
+
+	KEYBT(unsigned int _symbol1,
+		unsigned int _symbol2):
+        symbol1(_symbol1),
+        code1(_symbol1),
+        symbol2(_symbol2),
+        code2(_symbol2){}
+
+
+    KEYBT(QChar _symbol1,
+		int _code1,
+		QChar _symbol2,
+		int _code2):
+			symbol1(_symbol1),
+            code1(_code1),
+            symbol2(_symbol2),
+            code2(_code2){}
+    };
+
+	class UBKeyboardLocale
+	{
+	public:
+		UBKeyboardLocale(const QString& _fullName,
+			const QString& _name,
+			const QString& _id,
+			QIcon* _icon,
+			KEYBT** _symbols)
+			:fullName(_fullName),name(_name), id(_id), icon(_icon),
+                        constSymbols(NULL), varSymbols(_symbols)
+		{}
+		UBKeyboardLocale(const QString& _fullName,
+			const QString& _name,
+			const QString& _id,
+			QIcon* _icon,
+			const KEYBT _symbols[])
+			:fullName(_fullName),name(_name),  id(_id), icon(_icon),
+                        constSymbols(_symbols), varSymbols(NULL)
+		{}
+
+		~UBKeyboardLocale();
+
+		const QString fullName;
+		const QString name;
+		const QString id;
+		QIcon* icon;
+		const KEYBT* operator[] (int index) const
+		{
+			return (varSymbols==NULL)? constSymbols + index : varSymbols[index];
+		}
+	private:
+		const KEYBT* constSymbols;
+		KEYBT** varSymbols;
+	};
+
+
+class UBPlatformUtils
+{
+    private:
+        UBPlatformUtils();
+        virtual ~UBPlatformUtils();
+
+        static void initializeKeyboardLayouts();
+        static void destroyKeyboardLayouts();
+        static int nKeyboardLayouts;
+        static UBKeyboardLocale** keyboardLayouts;
+
+    public:
+        static void init();
+        static void destroy();
+        static QString applicationResourcesDirectory();
+        static void hideFile(const QString &filePath);
+        static void setFileType(const QString &filePath, unsigned long fileType);
+        static void fadeDisplayOut();
+        static void fadeDisplayIn();
+        static QString preferredTranslation();
+        static QString preferredLanguage();
+        static bool hasVirtualKeyboard();
+        //static void showVirtualKeyboard();
+        static void runInstaller(const QString &installerFilePath);
+        static void bringPreviousProcessToFront();
+        static QString osUserLoginName();
+        static void setDesktopMode(bool desktop);
+        static void setWindowNonActivableFlag(QWidget* widget, bool nonAcivable);
+        static QString computerName();
+        static UBKeyboardLocale** getKeyboardLayouts(int& nCount);
+        static QString urlFromClipboard();
+};
+
+
+
+#endif /* UBPLATFORMUTILS_H_ */
diff --git a/src/frameworks/UBPlatformUtils_linux.cpp b/src/frameworks/UBPlatformUtils_linux.cpp
index e9bb2d90..3c18ce93 100644
--- a/src/frameworks/UBPlatformUtils_linux.cpp
+++ b/src/frameworks/UBPlatformUtils_linux.cpp
@@ -331,3 +331,12 @@ void UBPlatformUtils::destroyKeyboardLayouts()
 	delete [] keyboardLayouts;
 	keyboardLayouts = NULL;
 }
+
+QString UBPlatformUtils::urlFromClipboard()
+{
+    QString qsRet;
+
+    // Not used on Linux
+
+    return qsRet;
+}
diff --git a/src/frameworks/UBPlatformUtils_mac.mm b/src/frameworks/UBPlatformUtils_mac.mm
index 17cf3e61..0e83e8a3 100644
--- a/src/frameworks/UBPlatformUtils_mac.mm
+++ b/src/frameworks/UBPlatformUtils_mac.mm
@@ -12,6 +12,8 @@
 #import <Foundation/NSAutoreleasePool.h>
 #import <Carbon/Carbon.h>
 #import <APELite.h>
+#import <WebKit/WebKit.h>
+#import <AppKit/AppKit.h>
 
 
 NSString* bundleShortVersion(NSBundle *bundle)
@@ -537,3 +539,17 @@ void UBPlatformUtils::initializeKeyboardLayouts()
 
 void UBPlatformUtils::destroyKeyboardLayouts()
 {}
+
+QString UBPlatformUtils::urlFromClipboard()
+{
+    QString qsRet;
+
+    NSPasteboard* pPasteboard = [NSPasteboard pasteboardWithName:@"Apple CFPasteboard drag"];
+    WebArchive* pArchive = [[WebArchive alloc] initWithData:[pPasteboard dataForType:@"com.apple.webarchive"]];
+
+    qsRet = [[[[pArchive mainResource] URL] absoluteString] UTF8String];
+
+    [pArchive release];
+
+    return qsRet;
+}
diff --git a/src/frameworks/UBPlatformUtils_win.cpp b/src/frameworks/UBPlatformUtils_win.cpp
index 08066adc..6605ebe4 100644
--- a/src/frameworks/UBPlatformUtils_win.cpp
+++ b/src/frameworks/UBPlatformUtils_win.cpp
@@ -367,4 +367,11 @@ void UBPlatformUtils::destroyKeyboardLayouts()
 		delete keyboardLayouts[i];
 	delete [] keyboardLayouts;
 	keyboardLayouts = NULL;
-}
\ No newline at end of file
+}
+
+QString UBPlatformUtils::urlFromClipboard()
+{
+    QString qsRet;
+    //  Not implemented yet
+    return qsRet;
+}
diff --git a/src/gui/UBLibraryWidget.cpp b/src/gui/UBLibraryWidget.cpp
index b88f8e8f..9ffc9db4 100644
--- a/src/gui/UBLibraryWidget.cpp
+++ b/src/gui/UBLibraryWidget.cpp
@@ -27,6 +27,7 @@
 #include "core/UBDownloadManager.h"
 
 #include "frameworks/UBFileSystemUtils.h"
+#include "frameworks/UBPlatformUtils.h"
 
 #include "core/memcheck.h"
 
@@ -389,6 +390,19 @@ void UBLibraryWidget::dropEvent(QDropEvent *event)
                 mLibraryController->importItemOnLibrary(filePath);
                 bDropAccepted = true;
             }
+            else{
+#ifdef Q_WS_MACX
+                //  With Safari, in 95% of the drops, the mime datas are hidden in Apple Web Archive pasteboard type.
+                //  This is due to the way Safari is working so we have to dig into the pasteboard in order to retrieve
+                //  the data.
+                QString qsUrl = UBPlatformUtils::urlFromClipboard();
+                if("" != qsUrl){
+                    // We finally got the url of the dropped ressource! Let's import it!
+                    mLibraryController->importItemOnLibrary(qsUrl);
+                    bDropAccepted = true;
+                }
+#endif
+            }
         }
         else if (pMimeData->hasImage()){
             qDebug() << "hasImage";
diff --git a/src/gui/UBLibraryWidget.h b/src/gui/UBLibraryWidget.h
index 88bf56ee..c79319a1 100644
--- a/src/gui/UBLibraryWidget.h
+++ b/src/gui/UBLibraryWidget.h
@@ -79,6 +79,7 @@ private:
     void refreshView();
     void generateItems();
     void appendChainedElement(UBChainedLibElement* element, UBChainedLibElement* toElem);
+
     UBLibElement* elementAt(QPoint p);
     UBLibElement* elementFromFilePath(const QString& filePath);
     UBLibraryController* mLibraryController;