From b7030a74dd5208afc75be42c81201cfa72ebbcc9 Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Tue, 17 Apr 2007 19:53:34 +0000 Subject: Drag images out of mozilla. --- (limited to 'browser') diff --git a/browser/GeckoBrowserPersist.cpp b/browser/GeckoBrowserPersist.cpp new file mode 100644 index 0000000..48de4d1 --- /dev/null +++ b/browser/GeckoBrowserPersist.cpp @@ -0,0 +1,185 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "GeckoBrowserPersist.h" + +GeckoBrowserPersist::GeckoBrowserPersist(SugarBrowser *browser) + : mBrowser(browser) +{ +} + +GeckoBrowserPersist::~GeckoBrowserPersist() +{ +} + +static nsresult +NewURI(const char *uri, nsIURI **result) +{ + nsresult rv; + + nsCOMPtr mgr; + NS_GetServiceManager (getter_AddRefs (mgr)); + NS_ENSURE_TRUE(mgr, FALSE); + + nsCOMPtr ioService; + rv = mgr->GetServiceByContractID ("@mozilla.org/network/io-service;1", + NS_GET_IID (nsIIOService), + getter_AddRefs(ioService)); + NS_ENSURE_SUCCESS(rv, FALSE); + + nsCString cSpec(uri); + return ioService->NewURI (cSpec, nsnull, nsnull, result); +} + +static nsresult +GetPostData(SugarBrowser *browser, nsIInputStream **postData) +{ +#ifdef HAVE_NS_WEB_BROWSER + nsCOMPtr webBrowser; + gtk_moz_embed_get_nsIWebBrowser(GTK_MOZ_EMBED(browser), + getter_AddRefs(webBrowser)); + NS_ENSURE_TRUE(webBrowser, NS_ERROR_FAILURE); + + nsCOMPtr webNav(do_QueryInterface(webBrowser)); + NS_ENSURE_TRUE(webNav, NS_ERROR_FAILURE); + + PRInt32 sindex; + + nsCOMPtr sessionHistory; + webNav->GetSessionHistory(getter_AddRefs(sessionHistory)); + NS_ENSURE_TRUE(sessionHistory, NS_ERROR_FAILURE); + + nsCOMPtr entry; + sessionHistory->GetIndex(&sindex); + sessionHistory->GetEntryAtIndex(sindex, PR_FALSE, getter_AddRefs(entry)); + + nsCOMPtr shEntry(do_QueryInterface(entry)); + if (shEntry) { + shEntry->GetPostData(postData); + } + + return NS_OK; +#endif + return NS_ERROR_NOT_IMPLEMENTED; +} + +bool +GeckoBrowserPersist::SaveURI(const char *uri, const char *filename) +{ + nsresult rv; + + nsCOMPtr sourceURI; + rv = NewURI(uri, getter_AddRefs(sourceURI)); + NS_ENSURE_SUCCESS(rv, FALSE); + + nsCOMPtr destFile = do_CreateInstance("@mozilla.org/file/local;1"); + NS_ENSURE_TRUE(destFile, FALSE); + + destFile->InitWithNativePath(nsCString(filename)); + + nsCOMPtr postData; + GetPostData(mBrowser, getter_AddRefs(postData)); + + nsCOMPtr inputChannel; + rv = NS_NewChannel(getter_AddRefs(inputChannel), sourceURI, + nsnull, nsnull, nsnull, nsIRequest::LOAD_NORMAL); + NS_ENSURE_SUCCESS(rv, FALSE); + + nsCOMPtr httpChannel(do_QueryInterface(inputChannel)); + if (httpChannel) { + nsCOMPtr stream(do_QueryInterface(postData)); + if (stream) + { + // Rewind the postdata stream + stream->Seek(nsISeekableStream::NS_SEEK_SET, 0); + nsCOMPtr uploadChannel(do_QueryInterface(httpChannel)); + NS_ASSERTION(uploadChannel, "http must support nsIUploadChannel"); + // Attach the postdata to the http channel + uploadChannel->SetUploadStream(postData, EmptyCString(), -1); + } + } + + nsCOMPtr stream; + rv = inputChannel->Open(getter_AddRefs(stream)); + NS_ENSURE_SUCCESS(rv, FALSE); + + nsCOMPtr fileOutputStream = + do_CreateInstance(NS_LOCALFILEOUTPUTSTREAM_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, FALSE); + + rv = fileOutputStream->Init(destFile, -1, -1, 0); + NS_ENSURE_SUCCESS(rv, FALSE); + + // Read data from the input and write to the output + char buffer[8192]; + PRUint32 bytesRead; + PRUint32 bytesRemaining; + PRBool cancel = PR_FALSE; + PRBool readError; + + rv = stream->Available(&bytesRemaining); + NS_ENSURE_SUCCESS(rv, FALSE); + + while (!cancel && bytesRemaining) + { + readError = PR_TRUE; + rv = stream->Read(buffer, PR_MIN(sizeof(buffer), bytesRemaining), &bytesRead); + if (NS_SUCCEEDED(rv)) + { + readError = PR_FALSE; + // Write out the data until something goes wrong, or, it is + // all written. We loop because for some errors (e.g., disk + // full), we get NS_OK with some bytes written, then an error. + // So, we want to write again in that case to get the actual + // error code. + const char *bufPtr = buffer; // Where to write from. + while (NS_SUCCEEDED(rv) && bytesRead) + { + PRUint32 bytesWritten = 0; + rv = fileOutputStream->Write(bufPtr, bytesRead, &bytesWritten); + if (NS_SUCCEEDED(rv)) + { + bytesRead -= bytesWritten; + bufPtr += bytesWritten; + bytesRemaining -= bytesWritten; + // Force an error if (for some reason) we get NS_OK but + // no bytes written. + if (!bytesWritten) + { + rv = NS_ERROR_FAILURE; + cancel = PR_TRUE; + } + } + else + { + // Disaster - can't write out the bytes - disk full / permission? + cancel = PR_TRUE; + } + } + } + else + { + // Disaster - can't read the bytes - broken link / file error? + cancel = PR_TRUE; + } + } + NS_ENSURE_SUCCESS(rv, FALSE); + + stream->Close(); + + return TRUE; +} diff --git a/browser/GeckoBrowserPersist.h b/browser/GeckoBrowserPersist.h new file mode 100644 index 0000000..e976789 --- /dev/null +++ b/browser/GeckoBrowserPersist.h @@ -0,0 +1,19 @@ +#ifndef __GECKO_BROWSER_PERSIST_H__ +#define __GECKO_BROWSER_PERSIST_H__ + +#include "sugar-browser.h" + +class GeckoBrowserPersist +{ +public: + GeckoBrowserPersist(SugarBrowser *browser); + ~GeckoBrowserPersist(); + + bool SaveURI(const char *uri, const char *filename); +private: + SugarBrowser *mBrowser; +protected: + /* additional members */ +}; + +#endif // __GECKO_BROWSER_PERSIST_H__ diff --git a/browser/GeckoDocumentObject.cpp b/browser/GeckoDocumentObject.cpp new file mode 100644 index 0000000..6f034e1 --- /dev/null +++ b/browser/GeckoDocumentObject.cpp @@ -0,0 +1,187 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "GeckoDocumentObject.h" +#include "GeckoBrowserPersist.h" + +GeckoDocumentObject::GeckoDocumentObject(SugarBrowser *browser, nsIDOMNode *node) + : mBrowser(browser), + mNode(node), + mImage(NULL) +{ +} + +GeckoDocumentObject::~GeckoDocumentObject() +{ +} + +bool GeckoDocumentObject::IsImage() +{ + if(mImage) { + return true; + } + + nsresult rv; + + PRUint16 type; + rv = mNode->GetNodeType(&type); + if(NS_FAILED(rv)) return rv; + + nsCOMPtr element = do_QueryInterface(mNode); + if ((nsIDOMNode::ELEMENT_NODE == type) && element) { + nsString uTag; + rv = element->GetLocalName(uTag); + if(NS_FAILED(rv)) return rv; + + nsCString tag; + NS_UTF16ToCString (uTag, NS_CSTRING_ENCODING_UTF8, tag); + + if (g_ascii_strcasecmp (tag.get(), "img") == 0) { + nsCOMPtr imagePtr; + imagePtr = do_QueryInterface(mNode, &rv); + if(NS_FAILED(rv)) return rv; + + mImage = imagePtr; + + return true; + } + } + + return false; +} + +static nsresult +NewURI(const char *uri, nsIURI **result) +{ + nsresult rv; + + nsCOMPtr mgr; + NS_GetServiceManager (getter_AddRefs (mgr)); + NS_ENSURE_TRUE(mgr, FALSE); + + nsCOMPtr ioService; + rv = mgr->GetServiceByContractID ("@mozilla.org/network/io-service;1", + NS_GET_IID (nsIIOService), + getter_AddRefs(ioService)); + NS_ENSURE_SUCCESS(rv, FALSE); + + nsCString cSpec(uri); + return ioService->NewURI (cSpec, nsnull, nsnull, result); +} + +static nsresult +FilenameFromContentDisposition(nsCString contentDisposition, nsCString &fileName) +{ + nsresult rv; + nsCString fallbackCharset; + + nsCOMPtr mimehdrpar = + do_GetService("@mozilla.org/network/mime-hdrparam;1"); + NS_ENSURE_TRUE(mimehdrpar, NS_ERROR_FAILURE); + + nsString aFileName; + rv = mimehdrpar->GetParameter (contentDisposition, "filename", + fallbackCharset, PR_TRUE, nsnull, + aFileName); + + if (NS_FAILED(rv) || !fileName.Length()) { + rv = mimehdrpar->GetParameter (contentDisposition, "name", + fallbackCharset, PR_TRUE, nsnull, + aFileName); + } + + if (NS_SUCCEEDED(rv) && fileName.Length()) { + NS_UTF16ToCString (aFileName, NS_CSTRING_ENCODING_UTF8, fileName); + } + + return NS_OK; +} + +char * +GeckoDocumentObject::GetImageName() +{ + if(!IsImage()) { + return NULL; + } + + nsresult rv; + char *imgURIStr = GetImageURI(); + + nsCOMPtr imageURI; + rv = NewURI(imgURIStr, getter_AddRefs(imageURI)); + NS_ENSURE_SUCCESS(rv, NULL); + + nsCOMPtr mgr; + NS_GetServiceManager (getter_AddRefs (mgr)); + NS_ENSURE_TRUE(mgr, NULL); + + nsCOMPtr imgCache; + rv = mgr->GetServiceByContractID("@mozilla.org/image/cache;1", + NS_GET_IID (imgICache), + getter_AddRefs(imgCache)); + NS_ENSURE_SUCCESS(rv, NULL); + + nsCOMPtr imgProperties; + imgCache->FindEntryProperties(imageURI, getter_AddRefs(imgProperties)); + if (imgProperties) { + nsCOMPtr dispositionCString; + imgProperties->Get("content-disposition", + NS_GET_IID(nsISupportsCString), + getter_AddRefs(dispositionCString)); + if (dispositionCString) { + nsCString contentDisposition; + dispositionCString->GetData(contentDisposition); + FilenameFromContentDisposition(contentDisposition, mImageName); + } + } + + if (!mImageName.Length()) { + nsCOMPtr url(do_QueryInterface(imageURI)); + if (url) { + url->GetFileName(mImageName); + } + } + + return mImageName.Length() ? g_strdup(mImageName.get()) : NULL; +} + +char * +GeckoDocumentObject::GetImageURI() +{ + if(!IsImage()) { + return NULL; + } + + if(!mImageURI.Length()) { + nsresult rv; + nsString img; + rv = mImage->GetSrc(img); + if (NS_FAILED(rv)) return NULL; + + NS_UTF16ToCString (img, NS_CSTRING_ENCODING_UTF8, mImageURI); + } + return g_strdup(mImageURI.get()); +} + +bool +GeckoDocumentObject::SaveImage(const char *filename) +{ + GeckoBrowserPersist browserPersist(mBrowser); + return browserPersist.SaveURI(mImageURI.get(), filename); +} diff --git a/browser/GeckoDocumentObject.h b/browser/GeckoDocumentObject.h new file mode 100644 index 0000000..05328e5 --- /dev/null +++ b/browser/GeckoDocumentObject.h @@ -0,0 +1,29 @@ +#ifndef __GECKO_DOCUMENT_OBJECT_H__ +#define __GECKO_DOCUMENT_OBJECT_H__ + +#include +#include + +#include "sugar-browser.h" + +class GeckoDocumentObject +{ +public: + GeckoDocumentObject(SugarBrowser *browser, nsIDOMNode *node); + ~GeckoDocumentObject(); + + bool IsImage(); + char *GetImageURI(); + char *GetImageName(); + bool SaveImage(const char *filename); +private: + SugarBrowser *mBrowser; + nsCOMPtr mNode; + nsCOMPtr mImage; + nsCString mImageURI; + nsCString mImageName; +protected: + /* additional members */ +}; + +#endif // __GECKO_DOCUMENT_OBJECT_H__ diff --git a/browser/GeckoDragDropHooks.cpp b/browser/GeckoDragDropHooks.cpp new file mode 100644 index 0000000..425ee45 --- /dev/null +++ b/browser/GeckoDragDropHooks.cpp @@ -0,0 +1,185 @@ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "GeckoDragDropHooks.h" +#include "GeckoDocumentObject.h" + +#define TEXT_URI_LIST "text/uri-list" +#define TEXT_X_MOZ_URL "text/x-moz-url" +#define FILE_LOCALHOST "file://" + +//***************************************************************************** +// UriListDataProvider +//***************************************************************************** + +class UriListDataProvider : public nsIFlavorDataProvider +{ +public: + UriListDataProvider(GeckoDocumentObject *mDocumentObject); + virtual ~UriListDataProvider(); + NS_DECL_ISUPPORTS + NS_DECL_NSIFLAVORDATAPROVIDER +private: + GeckoDocumentObject *mDocumentObject; + nsCString mFilePath; +}; + +//***************************************************************************** + +NS_IMPL_ISUPPORTS1(UriListDataProvider, nsIFlavorDataProvider) + +UriListDataProvider::UriListDataProvider(GeckoDocumentObject *documentObject) + : mDocumentObject(documentObject) +{ +} + +UriListDataProvider::~UriListDataProvider() +{ + if(mFilePath.Length()) { + remove(mFilePath.get()); + } + + delete mDocumentObject; +} + +NS_IMETHODIMP +UriListDataProvider::GetFlavorData(nsITransferable *aTransferable, + const char *aFlavor, nsISupports **aData, + PRUint32 *aDataLen) +{ + NS_ENSURE_ARG_POINTER(aData && aDataLen); + + nsresult rv = NS_ERROR_NOT_IMPLEMENTED; + char *image_name; + timeval timestamp; + + *aData = nsnull; + *aDataLen = 0; + + if(g_ascii_strcasecmp(aFlavor, TEXT_URI_LIST) != 0) { + return rv; + } + + gettimeofday(×tamp, NULL); + + mFilePath.Append(g_get_tmp_dir()); + mFilePath.Append("/"); + mFilePath.AppendInt(timestamp.tv_sec); + mFilePath.AppendInt(timestamp.tv_usec); + + image_name = mDocumentObject->GetImageName(); + mFilePath.Append(image_name); + g_free(image_name); + + if(!mDocumentObject->SaveImage(mFilePath.get())) { + return NS_ERROR_FAILURE; + } + + nsCString localURI(FILE_LOCALHOST); + localURI.Append(mFilePath); + + nsString localURI16; + NS_CStringToUTF16(localURI, NS_CSTRING_ENCODING_UTF8, localURI16); + + nsCOMPtr localURIData(do_CreateInstance( + "@mozilla.org/supports-string;1", &rv)); + if(NS_FAILED(rv)) return rv; + + rv = localURIData->SetData(localURI16); + if(NS_FAILED(rv)) return rv; + + CallQueryInterface(localURIData, aData); + *aDataLen = sizeof(nsISupportsString*); + + // FIXME: Why do we need this? Is there a leak in mozilla? + this->Release(); + + return rv; +} + +//***************************************************************************** +// GeckoDragDropHooks +//***************************************************************************** + +NS_IMPL_ISUPPORTS1(GeckoDragDropHooks, nsIClipboardDragDropHooks) + +GeckoDragDropHooks::GeckoDragDropHooks(SugarBrowser *browser) + : mBrowser(browser) +{ +} + +GeckoDragDropHooks::~GeckoDragDropHooks() +{ +} + +NS_IMETHODIMP +GeckoDragDropHooks::AllowStartDrag(nsIDOMEvent *event, PRBool *_retval) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +GeckoDragDropHooks::AllowDrop(nsIDOMEvent *event, nsIDragSession *session, + PRBool *_retval) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +GeckoDragDropHooks::OnCopyOrDrag(nsIDOMEvent *aEvent, nsITransferable *trans, + PRBool *_retval) +{ + nsresult rv; + + *_retval = true; + + nsCOMPtr mouseEvent; + mouseEvent = do_QueryInterface(aEvent, &rv); + if(NS_FAILED(rv)) return rv; + + nsCOMPtr eventTarget; + rv = mouseEvent->GetTarget(getter_AddRefs(eventTarget)); + if(NS_FAILED(rv)) return rv; + + nsCOMPtr targetNode; + targetNode = do_QueryInterface(eventTarget, &rv); + if(NS_FAILED(rv)) return rv; + + GeckoDocumentObject *documentObject = new GeckoDocumentObject(mBrowser, + targetNode); + if(documentObject->IsImage()) { + rv = trans->RemoveDataFlavor(TEXT_X_MOZ_URL); + if(NS_FAILED(rv)) return rv; + + rv = trans->AddDataFlavor(TEXT_URI_LIST); + if(NS_FAILED(rv)) return rv; + + UriListDataProvider *rawPtr = new UriListDataProvider(documentObject); + nsCOMPtr dataProvider(do_QueryInterface(rawPtr, &rv)); + if(NS_FAILED(rv)) return rv; + + rv = trans->SetTransferData(TEXT_URI_LIST, dataProvider, 0); + if(NS_FAILED(rv)) return rv; + } + + return rv; +} + +NS_IMETHODIMP +GeckoDragDropHooks::OnPasteOrDrop(nsIDOMEvent *event, nsITransferable *trans, + PRBool *_retval) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} diff --git a/browser/GeckoDragDropHooks.h b/browser/GeckoDragDropHooks.h new file mode 100644 index 0000000..c551c0e --- /dev/null +++ b/browser/GeckoDragDropHooks.h @@ -0,0 +1,25 @@ +#ifndef __GECKO_DRAG_DROP_HOOKS_H__ +#define __GECKO_DRAG_DROP_HOOKS_H__ + +#include + +#include "sugar-browser.h" + +class GeckoDragDropHooks : public nsIClipboardDragDropHooks +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSICLIPBOARDDRAGDROPHOOKS + + GeckoDragDropHooks(SugarBrowser *browser); + +private: + ~GeckoDragDropHooks(); + + SugarBrowser *mBrowser; + +protected: + /* additional members */ +}; + +#endif // __GECKO_DRAG_DROP_HOOKS_H__ diff --git a/browser/Makefile.am b/browser/Makefile.am index ae013e0..b418583 100644 --- a/browser/Makefile.am +++ b/browser/Makefile.am @@ -3,6 +3,7 @@ libsugarbrowser_la_CPPFLAGS = \ $(LIB_CFLAGS) \ $(GECKO_CFLAGS) \ $(NSPR_CFLAGS) \ + -I$(MOZILLA_INCLUDE_DIR)/commandhandler \ -I$(MOZILLA_INCLUDE_DIR)/dom \ -I$(MOZILLA_INCLUDE_DIR)/docshell \ -I$(MOZILLA_INCLUDE_DIR)/exthandler \ @@ -15,6 +16,8 @@ libsugarbrowser_la_CPPFLAGS = \ -I$(MOZILLA_INCLUDE_DIR)/uriloader \ -I$(MOZILLA_INCLUDE_DIR)/webbrwsr \ -I$(MOZILLA_INCLUDE_DIR)/webbrowserpersist \ + -I$(MOZILLA_INCLUDE_DIR)/widget \ + -I$(MOZILLA_INCLUDE_DIR)/xpcom \ -DPLUGIN_DIR=\"$(libdir)/mozilla/plugins\" \ -DSHARE_DIR=\"$(pkgdatadir)\" @@ -26,8 +29,14 @@ libsugarbrowser_la_LIBADD = \ libsugarbrowser_la_SOURCES = \ $(BUILT_SOURCES) \ + GeckoBrowserPersist.h \ + GeckoBrowserPersist.cpp \ GeckoContentHandler.h \ GeckoContentHandler.cpp \ + GeckoDocumentObject.h \ + GeckoDocumentObject.cpp \ + GeckoDragDropHooks.h \ + GeckoDragDropHooks.cpp \ GeckoDownload.h \ GeckoDownload.cpp \ sugar-address-entry.c \ diff --git a/browser/sugar-browser.cpp b/browser/sugar-browser.cpp index cd455b6..270631b 100644 --- a/browser/sugar-browser.cpp +++ b/browser/sugar-browser.cpp @@ -23,6 +23,9 @@ #include "sugar-marshal.h" #include "GeckoContentHandler.h" #include "GeckoDownload.h" +#include "GeckoDragDropHooks.h" +#include "GeckoDocumentObject.h" +#include "GeckoBrowserPersist.h" #include #include @@ -56,6 +59,8 @@ #include #include #include +#include +#include enum { PROP_0, @@ -75,6 +80,8 @@ enum { static guint signals[N_SIGNALS]; +static GObjectClass *parent_class = NULL; + static const nsModuleComponentInfo sSugarComponents[] = { { "Gecko Content Handler", @@ -211,25 +218,6 @@ sugar_browser_shutdown(void) G_DEFINE_TYPE(SugarBrowser, sugar_browser, GTK_TYPE_MOZ_EMBED) static nsresult -NewURI(const char *uri, nsIURI **result) -{ - nsresult rv; - - nsCOMPtr mgr; - NS_GetServiceManager (getter_AddRefs (mgr)); - NS_ENSURE_TRUE(mgr, FALSE); - - nsCOMPtr ioService; - rv = mgr->GetServiceByContractID ("@mozilla.org/network/io-service;1", - NS_GET_IID (nsIIOService), - getter_AddRefs(ioService)); - NS_ENSURE_SUCCESS(rv, FALSE); - - nsCString cSpec(uri); - return ioService->NewURI (cSpec, nsnull, nsnull, result); -} - -static nsresult FilenameFromContentDisposition(nsCString contentDisposition, nsCString &fileName) { nsresult rv; @@ -258,38 +246,6 @@ FilenameFromContentDisposition(nsCString contentDisposition, nsCString &fileName return NS_OK; } -static nsresult -ImageNameFromCache(nsIURI *imgURI, nsCString &imgName) -{ - nsresult rv; - - nsCOMPtr mgr; - NS_GetServiceManager (getter_AddRefs (mgr)); - NS_ENSURE_TRUE(mgr, NS_ERROR_FAILURE); - - nsCOMPtr imgCache; - rv = mgr->GetServiceByContractID("@mozilla.org/image/cache;1", - NS_GET_IID (imgICache), - getter_AddRefs(imgCache)); - NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE); - - nsCOMPtr imgProperties; - imgCache->FindEntryProperties(imgURI, getter_AddRefs(imgProperties)); - if (imgProperties) { - nsCOMPtr dispositionCString; - imgProperties->Get("content-disposition", - NS_GET_IID(nsISupportsCString), - getter_AddRefs(dispositionCString)); - if (dispositionCString) { - nsCString contentDisposition; - dispositionCString->GetData(contentDisposition); - FilenameFromContentDisposition(contentDisposition, imgName); - } - } - - return NS_OK; -} - static SugarBrowserMetadata * sugar_browser_get_document_metadata(SugarBrowser *browser) { @@ -382,13 +338,47 @@ sugar_browser_get_property(GObject *object, } } +static void +sugar_browser_realize(GtkWidget *widget) +{ + GTK_WIDGET_CLASS(parent_class)->realize(widget); + +#ifdef HAVE_NS_WEB_BROWSER + GtkMozEmbed *embed = GTK_MOZ_EMBED(widget); + nsCOMPtr webBrowser; + gtk_moz_embed_get_nsIWebBrowser(embed, getter_AddRefs(webBrowser)); + NS_ENSURE_TRUE(webBrowser, ); + + nsCOMPtr commandManager = do_GetInterface(webBrowser); + if (commandManager) { + nsresult rv; + nsIClipboardDragDropHooks *rawPtr = new GeckoDragDropHooks( + SUGAR_BROWSER(widget)); + nsCOMPtr geckoDragDropHooks( + do_QueryInterface(rawPtr, &rv)); + NS_ENSURE_SUCCESS(rv, ); + + nsCOMPtr DOMWindow = do_GetInterface(webBrowser); + nsCOMPtr cmdParamsObj = do_CreateInstance( + NS_COMMAND_PARAMS_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, ); + cmdParamsObj->SetISupportsValue("addhook", geckoDragDropHooks); + commandManager->DoCommand("cmd_clipboardDragDropHook", cmdParamsObj, + DOMWindow); + } +#endif +} static void sugar_browser_class_init(SugarBrowserClass *browser_class) { - GObjectClass *gobject_class = G_OBJECT_CLASS(browser_class); + GObjectClass *gobject_class = G_OBJECT_CLASS(browser_class); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(browser_class); - gobject_class->get_property = sugar_browser_get_property; + parent_class = (GObjectClass *) g_type_class_peek_parent(browser_class); + + gobject_class->get_property = sugar_browser_get_property; + widget_class->realize = sugar_browser_realize; signals[MOUSE_CLICK] = g_signal_new ("mouse_click", SUGAR_TYPE_BROWSER, @@ -570,29 +560,6 @@ location_cb(GtkMozEmbed *embed) update_navigation_properties(browser); } -static char * -get_image_name(const char *uri) -{ - nsresult rv; - - nsCString imgName; - - nsCOMPtr imgURI; - rv = NewURI(uri, getter_AddRefs(imgURI)); - NS_ENSURE_SUCCESS(rv, NULL); - - ImageNameFromCache(imgURI, imgName); - - if (!imgName.Length()) { - nsCOMPtr url(do_QueryInterface(imgURI)); - if (url) { - url->GetFileName(imgName); - } - } - - return imgName.Length() ? g_strdup(imgName.get()) : NULL; -} - static gboolean dom_mouse_click_cb(GtkMozEmbed *embed, nsIDOMMouseEvent *mouseEvent) { @@ -610,36 +577,10 @@ dom_mouse_click_cb(GtkMozEmbed *embed, nsIDOMMouseEvent *mouseEvent) event = sugar_browser_event_new(); - nsresult rv; - - PRUint16 type; - rv = targetNode->GetNodeType(&type); - if (NS_FAILED(rv)) return NS_ERROR_FAILURE; - - nsCOMPtr element = do_QueryInterface(targetNode); - if ((nsIDOMNode::ELEMENT_NODE == type) && element) { - nsString uTag; - rv = element->GetLocalName(uTag); - if (NS_FAILED(rv)) return NS_ERROR_FAILURE; - - nsCString tag; - NS_UTF16ToCString (uTag, NS_CSTRING_ENCODING_UTF8, tag); - - if (g_ascii_strcasecmp (tag.get(), "img") == 0) { - nsString img; - - nsCOMPtr image; - image = do_QueryInterface(targetNode, &rv); - if (NS_FAILED(rv) || !image) return NS_ERROR_FAILURE; - - rv = image->GetSrc(img); - if (NS_FAILED(rv)) return NS_ERROR_FAILURE; - - nsCString cImg; - NS_UTF16ToCString (img, NS_CSTRING_ENCODING_UTF8, cImg); - event->image_uri = g_strdup(cImg.get()); - event->image_name = get_image_name(event->image_uri); - } + GeckoDocumentObject documentObject(browser, targetNode); + if(documentObject.IsImage()) { + event->image_uri = documentObject.GetImageURI(); + event->image_name = documentObject.GetImageName(); } PRUint16 btn = 0; @@ -712,74 +653,13 @@ sugar_browser_grab_focus(SugarBrowser *browser) } } - -static nsresult -GetPostData(SugarBrowser *browser, nsIInputStream **postData) -{ -#ifdef HAVE_NS_WEB_BROWSER - nsCOMPtr webBrowser; - gtk_moz_embed_get_nsIWebBrowser(GTK_MOZ_EMBED(browser), - getter_AddRefs(webBrowser)); - NS_ENSURE_TRUE(webBrowser, NS_ERROR_FAILURE); - - nsCOMPtr webNav(do_QueryInterface(webBrowser)); - NS_ENSURE_TRUE(webNav, NS_ERROR_FAILURE); - - PRInt32 sindex; - - nsCOMPtr sessionHistory; - webNav->GetSessionHistory(getter_AddRefs(sessionHistory)); - NS_ENSURE_TRUE(sessionHistory, NS_ERROR_FAILURE); - - nsCOMPtr entry; - sessionHistory->GetIndex(&sindex); - sessionHistory->GetEntryAtIndex(sindex, PR_FALSE, getter_AddRefs(entry)); - - nsCOMPtr shEntry(do_QueryInterface(entry)); - if (shEntry) { - shEntry->GetPostData(postData); - } - - return NS_OK; -#endif - return NS_ERROR_NOT_IMPLEMENTED; -} - gboolean sugar_browser_save_uri(SugarBrowser *browser, const char *uri, const char *filename) { -#ifdef HAVE_NS_WEB_BROWSER - nsresult rv; - - nsCOMPtr sourceURI; - rv = NewURI(uri, getter_AddRefs(sourceURI)); - NS_ENSURE_SUCCESS(rv, FALSE); - - nsCOMPtr destFile = do_CreateInstance("@mozilla.org/file/local;1"); - NS_ENSURE_TRUE(destFile, FALSE); - - destFile->InitWithNativePath(nsCString(filename)); - - nsCOMPtr webBrowser; - gtk_moz_embed_get_nsIWebBrowser(GTK_MOZ_EMBED(browser), - getter_AddRefs(webBrowser)); - NS_ENSURE_TRUE(webBrowser, FALSE); - - nsCOMPtr webPersist = do_QueryInterface (webBrowser); - NS_ENSURE_TRUE(webPersist, FALSE); - - nsCOMPtr postData; - GetPostData(browser, getter_AddRefs(postData)); - - rv = webPersist->SaveURI(sourceURI, nsnull, nsnull, postData, nsnull, destFile); - NS_ENSURE_SUCCESS(rv, FALSE); - - return TRUE; -#else - return FALSE; -#endif + GeckoBrowserPersist browserPersist(browser); + return browserPersist.SaveURI(uri, filename); } gboolean -- cgit v0.9.1