From 30ee6768a2049d467b6825a49745cf9552e113e3 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Sat, 17 Mar 2007 13:26:10 +0000 Subject: Add document metadata property. Expose the filename. --- (limited to 'lib') diff --git a/lib/python/_sugar.defs b/lib/python/_sugar.defs index 4788250..c894777 100644 --- a/lib/python/_sugar.defs +++ b/lib/python/_sugar.defs @@ -9,6 +9,14 @@ (release-func "sugar_browser_event_free") ) +(define-boxed SugarBrowserMetadata + (in-module "Sugar") + (c-name "SugarBrowserMetadata") + (gtype-id "SUGAR_TYPE_BROWSER_METADATA") + (copy-func "sugar_browser_metadata_copy") + (release-func "sugar_browser_metadata_free") +) + (define-object AddressEntry (in-module "Sugar") (parent "GtkEntry") diff --git a/lib/python/_sugar.override b/lib/python/_sugar.override index 303b378..1e328e9 100644 --- a/lib/python/_sugar.override +++ b/lib/python/_sugar.override @@ -179,6 +179,26 @@ _wrap_sugar_cairo_surface_from_gdk_pixbuf(PyGObject *self, PyObject *args, PyObj return PycairoSurface_FromSurface(surface, NULL); } %% +override-slot SugarBrowserMetadata.tp_getattr +static PyObject * +_wrap_sugar_browser_metadata_tp_getattr(PyObject *self, char *attr) +{ + SugarBrowserMetadata *metadata = pyg_boxed_get(self, SugarBrowserMetadata); + + if (!strcmp(attr, "__members__")) + return Py_BuildValue("[s]", "filename"); + else if (!strcmp(attr, "filename")) { + if (metadata->filename) { + return PyString_FromString(metadata->filename); + } else { + Py_INCREF(Py_None); + return Py_None; + } + } + + return NULL; +} +%% override-slot SugarBrowserEvent.tp_getattr static PyObject * _wrap_sugar_browser_event_tp_getattr(PyObject *self, char *attr) diff --git a/lib/src/Makefile.am b/lib/src/Makefile.am index 668a821..bdf5dcc 100644 --- a/lib/src/Makefile.am +++ b/lib/src/Makefile.am @@ -4,6 +4,7 @@ libsugarprivate_la_CPPFLAGS = \ $(GECKO_CFLAGS) \ $(NSPR_CFLAGS) \ -I$(MOZILLA_INCLUDE_DIR)/dom \ + -I$(MOZILLA_INCLUDE_DIR)/docshell \ -I$(MOZILLA_INCLUDE_DIR)/exthandler \ -I$(MOZILLA_INCLUDE_DIR)/gtkembedmoz \ -I$(MOZILLA_INCLUDE_DIR)/imglib2 \ diff --git a/lib/src/sugar-browser.cpp b/lib/src/sugar-browser.cpp index bac70d0..8385e1d 100644 --- a/lib/src/sugar-browser.cpp +++ b/lib/src/sugar-browser.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -46,7 +47,9 @@ #include #include #include +#include #include +#include #include enum { @@ -56,7 +59,8 @@ enum { PROP_ADDRESS, PROP_CAN_GO_BACK, PROP_CAN_GO_FORWARD, - PROP_LOADING + PROP_LOADING, + PROP_DOCUMENT_METADATA }; enum { @@ -169,6 +173,140 @@ 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; + + 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; +} + +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) +{ + SugarBrowserMetadata *metadata = sugar_browser_metadata_new(); + +#ifdef HAVE_NS_WEB_BROWSER + nsCOMPtr webBrowser; + gtk_moz_embed_get_nsIWebBrowser(GTK_MOZ_EMBED(browser), + getter_AddRefs(webBrowser)); + NS_ENSURE_TRUE(webBrowser, metadata); + + nsCOMPtr DOMWindow; + webBrowser->GetContentDOMWindow(getter_AddRefs(DOMWindow)); + NS_ENSURE_TRUE(DOMWindow, metadata); + + nsCOMPtr DOMWindowUtils(do_GetInterface(DOMWindow)); + NS_ENSURE_TRUE(DOMWindowUtils, metadata); + + const PRUnichar contentDispositionLiteral[] = + {'c', 'o', 'n', 't', 'e', 'n', 't', '-', 'd', 'i', 's', 'p', + 'o', 's', 'i', 't', 'i', 'o', 'n', '\0'}; + + nsString contentDisposition; + DOMWindowUtils->GetDocumentMetadata(nsString(contentDispositionLiteral), + contentDisposition); + + nsCString cContentDisposition; + NS_UTF16ToCString (contentDisposition, NS_CSTRING_ENCODING_UTF8, + cContentDisposition); + + nsCString fileName; + FilenameFromContentDisposition(cContentDisposition, fileName); + + if (!fileName.Length()) { + nsCOMPtr webNav(do_QueryInterface(webBrowser)); + if (webNav) { + nsCOMPtr docURI; + webNav->GetCurrentURI (getter_AddRefs(docURI)); + + nsCOMPtr url(do_QueryInterface(docURI)); + if (url) { + url->GetFileName(fileName); + } + } + } + + if (fileName.Length()) { + metadata->filename = g_strdup(fileName.get()); + } +#endif + + return metadata; +} + static void sugar_browser_get_property(GObject *object, guint prop_id, @@ -196,6 +334,11 @@ sugar_browser_get_property(GObject *object, case PROP_LOADING: g_value_set_boolean(value, browser->loading); break; + case PROP_DOCUMENT_METADATA: + SugarBrowserMetadata *metadata; + metadata = sugar_browser_get_document_metadata(browser); + g_value_set_boxed(value, metadata); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -261,6 +404,14 @@ sugar_browser_class_init(SugarBrowserClass *browser_class) "Loading", FALSE, G_PARAM_READABLE)); + + g_object_class_install_property(gobject_class, PROP_DOCUMENT_METADATA, + g_param_spec_boxed("document-metadata", + "Document Metadata", + "Document metadata", + SUGAR_TYPE_BROWSER_METADATA, + G_PARAM_READABLE)); + } SugarBrowser * @@ -380,76 +531,6 @@ location_cb(GtkMozEmbed *embed) update_navigation_properties(browser); } -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 -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 fallbackCharset; - - nsCString contentDisposition; - dispositionCString->GetData(contentDisposition); - - nsCOMPtr mimehdrpar = - do_GetService("@mozilla.org/network/mime-hdrparam;1"); - NS_ENSURE_TRUE(mimehdrpar, NS_ERROR_FAILURE); - - nsString fileName; - rv = mimehdrpar->GetParameter (contentDisposition, "filename", - fallbackCharset, PR_TRUE, nsnull, - fileName); - - if (NS_FAILED(rv) || !fileName.Length()) { - rv = mimehdrpar->GetParameter (contentDisposition, "name", - fallbackCharset, PR_TRUE, nsnull, - fileName); - } - - if (NS_SUCCEEDED(rv) && fileName.Length()) { - nsCString cFileName; - NS_UTF16ToCString (fileName, NS_CSTRING_ENCODING_UTF8, imgName); - } - } - } -} - static char * get_image_name(const char *uri) { @@ -731,3 +812,52 @@ sugar_browser_event_free(SugarBrowserEvent *event) g_free(event); } + +GType +sugar_browser_metadata_get_type(void) +{ + static GType type = 0; + + if (G_UNLIKELY(type == 0)) { + type = g_boxed_type_register_static("SugarBrowserMetadata", + (GBoxedCopyFunc)sugar_browser_metadata_copy, + (GBoxedFreeFunc)sugar_browser_metadata_free); + } + + return type; +} + +SugarBrowserMetadata * +sugar_browser_metadata_new(void) +{ + SugarBrowserMetadata *metadata; + + metadata = g_new0(SugarBrowserMetadata, 1); + + return metadata; +} + +SugarBrowserMetadata * +sugar_browser_metadata_copy(SugarBrowserMetadata *metadata) +{ + SugarBrowserMetadata *copy; + + g_return_val_if_fail(metadata != NULL, NULL); + + copy = g_new0(SugarBrowserMetadata, 1); + copy->filename = g_strdup(metadata->filename); + + return copy; +} + +void +sugar_browser_metadata_free(SugarBrowserMetadata *metadata) +{ + g_return_if_fail(metadata != NULL); + + if (metadata->filename) { + g_free(metadata->filename); + } + + g_free(metadata); +} diff --git a/lib/src/sugar-browser.h b/lib/src/sugar-browser.h index fbce875..43108ec 100644 --- a/lib/src/sugar-browser.h +++ b/lib/src/sugar-browser.h @@ -24,9 +24,10 @@ G_BEGIN_DECLS -typedef struct _SugarBrowser SugarBrowser; -typedef struct _SugarBrowserClass SugarBrowserClass; -typedef struct _SugarBrowserEvent SugarBrowserEvent; +typedef struct _SugarBrowser SugarBrowser; +typedef struct _SugarBrowserClass SugarBrowserClass; +typedef struct _SugarBrowserEvent SugarBrowserEvent; +typedef struct _SugarBrowserMetadata SugarBrowserMetadata; #define SUGAR_TYPE_BROWSER (sugar_browser_get_type()) #define SUGAR_BROWSER(object) (G_TYPE_CHECK_INSTANCE_CAST((object), SUGAR_TYPE_BROWSER, SugarBrowser)) @@ -86,6 +87,17 @@ SugarBrowserEvent *sugar_browser_event_new (void); SugarBrowserEvent *sugar_browser_event_copy (SugarBrowserEvent *event); void sugar_browser_event_free (SugarBrowserEvent *event); +#define SUGAR_TYPE_BROWSER_METADATA (sugar_browser_metadata_get_type()) + +struct _SugarBrowserMetadata { + char *filename; +}; + +GType sugar_browser_metadata_get_type (void); +SugarBrowserMetadata *sugar_browser_metadata_new (void); +SugarBrowserMetadata *sugar_browser_metadata_copy (SugarBrowserMetadata *event); +void sugar_browser_metadata_free (SugarBrowserMetadata *event); + G_END_DECLS #endif -- cgit v0.9.1