From fbf4b15ed54be3abfe2c3c937c50b9c623804cb5 Mon Sep 17 00:00:00 2001 From: Christian Persch Date: Sat, 26 Feb 2005 22:01:48 +0000 Subject: Depend on gnome-desktop for gnome-desktop-item, and up the gnome-vfs 2005-02-26 Christian Persch * configure.ac: Depend on gnome-desktop for gnome-desktop-item, and up the gnome-vfs dependency version. * embed/ephy-embed-persist.c: (ephy_embed_persist_set_user_time), (ephy_embed_persist_get_user_time), (ephy_embed_persist_set_property), (ephy_embed_persist_get_property), (ephy_embed_persist_init), (ephy_embed_persist_class_init): * embed/ephy-embed-persist.h: Add user time property. * embed/mozilla/ContentHandler.cpp: * embed/mozilla/ContentHandler.h: Forward user time to MozDownload via a string. Not perfect, but better than nothing. * embed/mozilla/EphyHeaderSniffer.cpp: Set user time on filechooser. * embed/mozilla/MozDownload.cpp: Get user time from content handler, and use it when launching the external handler app. * lib/ephy-file-helpers.c: (ephy_file_check_mime), (launch_desktop_item), (ephy_file_launch_desktop_file), (ephy_file_launch_application), (ephy_file_launch_handler): * lib/ephy-file-helpers.h: Convenience functions to launch an app, or a desktop item, with user time. * lib/ephy-gui.c: (ephy_gui_confirm_overwrite_file), (ephy_gui_window_update_user_time), (ephy_gui_window_present): * lib/ephy-gui.h: Make our own gtk_window_present, to correctly update user time. Check if the path is writable in ephy_gui_confirm_overwrite_file(). * src/ephy-session.c: (ephy_session_autoresume): After showing the recovery dialogue, don't use the old user time to launch the windows; use the current event time instead. * src/popup-commands.c: (background_download_completed), (image_open_uri), (save_source_completed_cb), (popup_cmd_open_image): * src/window-commands.c: (window_cmd_file_save_as), (save_source_completed_cb), (save_temp_source), (window_cmd_view_page_source): Launch handlers with user time. --- ChangeLog | 60 +++++++++++++ configure.ac | 8 +- embed/ephy-embed-persist.c | 62 ++++++++++++- embed/ephy-embed-persist.h | 4 + embed/mozilla/ContentHandler.cpp | 41 +++++++-- embed/mozilla/ContentHandler.h | 1 + embed/mozilla/EphyHeaderSniffer.cpp | 8 ++ embed/mozilla/MozDownload.cpp | 52 ++++++----- lib/ephy-file-helpers.c | 171 +++++++++++++++++++++++++++++++++++- lib/ephy-file-helpers.h | 14 ++- lib/ephy-gui.c | 50 ++++++++++- lib/ephy-gui.h | 3 + src/ephy-session.c | 4 +- src/popup-commands.c | 72 +++++---------- src/window-commands.c | 46 +++------- 15 files changed, 468 insertions(+), 128 deletions(-) diff --git a/ChangeLog b/ChangeLog index 80bb643e1..764de7c47 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,63 @@ +2005-02-26 Christian Persch + + * configure.ac: + + Depend on gnome-desktop for gnome-desktop-item, + and up the gnome-vfs dependency version. + + * embed/ephy-embed-persist.c: (ephy_embed_persist_set_user_time), + (ephy_embed_persist_get_user_time), + (ephy_embed_persist_set_property), + (ephy_embed_persist_get_property), (ephy_embed_persist_init), + (ephy_embed_persist_class_init): + * embed/ephy-embed-persist.h: + + Add user time property. + + * embed/mozilla/ContentHandler.cpp: + * embed/mozilla/ContentHandler.h: + + Forward user time to MozDownload via a string. Not perfect, + but better than nothing. + + * embed/mozilla/EphyHeaderSniffer.cpp: + + Set user time on filechooser. + + * embed/mozilla/MozDownload.cpp: + + Get user time from content handler, and use it when + launching the external handler app. + + * lib/ephy-file-helpers.c: (ephy_file_check_mime), + (launch_desktop_item), (ephy_file_launch_desktop_file), + (ephy_file_launch_application), (ephy_file_launch_handler): + * lib/ephy-file-helpers.h: + + Convenience functions to launch an app, or a desktop item, + with user time. + + * lib/ephy-gui.c: (ephy_gui_confirm_overwrite_file), + (ephy_gui_window_update_user_time), (ephy_gui_window_present): + * lib/ephy-gui.h: + + Make our own gtk_window_present, to correctly update user time. + Check if the path is writable in ephy_gui_confirm_overwrite_file(). + + * src/ephy-session.c: (ephy_session_autoresume): + + After showing the recovery dialogue, don't use the old user time + to launch the windows; use the current event time instead. + + * src/popup-commands.c: (background_download_completed), + (image_open_uri), (save_source_completed_cb), + (popup_cmd_open_image): + * src/window-commands.c: (window_cmd_file_save_as), + (save_source_completed_cb), (save_temp_source), + (window_cmd_view_page_source): + + Launch handlers with user time. + 2005-02-24 Christian Persch * src/ephy-link.c: (ephy_link_base_init): diff --git a/configure.ac b/configure.ac index 4527232c2..c32e89793 100644 --- a/configure.ac +++ b/configure.ac @@ -48,10 +48,10 @@ PANGO_REQUIRED=1.8.0 GTK_REQUIRED=2.6.0 LIBXML_REQUIRED=2.6.12 LIBXSLT_REQUIRED=1.1.7 -LIBGNOMEVFS_REQUIRED=2.3.1 LIBGLADE_REQUIRED=2.3.1 +LIBGNOMEVFS_REQUIRED=2.9.2 LIBGNOMEUI_REQUIRED=2.6.0 -GNOME_ICON_THEME_REQUIRED=2.9.90 +GNOME_DESKTOP_REQUIRED=2.9.91 AC_ENABLE_SHARED([yes]) AC_ENABLE_STATIC([no]) @@ -68,7 +68,7 @@ AC_PATH_PROG([GLIB_GENMARSHAL], [glib-genmarshal]) AC_PATH_PROG([GLIB_MKENUMS],[glib-mkenums]) GNOME_DEBUG_CHECK -GNOME_COMPILE_WARNINGS([error]) +GNOME_COMPILE_WARNINGS([maximum]) dnl GNOME_CXX_WARNINGS PKG_CHECK_MODULES([EPIPHANY_DEPENDENCY], [\ @@ -85,7 +85,7 @@ PKG_CHECK_MODULES([EPIPHANY_DEPENDENCY], [\ gnome-vfs-2.0 >= $LIBGNOMEVFS_REQUIRED \ gnome-vfs-module-2.0 \ gconf-2.0 \ - gnome-icon-theme >= $GNOME_ICON_THEME_REQUIRED \ + gnome-desktop-2.0 >= $GNOME_DESKTOP_REQUIRED \ ]) AC_SUBST([EPIPHANY_DEPENDENCY_CFLAGS]) AC_SUBST([EPIPHANY_DEPENDENCY_LIBS]) diff --git a/embed/ephy-embed-persist.c b/embed/ephy-embed-persist.c index 92d7a99c8..cd065d628 100644 --- a/embed/ephy-embed-persist.c +++ b/embed/ephy-embed-persist.c @@ -25,6 +25,8 @@ #include "mozilla-embed-persist.h" #include "ephy-debug.h" +#include + enum { PROP_0, @@ -36,7 +38,8 @@ enum PROP_HANDLER, PROP_MAX_SIZE, PROP_PERSISTKEY, - PROP_SOURCE, + PROP_SOURCE, + PROP_USER_TIME }; #define EPHY_EMBED_PERSIST_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_EMBED_PERSIST, EphyEmbedPersistPrivate)) @@ -51,6 +54,7 @@ struct _EphyEmbedPersistPrivate long max_size; EphyEmbedPersistFlags flags; GtkWindow *fc_parent; + guint32 user_time; }; static void ephy_embed_persist_class_init (EphyEmbedPersistClass *klass); @@ -238,6 +242,26 @@ ephy_embed_persist_set_source (EphyEmbedPersist *persist, persist->priv->source = g_strdup (value); } +/** + * ephy_embed_persist_set_user_time: + * @persist: an #EphyEmbedPersist + * @user_time: a timestamp, or 0 + * + * Sets the time stamp of the user action which created @persist. + * Defaults to gtk_get_current_event_time() when @persist is created. + **/ +void +ephy_embed_persist_set_user_time (EphyEmbedPersist *persist, + guint32 user_time) +{ + g_return_if_fail (EPHY_IS_EMBED_PERSIST (persist)); + + LOG ("ephy_embed_persist_set_user_time persist %p user-time %d", + persist, user_time); + + persist->priv->user_time = user_time; +} + /** * ephy_embed_persist_get_dest: * @persist: an #EphyEmbedPersist @@ -367,6 +391,24 @@ ephy_embed_persist_get_source (EphyEmbedPersist *persist) return persist->priv->source; } +/** + * ephy_embed_persist_get_user_time: + * @persist: an #EphyEmbedPersist + * + * Returns the timestamp of the user action which created @persist. + * If not set explicitly, defaults to gtk_get_current_event_time () + * at the time of creation of @persist. + * + * Return value: a timestamp, or 0 + **/ +guint32 +ephy_embed_persist_get_user_time (EphyEmbedPersist *persist) +{ + g_return_val_if_fail (EPHY_IS_EMBED_PERSIST (persist), 0); + + return persist->priv->user_time; +} + static void ephy_embed_persist_set_property (GObject *object, guint prop_id, @@ -401,6 +443,9 @@ ephy_embed_persist_set_property (GObject *object, case PROP_SOURCE: ephy_embed_persist_set_source (persist, g_value_get_string (value)); break; + case PROP_USER_TIME: + ephy_embed_persist_set_user_time (persist, g_value_get_uint (value)); + break; } } @@ -438,6 +483,9 @@ ephy_embed_persist_get_property (GObject *object, case PROP_SOURCE: g_value_set_string (value, ephy_embed_persist_get_source (persist)); break; + case PROP_USER_TIME: + g_value_set_uint (value, ephy_embed_persist_get_user_time (persist)); + break; } } @@ -449,6 +497,8 @@ ephy_embed_persist_init (EphyEmbedPersist *persist) LOG ("EphyEmbedPersist initialising %p", persist); persist->priv->max_size = -1; + + ephy_embed_persist_set_user_time (persist, gtk_get_current_event_time ()); } static void @@ -585,6 +635,16 @@ ephy_embed_persist_class_init (EphyEmbedPersistClass *klass) NULL, G_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_USER_TIME, + g_param_spec_uint ("user-time", + "User Time", + "User Time", + 0, + G_MAXUINT, + 0, + G_PARAM_READWRITE)); + g_type_class_add_private (object_class, sizeof(EphyEmbedPersistPrivate)); } diff --git a/embed/ephy-embed-persist.h b/embed/ephy-embed-persist.h index d8969e341..a0ea180c8 100644 --- a/embed/ephy-embed-persist.h +++ b/embed/ephy-embed-persist.h @@ -105,6 +105,8 @@ void ephy_embed_persist_set_persist_key (EphyEmbedPersist *persist, void ephy_embed_persist_set_source (EphyEmbedPersist *persist, const char *value); +void ephy_embed_persist_set_user_time (EphyEmbedPersist *persist, + guint32 user_time); const char *ephy_embed_persist_get_dest (EphyEmbedPersist *persist); @@ -122,6 +124,8 @@ const char *ephy_embed_persist_get_persist_key (EphyEmbedPersist *persist); const char *ephy_embed_persist_get_source (EphyEmbedPersist *persist); +guint32 ephy_embed_persist_get_user_time (EphyEmbedPersist *persist); + char *ephy_embed_persist_to_string (EphyEmbedPersist *persist); G_END_DECLS diff --git a/embed/mozilla/ContentHandler.cpp b/embed/mozilla/ContentHandler.cpp index 91c9d081d..ef2e07b6b 100644 --- a/embed/mozilla/ContentHandler.cpp +++ b/embed/mozilla/ContentHandler.cpp @@ -25,11 +25,14 @@ #include "config.h" +#include "ContentHandler.h" + #include #include #include #include #include +#include #include #include #include @@ -55,17 +58,22 @@ #include "ephy-debug.h" #include "eel-gconf-extensions.h" -#include "ContentHandler.h" #include "MozDownload.h" #include "EphyUtils.h" +/* FIXME: we don't generally have a timestamp for the user action which initiated this + * content handler. + */ #ifdef MOZ_NSIMIMEINFO_NSACSTRING_ GContentHandler::GContentHandler() +: mUserTime(0) { LOG ("GContentHandler ctor (%p)", this); } #else -GContentHandler::GContentHandler() : mMimeType(nsnull) +GContentHandler::GContentHandler() +: mMimeType(nsnull) +, mUserTime(0) { LOG ("GContentHandler ctor (%p)", this); } @@ -156,6 +164,9 @@ NS_IMETHODIMP GContentHandler::PromptForSaveToFile( GTK_WINDOW (dialog)); } + /* FIXME: this will only be the real user time if we came from ::Show */ + ephy_gui_window_update_user_time (GTK_WIDGET (dialog), (guint32) mUserTime); + /* FIXME: modal -- mozilla sucks! */ do { @@ -267,7 +278,7 @@ NS_METHOD GContentHandler::MIMEConfirmAction () { dialog = gtk_message_dialog_new (parentWindow, GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_WARNING, GTK_BUTTONS_NONE, + GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, /* translators: %s is the name of the application */ _("Open this file with \"%s\"?"), mHelperApp->name); @@ -283,7 +294,7 @@ NS_METHOD GContentHandler::MIMEConfirmAction () { dialog = gtk_message_dialog_new (parentWindow, GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_WARNING, GTK_BUTTONS_NONE, + GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, _("Download the file?")); gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), @@ -312,6 +323,10 @@ NS_METHOD GContentHandler::MIMEConfirmAction () g_signal_connect_data (dialog, "response", G_CALLBACK (response_cb), this, (GClosureNotify) release_cb, (GConnectFlags) 0); + + /* FIXME: should find a way to get the user time of the user action which + * initiated this content handler + */ gtk_window_present (GTK_WINDOW (dialog)); return NS_OK; @@ -361,16 +376,30 @@ NS_METHOD GContentHandler::MIMEInitiateAction (void) NS_METHOD GContentHandler::MIMEDoAction (void) { + /* This is okay, since we either clicked on a button, or we get 0 */ + mUserTime = gtk_get_current_event_time (); + nsCOMPtr mimeInfo; mLauncher->GetMIMEInfo(getter_AddRefs(mimeInfo)); NS_ENSURE_TRUE (mimeInfo, NS_ERROR_FAILURE); if (mAction == CONTENT_ACTION_OPEN) { - nsEmbedString desc; + g_return_val_if_fail (mHelperApp, NS_ERROR_FAILURE); + + const char *id; + id = gnome_vfs_mime_application_get_desktop_id (mHelperApp); + + /* The current time is fine here as the user has just clicked + * a button (it is used as the time for the application opening) + */ + char *info; + info = g_strdup_printf ("gnome-default:%d:%s", gtk_get_current_event_time(), id); - NS_CStringToUTF16 (nsEmbedCString ("gnome-default"), + nsEmbedString desc; + NS_CStringToUTF16 (nsEmbedCString (info), NS_CSTRING_ENCODING_UTF8, desc); + g_free (info); /* HACK we use the application description to ask MozDownload to open the file when download diff --git a/embed/mozilla/ContentHandler.h b/embed/mozilla/ContentHandler.h index 3401a68cb..6a8c58472 100644 --- a/embed/mozilla/ContentHandler.h +++ b/embed/mozilla/ContentHandler.h @@ -84,6 +84,7 @@ class GContentHandler : public nsIHelperAppLauncherDialog #else char *mMimeType; #endif + PRUint32 mUserTime; }; #endif /* CONTENT_HANDLER_H */ diff --git a/embed/mozilla/EphyHeaderSniffer.cpp b/embed/mozilla/EphyHeaderSniffer.cpp index 293416b28..7676c245f 100644 --- a/embed/mozilla/EphyHeaderSniffer.cpp +++ b/embed/mozilla/EphyHeaderSniffer.cpp @@ -351,10 +351,17 @@ nsresult EphyHeaderSniffer::PerformSave (nsIURI* inOriginalURI) EphyFileChooser *dialog; GtkWindow *window; const char *title; + guint32 user_time; title = ephy_embed_persist_get_fc_title (EPHY_EMBED_PERSIST (mEmbedPersist)); window = ephy_embed_persist_get_fc_parent (EPHY_EMBED_PERSIST (mEmbedPersist)); + user_time = ephy_embed_persist_get_user_time (EPHY_EMBED_PERSIST (mEmbedPersist)); + if (user_time == 0) + { + g_warning ("EphyHeaderSniffer::PerformSave without valid user time!\n"); + } + dialog = ephy_file_chooser_new (title ? title: _("Save"), GTK_WIDGET (window), GTK_FILE_CHOOSER_ACTION_SAVE, @@ -367,6 +374,7 @@ nsresult EphyHeaderSniffer::PerformSave (nsIURI* inOriginalURI) g_signal_connect (dialog, "response", G_CALLBACK (filechooser_response_cb), this); + ephy_gui_window_update_user_time (GTK_WIDGET (dialog), user_time); gtk_widget_show (GTK_WIDGET (dialog)); g_free (filename); diff --git a/embed/mozilla/MozDownload.cpp b/embed/mozilla/MozDownload.cpp index 8160f2715..140eb98fc 100644 --- a/embed/mozilla/MozDownload.cpp +++ b/embed/mozilla/MozDownload.cpp @@ -61,6 +61,9 @@ #include #undef MOZILLA_STRICT_API +#include +#include + const char* const persistContractID = "@mozilla.org/embedding/browser/nsWebBrowserPersist;1"; MozDownload::MozDownload() : @@ -365,58 +368,61 @@ MozDownload::OnStateChange (nsIWebProgress *aWebProgress, nsIRequest *aRequest, else if (NS_SUCCEEDED (aStatus)) { GnomeVFSMimeApplication *helperApp; -#ifdef MOZ_NSIMIMEINFO_NSACSTRING_ nsEmbedCString mimeType; +#ifdef MOZ_NSIMIMEINFO_NSACSTRING_ rv = mMIMEInfo->GetMIMEType (mimeType); NS_ENSURE_SUCCESS (rv, NS_ERROR_FAILURE); - helperApp = gnome_vfs_mime_get_default_application (mimeType.get()); - nsEmbedString description; mMIMEInfo->GetApplicationDescription (description); nsEmbedCString cDesc; NS_UTF16ToCString (description, NS_CSTRING_ENCODING_UTF8, cDesc); - - /* HACK we use the application description to decide - if we have to open the saved file */ - if ((strcmp (cDesc.get(), "gnome-default") == 0) && - helperApp) #else char *mimeType; rv = mMIMEInfo->GetMIMEType (&mimeType); NS_ENSURE_SUCCESS (rv, NS_ERROR_FAILURE); - helperApp = gnome_vfs_mime_get_default_application (mimeType); + if (mime) + { + mimeType.Assign (mime); + nsMemory::Free (mime); + } PRUnichar *description; mMIMEInfo->GetApplicationDescription (&description); + NS_ENSURE_TRUE (description, NS_ERROR_FAILURE); nsEmbedCString cDesc; NS_UTF16ToCString (nsEmbedString(description), NS_CSTRING_ENCODING_UTF8, cDesc); + nsMemory::Free (description); +#endif + /* HACK we use the application description to decide if we have to open the saved file */ - if (strcmp (cDesc.get(), "gnome-default") == 0 && - helperApp) -#endif + if (g_str_has_suffix (cDesc.get(), "gnome-default:")) { - GList *params = NULL; - char *param; - nsEmbedCString aDest; + /* Format gnome-default:: */ + char **str = g_strsplit (cDesc.get(), ":", -1); + g_return_val_if_fail (g_strv_length (str) != 3, NS_ERROR_FAILURE); - mDestination->GetSpec (aDest); + char *end; + guint32 user_time = strtoul (str[1], &end, 0); - param = gnome_vfs_make_uri_canonical (aDest.get ()); - params = g_list_append (params, param); - gnome_vfs_mime_application_launch (helperApp, params); - g_free (param); + helperApp = gnome_vfs_mime_application_new_from_desktop_id (str[2]); + if (!helperApp) return NS_ERROR_FAILURE; - g_list_free (params); - } + nsEmbedCString aDest; + rv = mDestination->GetSpec (aDest); + NS_ENSURE_SUCCESS (rv, NS_ERROR_FAILURE); - gnome_vfs_mime_application_free (helperApp); + ephy_file_launch_application (helperApp, aDest.get (), user_time); + + gnome_vfs_mime_application_free (helperApp); + g_strfreev (str); + } } } diff --git a/lib/ephy-file-helpers.c b/lib/ephy-file-helpers.c index f1f62bae5..f66d61312 100644 --- a/lib/ephy-file-helpers.c +++ b/lib/ephy-file-helpers.c @@ -22,6 +22,12 @@ #include "config.h" +#include "ephy-file-helpers.h" + +#include "ephy-prefs.h" +#include "eel-gconf-extensions.h" +#include "ephy-debug.h" + #include #include #include @@ -29,12 +35,14 @@ #include #include #include +#include +#include +#include #include -#include "ephy-file-helpers.h" -#include "ephy-prefs.h" -#include "eel-gconf-extensions.h" -#include "ephy-debug.h" +/* bug http://bugzilla.gnome.org/show_bug.cgi?id=156687 */ +#undef GNOME_DISABLE_DEPRECATED +#include static GHashTable *files = NULL; static GHashTable *mime_table = NULL; @@ -449,3 +457,158 @@ ephy_file_check_mime (const char *mime_type) return permission; } + +static int +launch_desktop_item (const char *desktop_file, + const char *parameter, + guint32 user_time, + GError **error) +{ + GnomeDesktopItem *item = NULL; + GList *uris = NULL; + char *canonical; + int ret = -1; + + item = gnome_desktop_item_new_from_file (desktop_file, 0, NULL); + if (item == NULL) return FALSE; + + if (parameter != NULL) + { + canonical = gnome_vfs_make_uri_canonical (parameter); + uris = g_list_append (uris, canonical); + } + + gnome_desktop_item_set_launch_time (item, user_time); + ret = gnome_desktop_item_launch (item, uris, 0, error); + + g_list_foreach (uris, (GFunc) g_free, NULL); + g_list_free (uris); + gnome_desktop_item_unref (item); + + return ret; +} + +gboolean +ephy_file_launch_desktop_file (const char *filename, + guint32 user_time) +{ + GError *error = NULL; + const char * const *dirs; + char *path = NULL; + int i, ret = -1; + + dirs = g_get_system_data_dirs (); + if (dirs == NULL) return FALSE; + + for (i = 0; dirs[i] != NULL; i++) + { + g_print ("Looking in path: %s\n", dirs[i]); + + path = g_build_filename (dirs[i], "applications", filename, NULL); + + if (g_file_test (path, G_FILE_TEST_IS_REGULAR)) break; + + g_free (path); + } + + if (path != NULL) + { + ret = launch_desktop_item (path, NULL, user_time, &error); + + if (ret == -1 || error != NULL) + { + g_warning ("Cannot launch desktop item '%s': %s\n", + path, error ? error->message : "(unknown error)"); + g_clear_error (&error); + } + + g_free (path); + } + + return ret >= 0; +} + +gboolean +ephy_file_launch_application (GnomeVFSMimeApplication *application, + const char *parameter, + guint32 user_time) +{ + GError *error = NULL; + const char *desktop_file; + int ret = -1; + + g_return_val_if_fail (application != NULL, FALSE); + g_return_val_if_fail (parameter != NULL, FALSE); + + desktop_file = gnome_vfs_mime_application_get_desktop_file_path (application); + if (desktop_file != NULL) + { + ret = launch_desktop_item (desktop_file, parameter, user_time, &error); + } + + if (ret == -1 || error != NULL) + { + /* FIXME We should really warn the user here */ + + g_warning ("Cannot launch application '%s': %s\n", + gnome_vfs_mime_application_get_name (application), + error ? error->message : "(unknown error)"); + g_clear_error (&error); + } + + return ret >= 0; +} + +gboolean +ephy_file_launch_handler (const char *mime_type, + const char *address, + guint32 user_time) +{ + GnomeVFSMimeApplication *app = NULL; + GnomeVFSFileInfo *info = NULL; + char *canonical; + gboolean ret = FALSE; + + g_return_val_if_fail (address != NULL, FALSE); + + canonical = gnome_vfs_make_uri_canonical (address); + g_return_val_if_fail (canonical != NULL, FALSE); + + if (mime_type != NULL) + { + app = gnome_vfs_mime_get_default_application (mime_type); + } + else + { + /* Sniff mime type and check if it's safe to open */ + info = gnome_vfs_file_info_new (); + if (gnome_vfs_get_file_info (canonical, info, + GNOME_VFS_FILE_INFO_GET_MIME_TYPE | + GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE) == GNOME_VFS_OK && + (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE) && + info->mime_type != NULL && + info->mime_type[0] != '\0' && + ephy_file_check_mime (info->mime_type) == EPHY_MIME_PERMISSION_SAFE) + { + /* FIXME rename tmp file to right extension ? */ + app = gnome_vfs_mime_get_default_application (info->mime_type); + } + gnome_vfs_file_info_unref (info); + } + + if (app != NULL) + { + ret = ephy_file_launch_application (app, address, user_time); + + gnome_vfs_mime_application_free (app); + } + else + { + /* FIXME: warn user? */ + g_warning ("No handler for found or file type is unsafe!\n"); + } + + g_free (canonical); + + return ret; +} diff --git a/lib/ephy-file-helpers.h b/lib/ephy-file-helpers.h index 8b9a99c13..81fdd90f5 100644 --- a/lib/ephy-file-helpers.h +++ b/lib/ephy-file-helpers.h @@ -24,6 +24,7 @@ #define EPHY_FILE_HELPERS_H #include +#include G_BEGIN_DECLS @@ -44,7 +45,7 @@ void ephy_file_helpers_shutdown (void); char *ephy_file_downloads_dir (void); -char *ephy_file_desktop_dir (void); +char *ephy_file_desktop_dir (void); const char *ephy_file_tmp_dir (void); @@ -64,6 +65,17 @@ void ephy_file_delete_on_exit (const char *path); EphyMimePermission ephy_file_check_mime (const char *mime_type); +gboolean ephy_file_launch_desktop_file (const char *filename, + guint32 user_time); + +gboolean ephy_file_launch_application (GnomeVFSMimeApplication *application, + const char *parameter, + guint32 user_time); + +gboolean ephy_file_launch_handler (const char *mime_type, + const char *address, + guint32 user_time); + G_END_DECLS #endif /* EPHY_FILE_HELPERS_H */ diff --git a/lib/ephy-gui.c b/lib/ephy-gui.c index 6b8a18497..954f4c993 100644 --- a/lib/ephy-gui.c +++ b/lib/ephy-gui.c @@ -22,6 +22,7 @@ #include "ephy-gui.h" #include "eel-gconf-extensions.h" +#include "ephy-debug.h" #include #include @@ -37,6 +38,8 @@ #include #include +#include + void ephy_gui_sanitise_popup_position (GtkMenu *menu, GtkWidget *widget, @@ -190,16 +193,26 @@ ephy_gui_confirm_overwrite_file (GtkWidget *parent, const char *filename) { GtkWidget *dialog; - char *display_name; - gboolean retval; + char *display_name, *path; + gboolean retval, writable; if (filename == NULL) return FALSE; if (!g_file_test (filename, G_FILE_TEST_EXISTS)) { - return TRUE; + /* check if path is writable to */ + path = g_path_get_dirname (filename); + writable = access (path, W_OK) == 0; + g_free (path); + + /* FIXME put up some UI to inform the user */ + return writable; } + /* check if file is writable */ + /* FIXME put up some UI to inform the user */ + if (access (filename, W_OK) != 0) return FALSE; + display_name = g_filename_display_basename (filename); dialog = gtk_message_dialog_new @@ -349,6 +362,8 @@ void ephy_gui_window_update_user_time (GtkWidget *window, guint32 user_time) { + LOG ("updating user time on window %p to %d", window, user_time); + if (user_time != 0) { gtk_widget_realize (window); @@ -357,3 +372,32 @@ ephy_gui_window_update_user_time (GtkWidget *window, } } + +/* gtk+ bug 166379 */ +/* adapted from gtk+/gtk/gtkwindow.c */ +void +ephy_gui_window_present (GtkWindow *window, + guint32 user_time) +{ + GtkWidget *widget; + + g_return_if_fail (GTK_IS_WINDOW (window)); + + widget = GTK_WIDGET (window); + + if (GTK_WIDGET_VISIBLE (window)) + { + g_assert (widget->window != NULL); + + gdk_window_show (widget->window); + + /* note that gdk_window_focus() will also move the window to + * the current desktop, for WM spec compliant window managers. + */ + gdk_window_focus (widget->window, user_time); + } + else + { + gtk_widget_show (widget); + } +} diff --git a/lib/ephy-gui.h b/lib/ephy-gui.h index 7a9847281..226f262f9 100644 --- a/lib/ephy-gui.h +++ b/lib/ephy-gui.h @@ -71,6 +71,9 @@ void ephy_gui_help (GtkWindow *parent, void ephy_gui_window_update_user_time (GtkWidget *window, guint32 user_time); +void ephy_gui_window_present (GtkWindow *window, + guint32 user_time); + G_END_DECLS #endif diff --git a/src/ephy-session.c b/src/ephy-session.c index 4dbdb4f18..68e448504 100644 --- a/src/ephy-session.c +++ b/src/ephy-session.c @@ -444,7 +444,7 @@ ephy_session_autoresume (EphySession *session, { ephy_gui_window_update_user_time (session->priv->resume_dialog, user_time); - gtk_window_present (GTK_WINDOW (priv->resume_dialog)); + ephy_gui_window_present (GTK_WINDOW (priv->resume_dialog), user_time); return TRUE; } @@ -455,7 +455,7 @@ ephy_session_autoresume (EphySession *session, { session->priv->dont_save = TRUE; retval = ephy_session_load (session, saved_session, - user_time); + 0 /* since we've shown the dialogue */); session->priv->dont_save = FALSE; ephy_session_save (session, SESSION_CRASHED); } diff --git a/src/popup-commands.c b/src/popup-commands.c index 4fa7457e0..16cdd8129 100644 --- a/src/popup-commands.c +++ b/src/popup-commands.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -266,11 +267,13 @@ popup_cmd_save_image_as (GtkAction *action, #define GNOME_BACKGROUND_PREFERENCES "gnome-background-properties" static void -background_download_completed (EphyEmbedPersist *persist, - gpointer data) +background_download_completed (EphyEmbedPersist *persist) { const char *bg; - char *type, *path; + char *type; + guint32 user_time; + + user_time = ephy_embed_persist_get_user_time (persist); bg = ephy_embed_persist_get_dest (persist); eel_gconf_set_string (CONF_DESKTOP_BG_PICTURE, bg); @@ -285,12 +288,7 @@ background_download_completed (EphyEmbedPersist *persist, g_object_unref (persist); /* open the "Background Properties" capplet */ - path = g_find_program_in_path (GNOME_BACKGROUND_PREFERENCES); - if (path != NULL) - { - g_spawn_command_line_async (path, NULL); - g_free (path); - } + ephy_file_launch_desktop_file ("background.desktop", user_time); } void @@ -375,63 +373,34 @@ popup_cmd_open_frame (GtkAction *action, static void image_open_uri (const char *address, - gboolean delete) + gboolean delete, + guint32 user_time) { - GList *uris = NULL; - char *canonical; - GnomeVFSMimeApplication *app = NULL; - GnomeVFSFileInfo *info; - - canonical = gnome_vfs_make_uri_canonical (address); - - info = gnome_vfs_file_info_new (); - if (gnome_vfs_get_file_info (canonical, info, - GNOME_VFS_FILE_INFO_GET_MIME_TYPE | - GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE) == GNOME_VFS_OK && - (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE) && - info->mime_type != NULL && - info->mime_type[0] != '\0' && - ephy_file_check_mime (info->mime_type) == EPHY_MIME_PERMISSION_SAFE) - { - app = gnome_vfs_mime_get_default_application (info->mime_type); - } + gboolean success; - if (app != NULL) + success = ephy_file_launch_handler (NULL, address, user_time); + + if (delete && success) { - /* FIXME rename tmp file to right extension ? */ - uris = g_list_append (uris, canonical); - gnome_vfs_mime_application_launch (app, uris); - gnome_vfs_mime_application_free (app); - g_list_free (uris); - if (delete) - { - ephy_file_delete_on_exit (address); - } + ephy_file_delete_on_exit (address); } - else + else if (delete) { - /* FIXME We should really warn the user here */ - - g_warning ("Cannot find an application to open %s with.", address); - if (delete) - { - gnome_vfs_unlink (address); - } + gnome_vfs_unlink (address); } - - g_free (canonical); - gnome_vfs_file_info_unref (info); } static void save_source_completed_cb (EphyEmbedPersist *persist) { const char *dest; + guint32 user_time; + user_time = ephy_embed_persist_get_user_time (persist); dest = ephy_embed_persist_get_dest (persist); g_return_if_fail (dest != NULL); - image_open_uri (dest, TRUE); + image_open_uri (dest, TRUE, user_time); } static void @@ -492,7 +461,8 @@ popup_cmd_open_image (GtkAction *action, if (strcmp (scheme, "file") == 0) { - image_open_uri (address, FALSE); + image_open_uri (address, FALSE, + gtk_get_current_event_time ()); } else { diff --git a/src/window-commands.c b/src/window-commands.c index 48479061e..43dc10630 100644 --- a/src/window-commands.c +++ b/src/window-commands.c @@ -57,6 +57,8 @@ #include #include #include +#include +#include void window_cmd_edit_find (GtkAction *action, @@ -394,6 +396,7 @@ window_cmd_file_save_as (GtkAction *action, ephy_embed_persist_set_embed (persist, embed); ephy_embed_persist_set_fc_title (persist, _("Save As")); ephy_embed_persist_set_fc_parent (persist,GTK_WINDOW (window)); + ephy_embed_persist_set_flags (persist, EPHY_EMBED_PERSIST_MAINDOC | EPHY_EMBED_PERSIST_ASK_DESTINATION); ephy_embed_persist_set_persist_key @@ -404,7 +407,6 @@ window_cmd_file_save_as (GtkAction *action, g_object_unref (G_OBJECT(persist)); } - void window_cmd_file_work_offline (GtkAction *action, EphyWindow *window) @@ -618,49 +620,24 @@ window_cmd_view_zoom_normal (GtkAction *action, ephy_window_set_zoom (window, 1.0); } -static void -editor_open_uri (const char *address) -{ - GList *uris = NULL; - char *canonical; - GnomeVFSMimeApplication *app; - - canonical = gnome_vfs_make_uri_canonical (address); - - uris = g_list_append (uris, canonical); - - app = gnome_vfs_mime_get_default_application ("text/plain"); - if (app) - { - gnome_vfs_mime_application_launch (app, uris); - gnome_vfs_mime_application_free (app); - } - else - { - /* FIXME We should really warn the user here */ - - g_warning ("Cannot find a text editor."); - } - - g_free (canonical); - g_list_free (uris); -} - static void save_source_completed_cb (EphyEmbedPersist *persist) { const char *dest; + guint32 user_time; + user_time = ephy_embed_persist_get_user_time (persist); dest = ephy_embed_persist_get_dest (persist); g_return_if_fail (dest != NULL); ephy_file_delete_on_exit (dest); - editor_open_uri (dest); + ephy_file_launch_handler ("text/plain", dest, user_time); } static void -save_temp_source (EphyEmbed *embed) +save_temp_source (EphyEmbed *embed, + guint32 user_time) { char *tmp, *base; EphyEmbedPersist *persist; @@ -687,6 +664,7 @@ save_temp_source (EphyEmbed *embed) ephy_embed_persist_set_flags (persist, EPHY_EMBED_PERSIST_COPY_PAGE | EPHY_EMBED_PERSIST_NO_VIEW); ephy_embed_persist_set_dest (persist, tmp); + ephy_embed_persist_set_user_time (persist, user_time); g_signal_connect (persist, "completed", G_CALLBACK (save_source_completed_cb), NULL); @@ -704,20 +682,22 @@ window_cmd_view_page_source (GtkAction *action, EphyEmbed *embed; char *address; char *scheme; + guint32 user_time; embed = ephy_window_get_active_embed (window); g_return_if_fail (embed != NULL); address = ephy_embed_get_location (embed, TRUE); scheme = gnome_vfs_get_uri_scheme (address); + user_time = gtk_get_current_event_time (); if (strcmp (scheme, "file") == 0) { - editor_open_uri (address); + ephy_file_launch_handler ("text/plain", address, user_time); } else { - save_temp_source (embed); + save_temp_source (embed, user_time); } g_free (scheme); -- cgit v1.2.3