diff options
33 files changed, 1941 insertions, 2811 deletions
@@ -189,6 +189,308 @@ Merge fixes from branch and clean up. +2003-10-16 Marco Pesenti Gritti <marco@gnome.org> + + * embed/mozilla/ContentHandler.cpp: + + pass handler with full path, not only + exec name. I dont get how it worked before. + +2003-10-16 Marco Pesenti Gritti <marco@gnome.org> + + * lib/widgets/ephy-cell-renderer-progress.c: + (ephy_cell_renderer_progress_init), + (ephy_cell_renderer_progress_set_value), + (ephy_cell_renderer_progress_set_property), (compute_dimensions), + (ephy_cell_renderer_progress_get_size), + (ephy_cell_renderer_progress_render), + (ephy_cell_renderer_progress_finalize), + (ephy_cell_renderer_progress_class_init): + * lib/widgets/ephy-cell-renderer-progress.h: + + fix for unknown/failed states + +2003-10-16 Xan Lopez <xan@masilla.org> + + * embed/mozilla/MozDownload.cpp: + * embed/mozilla/MozDownload.h: + + Unbreak for real. + +2003-10-16 Xan Lopez <xan@masilla.org> + + * TODO: + * embed/downloader-view.c: + * embed/mozilla/MozDownload.cpp: + + Evil marco loves to break my changes, ahem. + +2003-10-16 Marco Pesenti Gritti <marco@gnome.org> + + * TODO: + * embed/downloader-view.c: (downloader_view_init), + (get_row_from_download), (download_changed_cb), + (downloader_view_add_download), (downloader_view_build_ui), + (download_dialog_pause_cb), (downloader_view_remove_download), + (download_dialog_abort_cb): + * embed/ephy-download.c: (ephy_download_get_state): + * embed/ephy-download.h: + * embed/mozilla/MozDownload.cpp: + * embed/mozilla/MozDownload.h: + * embed/mozilla/mozilla-download.cpp: + + Implement state. + +2003-10-16 Marco Pesenti Gritti <marco@gnome.org> + + * data/glade/epiphany.glade: + + Remove details + + * embed/downloader-view.c: + + Remove details button leftover + +2003-10-16 Marco Pesenti Gritti <marco@gnome.org> + + * embed/mozilla/MozDownload.cpp: + + Fix some bugs + +2003-10-16 Marco Pesenti Gritti <marco@gnome.org> + + * embed/ephy-embed-persist.h: + * embed/ephy-favicon-cache.c: (ephy_favicon_cache_download): + * embed/mozilla/EphyHeaderSniffer.cpp: + * embed/mozilla/MozDownload.cpp: + * embed/mozilla/MozDownload.h: + + Implement no_view downloads and use for favicons. + +2003-10-15 Marco Pesenti Gritti <marco@gnome.org> + + * embed/mozilla/MozDownload.cpp: + + Fix reference problem when using persist. + +2003-10-15 Xan Lopez <xan@masilla.org> + + * data/glade/epiphany.glade: + * embed/downloader-view.c: (downloader_view_init), + (downloader_view_finalize), (download_changed_cb), + (downloader_view_add_download), (downloader_view_build_ui), + (download_dialog_pause_cb), (downloader_view_remove_download), + (download_dialog_abort_cb), (download_dialog_delete_cb): + + Re-add abort UI, drop details + Serious glade cleanup is left as an exercise for the reader + +2003-10-15 Xan Lopez <xan@masilla.org> + + * data/glade/epiphany.glade: + * embed/downloader-view.c: (downloader_view_add_download), + (download_dialog_pause_cb), (download_dialog_abort_cb): + * embed/downloader-view.h: + + Fix stop button (UI not updated yet) + + * embed/mozilla/MozDownload.cpp: + + Init mEmbedPersist to nsnull (Marco) + +2003-10-14 Marco Pesenti Gritti <marco@gnome.org> + + * embed/downloader-view.c: (format_interval), + (download_changed_cb), (downloader_view_build_ui): + * embed/ephy-download.c: (ephy_download_get_remaining_time), + (ephy_download_get_current_progress), + (ephy_download_get_total_progress), (ephy_download_get_percent), + (ephy_download_get_elapsed_time): + * embed/ephy-download.h: + * embed/mozilla/MozDownload.cpp: + * embed/mozilla/MozDownload.h: + * embed/mozilla/mozilla-download.cpp: + * lib/widgets/Makefile.am: + + Get back the treeview info to work. Use + procman progress renderer for percent. + +2003-10-14 Marco Pesenti Gritti <marco@gnome.org> + + * embed/downloader-view.c: (download_changed_cb), + (downloader_view_add_download): + + Fix percent/filenamee + +2003-10-14 Marco Pesenti Gritti <marco@gnome.org> + + * embed/downloader-view.c: (download_changed_cb), + (downloader_view_add_download), (downloader_view_build_ui), + (downloader_treeview_selection_changed_cb): + * embed/ephy-download.c: (ephy_download_class_init), + (ephy_download_new), (ephy_download_get_name): + * embed/ephy-download.h: + * embed/mozilla/MozDownload.cpp: + * embed/mozilla/MozDownload.h: + + Implement a download changed signal and try to update + percent in the treeview. + +2003-10-14 Marco Pesenti Gritti <marco@gnome.org> + + * embed/ephy-download.c: (ephy_download_get_source), + (ephy_download_get_target), (ephy_download_get_percent): + * embed/ephy-download.h: + * embed/mozilla/mozilla-download.cpp: + + Implement basic download info getters. + +2003-10-14 Marco Pesenti Gritti <marco@gnome.org> + + * embed/Makefile.am: + * embed/downloader-view.c: (destroy_details_cb), + (downloader_view_update_controls), + (downloader_view_update_details), + (downloader_view_set_download_info), + (downloader_view_add_download), (downloader_view_build_ui), + (download_dialog_pause_cb), (download_dialog_abort_cb), + (downloader_treeview_selection_changed_cb), + (download_dialog_delete_cb), (open_selection_foreach), + (download_dialog_open_cb): + * embed/downloader-view.h: + * embed/ephy-download.c: (ephy_download_get_type), + (ephy_download_class_init), (ephy_download_init), + (ephy_download_new), (ephy_download_cancel), (ephy_download_pause), + (ephy_download_resume): + * embed/ephy-download.h: + * embed/ephy-embed-shell.c: (impl_get_downloader_view): + * embed/mozilla/EphyDownload.cpp: + * embed/mozilla/EphyDownload.h: + * embed/mozilla/EphyHeaderSniffer.cpp: + * embed/mozilla/Makefile.am: + * embed/mozilla/MozDownload.cpp: + * embed/mozilla/MozDownload.h: + * embed/mozilla/MozRegisterComponents.cpp: + * embed/mozilla/mozilla-download.cpp: + * embed/mozilla/mozilla-download.h: + * embed/mozilla/mozilla-embed-persist.cpp: + * lib/Makefile.am: + * lib/widgets/Makefile.am: + * src/Makefile.am: + * src/bookmarks/Makefile.am: + + Big architectural changes. Now I think it make sense, + but we need to rewrite a lot of ui code. + +2003-10-14 Xan Lopez <xan@masilla.org> + + * embed/downloader-view.c: (downloader_view_class_init), + (download_dialog_pause_cb), (delete_pending_foreach): + * embed/mozilla/mozilla-downloader-view.cpp: + * embed/mozilla/mozilla-downloader-view.h: + + Some cleanups. + +2003-10-14 Xan Lopez <xan@masilla.org> + + * embed/downloader-view.c: (download_dialog_abort_cb), + (downloader_cancel_download): + * embed/mozilla/mozilla-downloader-view.cpp: + + Evil stuff. + +2003-10-14 Xan Lopez <xan@masilla.org> + + * embed/ephy-embed-shell.c: (impl_get_downloader_view): + * embed/mozilla/mozilla-downloader-view.cpp: + * embed/mozilla/mozilla-downloader-view.h: + + And More. + +2003-10-13 Xan Lopez <xan@masilla.org> + + * embed/mozilla/EphyDownload.h: + + Cleanup + + * embed/mozilla/Makefile.am: + * embed/mozilla/mozilla-downloader-view.cpp: + * embed/mozilla/mozilla-downloader-view.h: + + Yet More Work. + +2003-10-13 Xan Lopez <xan@masilla.org> + + * embed/downloader-view.c: (downloader_view_class_init), + (download_dialog_pause_cb), (download_dialog_abort_cb), + (delete_pending_foreach), (downloader_cancel_download), + (downloader_pause_download), (downloader_resume_download): + * embed/downloader-view.h: + + More work. + +2003-10-07 Marco Pesenti Gritti <marco@gnome.org> + + * embed/mozilla/EphyHeaderSniffer.cpp: + + Fix crash when download start + +2003-10-07 Marco Pesenti Gritti <marco@gnome.org> + + * embed/ephy-embed-persist.h: + * embed/ephy-embed-popup-control.c: (save_property_url), + (embed_popup_download_link_cmd), (embed_popup_save_image_as_cmd), + (save_url), (embed_popup_save_page_as_cmd), + (embed_popup_save_background_as_cmd): + * embed/ephy-embed-utils.c: (ephy_embed_utils_save): + * embed/ephy-embed-utils.h: + * embed/mozilla/EphyDownload.cpp: + * embed/mozilla/EphyDownload.h: + * embed/mozilla/EphyHeaderSniffer.cpp: + * embed/mozilla/EphyHeaderSniffer.h: + * embed/mozilla/mozilla-embed-persist.cpp: + * src/popup-commands.c: (save_property_url), + (popup_cmd_download_link), (popup_cmd_save_image_as), + (popup_cmd_save_background_as): + * src/window-commands.c: (window_cmd_file_save_as): + + Make embed-persist use nsIDownload and cleanup api a bit. + +2003-10-06 Xan Lopez <xan@masilla.org> + + * embed/mozilla/ContentHandler.cpp: + * embed/mozilla/EphyWrapper.cpp: + * embed/mozilla/EphyWrapper.h: + * embed/mozilla/EventContext.cpp: + * embed/mozilla/GlobalHistory.h: + * embed/mozilla/ProgressListener.cpp: + * embed/mozilla/ProgressListener.h: + * embed/mozilla/mozilla-embed-persist.cpp: + + Remove ProgressListener again, hopefully everything + compiles without it now. + +2003-10-06 Xan Lopez <xan@masilla.org> + + * embed/mozilla/EphyDownload.cpp: + * embed/mozilla/EphyDownload.h: + * embed/mozilla/EphyHeaderSniffer.cpp: + * embed/mozilla/EphyHeaderSniffer.h: + * embed/mozilla/MozRegisterComponents.cpp: + * embed/mozilla/ProgressListener.cpp: + * embed/mozilla/ProgressListener.h: + * embed/mozilla/mozilla-embed-persist.cpp: + + Cleanups. + +2003-10-06 Xan Lopez <xan@masilla.org> + + * embed/mozilla/Makefile.am: + * embed/mozilla/MozRegisterComponents.cpp: + * embed/mozilla/mozilla-embed-persist.cpp: + + Make it work, behold the all new EphyDownload. + 2003-10-06 Christian Persch <chpe@cvs.gnome.org> * src/ephy-notebook.c: (find_notebook_at_pointer), @@ -1,3 +1,21 @@ - Check that filtering is not done more than one time on bookmarks dialogs init - change font size pref name or convert if possible + +Downloader: + +- Update rate (used for estimated time) only after some time, otherwise estimated +keep to chang in an annoying way +- Fixup column sizing. Ideally filename should get all available space, the +others column can get the minimum (for progress we can just fixup requisition +in the renderer to something sane) +- Fix hash table destruction. Free row refs and unref download objects. +- Cleanup downloader-view, there is prolly still crap here and there +- Add LOGs on all objects involved in download. Init/Finalize and in c++ +constructor/destructor. Verify that references are correct == objects +are destroyed at right time. +- Probably use cur from total instead of just total in the size field +- Deal with the case where total size is unknown (we need special rendering +for progress too I guess) +- Initialize progress values when starting the download +- Need a way to do downloads without view, for favicons - expand filename col in downloader diff --git a/data/glade/epiphany.glade b/data/glade/epiphany.glade index 0b05ee4c5..23e014551 100644 --- a/data/glade/epiphany.glade +++ b/data/glade/epiphany.glade @@ -400,310 +400,6 @@ <property name="fill">True</property> </packing> </child> - - <child> - <widget class="GtkAlignment" id="alignment8"> - <property name="visible">True</property> - <property name="xalign">1</property> - <property name="yalign">0.5</property> - <property name="xscale">0</property> - <property name="yscale">0</property> - - <child> - <widget class="GtkToggleButton" id="details_togglebutton"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="active">False</property> - <property name="inconsistent">False</property> - <signal name="toggled" handler="download_dialog_details_cb" last_modification_time="Sat, 01 Jun 2002 23:52:31 GMT"/> - - <child> - <widget class="GtkAlignment" id="alignment5"> - <property name="visible">True</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xscale">0</property> - <property name="yscale">0</property> - - <child> - <widget class="GtkHBox" id="hbox83"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">2</property> - - <child> - <widget class="GtkImage" id="image3"> - <property name="visible">True</property> - <property name="stock">gtk-dialog-info</property> - <property name="icon_size">4</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="label1220"> - <property name="visible">True</property> - <property name="label" translatable="yes">Download _Details</property> - <property name="use_underline">True</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - </widget> - </child> - </widget> - </child> - </widget> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkVBox" id="details_frame"> - <property name="homogeneous">False</property> - <property name="spacing">0</property> - - <child> - <widget class="GtkTable" id="details_table"> - <property name="visible">True</property> - <property name="n_rows">6</property> - <property name="n_columns">2</property> - <property name="homogeneous">False</property> - <property name="row_spacing">6</property> - <property name="column_spacing">12</property> - - <child> - <widget class="GtkHSeparator" id="details_separator"> - <property name="visible">True</property> - </widget> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">2</property> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="x_options">fill</property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="label1142"> - <property name="visible">True</property> - <property name="label" translatable="yes"><b>Address:</b></property> - <property name="use_underline">False</property> - <property name="use_markup">True</property> - <property name="justify">GTK_JUSTIFY_RIGHT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">fill</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="label1211"> - <property name="visible">True</property> - <property name="label" translatable="yes"><b>Status:</b></property> - <property name="use_underline">False</property> - <property name="use_markup">True</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="x_options">fill</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="label1212"> - <property name="visible">True</property> - <property name="label" translatable="yes"><b>Time Elapsed:</b></property> - <property name="use_underline">False</property> - <property name="use_markup">True</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">3</property> - <property name="bottom_attach">4</property> - <property name="x_options">fill</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="label1213"> - <property name="visible">True</property> - <property name="label" translatable="yes"><b>Time Remaining:</b></property> - <property name="use_underline">False</property> - <property name="use_markup">True</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">4</property> - <property name="bottom_attach">5</property> - <property name="x_options">fill</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="details_status"> - <property name="visible">True</property> - <property name="label" translatable="yes"></property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="details_elapsed"> - <property name="visible">True</property> - <property name="label" translatable="yes"></property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">3</property> - <property name="bottom_attach">4</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="details_remaining"> - <property name="visible">True</property> - <property name="label" translatable="yes"></property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">4</property> - <property name="bottom_attach">5</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkProgressBar" id="details_progress"> - <property name="visible">True</property> - <property name="orientation">GTK_PROGRESS_LEFT_TO_RIGHT</property> - <property name="fraction">0</property> - <property name="pulse_step">0.1</property> - </widget> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">2</property> - <property name="top_attach">5</property> - <property name="bottom_attach">6</property> - <property name="y_options"></property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">True</property> - </packing> - </child> </widget> <packing> <property name="padding">0</property> diff --git a/embed/downloader-view.c b/embed/downloader-view.c index cd0ebe607..eee883bb3 100644 --- a/embed/downloader-view.c +++ b/embed/downloader-view.c @@ -29,6 +29,7 @@ #include "ephy-embed-utils.h" #include "ephy-file-helpers.h" #include "ephy-embed-shell.h" +#include "ephy-cell-renderer-progress.h" #include "ephy-stock-icons.h" #include <gtk/gtktreeview.h> @@ -44,38 +45,23 @@ enum { - DOWNLOAD_REMOVE, - DOWNLOAD_PAUSE, - DOWNLOAD_RESUME, - LAST_SIGNAL -}; - -enum -{ COL_PERCENT, COL_FILENAME, COL_SIZE, COL_REMAINING, - COL_PERSIST_OBJECT + COL_DOWNLOAD_OBJECT }; #define EPHY_DOWNLOADER_VIEW_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_DOWNLOADER_VIEW, DownloaderViewPrivate)) struct DownloaderViewPrivate { - GHashTable *details_hash; GtkTreeModel *model; - gboolean show_details; + GHashTable *details_hash; /* Widgets */ GtkWidget *window; GtkWidget *treeview; - GtkWidget *details_location; - GtkWidget *details_status; - GtkWidget *details_elapsed; - GtkWidget *details_remaining; - GtkWidget *details_progress; - GtkWidget *details_button; GtkWidget *open_button; GtkWidget *pause_button; @@ -84,27 +70,9 @@ struct DownloaderViewPrivate typedef struct { - glong elapsed; - glong remaining; - gfloat speed; - gint size_total; - gint size_done; - gfloat progress; - gchar *filename; - gchar *source; - gchar *dest; - DownloadStatus status; - gboolean download_started; - - GtkTreeRowReference *ref; -} DownloadDetails; - -typedef struct -{ gboolean is_paused; gboolean can_abort; gboolean can_open; - gboolean can_pause; DownloaderViewPrivate *priv; } ControlsInfo; @@ -112,12 +80,6 @@ enum { PROP_WINDOW, PROP_TREEVIEW, - PROP_DETAILS_FRAME, - PROP_DETAILS_TABLE, - PROP_DETAILS_STATUS, - PROP_DETAILS_ELAPSED, - PROP_DETAILS_REMAINING, - PROP_DETAILS_PROGRESS, PROP_OPEN_BUTTON, PROP_PAUSE_BUTTON, PROP_ABORT_BUTTON, @@ -129,16 +91,9 @@ EphyDialogProperty properties [] = { { PROP_WINDOW, "download_manager_dialog", NULL, PT_NORMAL, NULL}, { PROP_TREEVIEW, "clist", NULL, PT_NORMAL, NULL }, - { PROP_DETAILS_FRAME, "details_frame", NULL, PT_NORMAL, NULL }, - { PROP_DETAILS_TABLE, "details_table", NULL, PT_NORMAL, NULL }, - { PROP_DETAILS_STATUS, "details_status", NULL, PT_NORMAL, NULL }, - { PROP_DETAILS_ELAPSED, "details_elapsed", NULL, PT_NORMAL, NULL }, - { PROP_DETAILS_REMAINING, "details_remaining", NULL, PT_NORMAL, NULL }, - { PROP_DETAILS_PROGRESS, "details_progress", NULL, PT_NORMAL, NULL }, { PROP_OPEN_BUTTON, "open_button", NULL, PT_NORMAL, NULL }, { PROP_PAUSE_BUTTON, "pause_button", NULL, PT_NORMAL, NULL }, { PROP_ABORT_BUTTON, "abort_button", NULL, PT_NORMAL, NULL }, - { PROP_DETAILS_BUTTON, "details_togglebutton", CONF_DOWNLOADING_SHOW_DETAILS, PT_NORMAL, NULL }, { -1, NULL, NULL } }; @@ -157,21 +112,14 @@ void download_dialog_pause_cb (GtkButton *button, DownloaderView *dv); void download_dialog_abort_cb (GtkButton *button, DownloaderView *dv); -static void -downloader_treeview_selection_changed_cb (GtkTreeSelection *selection, - DownloaderView *dv); gboolean download_dialog_delete_cb (GtkWidget *window, GdkEventAny *event, DownloaderView *dv); void -download_dialog_details_cb (GtkToggleButton *button, - DownloaderView *dv); -void download_dialog_open_cb (GtkWidget *button, DownloaderView *dv); static GObjectClass *parent_class = NULL; -static guint downloader_view_signals[LAST_SIGNAL] = { 0 }; GType downloader_view_get_type (void) @@ -202,29 +150,6 @@ downloader_view_get_type (void) } static void -format_time (gchar *buffer, glong time) -{ - gint secs, hours, mins; - - secs = (gint)(time + .5); - hours = secs / 3600; - secs -= hours * 3600; - mins = secs / 60; - secs -= mins * 60; - - if (hours) - { - /* Hours, Minutes, Seconds */ - sprintf (buffer, _("%u:%02u.%02u"), hours, mins, secs); - } - else - { - /* Minutes, Seconds */ - sprintf (buffer, _("%02u.%02u"), mins, secs); - } -} - -static void downloader_view_class_init (DownloaderViewClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); @@ -233,56 +158,18 @@ downloader_view_class_init (DownloaderViewClass *klass) object_class->finalize = downloader_view_finalize; - /* init signals */ - downloader_view_signals[DOWNLOAD_REMOVE] = - g_signal_new ("download_remove", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (DownloaderViewClass, download_remove), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); - downloader_view_signals[DOWNLOAD_PAUSE] = - g_signal_new ("download_pause", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (DownloaderViewClass, download_pause), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); - downloader_view_signals[DOWNLOAD_RESUME] = - g_signal_new ("download_resume", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (DownloaderViewClass, download_resume), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); - g_type_class_add_private (object_class, sizeof(DownloaderViewPrivate)); } static void -destroy_details_cb (DownloadDetails *details) -{ - g_free (details->filename); - g_free (details->source); - g_free (details->dest); - g_free (details); -} - -static void downloader_view_init (DownloaderView *dv) { dv->priv = EPHY_DOWNLOADER_VIEW_GET_PRIVATE (dv); - dv->priv->details_hash = g_hash_table_new_full (g_direct_hash, - g_direct_equal, - NULL, - (GDestroyNotify)destroy_details_cb); + dv->priv->details_hash = g_hash_table_new_full + (g_direct_hash, g_direct_equal, NULL, + (GDestroyNotify)gtk_tree_row_reference_free); + downloader_view_build_ui (dv); g_object_ref (embed_shell); @@ -291,12 +178,9 @@ downloader_view_init (DownloaderView *dv) static void downloader_view_finalize (GObject *object) { - DownloaderView *dv = EPHY_DOWNLOADER_VIEW (object); - + DownloaderView *dv = EPHY_DOWNLOADER_VIEW (object); g_hash_table_destroy (dv->priv->details_hash); - g_object_unref (embed_shell); - G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -307,416 +191,132 @@ downloader_view_new (void) (EPHY_TYPE_DOWNLOADER_VIEW, NULL)); } -static void -controls_info_foreach (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, - ControlsInfo *info) +static char * +format_interval (long interval) { - DownloadDetails *details; - GValue val = {0, }; - gpointer persist_object; - - gtk_tree_model_get_value (model, iter, COL_PERSIST_OBJECT, &val); - persist_object = g_value_get_pointer (&val); - g_value_unset (&val); - - details = g_hash_table_lookup (info->priv->details_hash, - persist_object); - - info->is_paused |= (details->status == DOWNLOAD_STATUS_PAUSED); - info->can_abort |= (details->status != DOWNLOAD_STATUS_COMPLETED); - info->can_open |= (details->status == DOWNLOAD_STATUS_COMPLETED); - info->can_pause |= ((details->status != DOWNLOAD_STATUS_COMPLETED) && - (details->download_started == TRUE)); -} - -static void -downloader_view_update_controls (DownloaderViewPrivate *priv) -{ - GtkTreeSelection *selection; - ControlsInfo *info; - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(priv->treeview)); - - info = g_new0 (ControlsInfo, 1); - info->priv = priv; - - /* initial conditions */ - info->is_paused = info->can_abort = info->can_open = info->can_pause = FALSE; - - if (selection) - { - gtk_tree_selection_selected_foreach - (selection, - (GtkTreeSelectionForeachFunc)controls_info_foreach, - info); - } - - /* setup buttons */ - gtk_widget_set_sensitive (priv->open_button, info->can_open); - gtk_widget_set_sensitive (priv->pause_button, info->can_pause); - gtk_widget_set_sensitive (priv->abort_button, info->can_abort); - - if (info->is_paused) - { - gtk_button_set_label (GTK_BUTTON (priv->pause_button), _("_Resume")); - } - else - { - gtk_button_set_label (GTK_BUTTON (priv->pause_button), _("_Pause")); - } - - g_free (info); -} - -static void -downloader_view_update_details (DownloaderViewPrivate *priv, - DownloadDetails *details) -{ - gchar buffer[50]; - - ephy_ellipsizing_label_set_text - (EPHY_ELLIPSIZING_LABEL (priv->details_location), - details->source); - - if (details->size_total >= 10000) - { - sprintf (buffer, _("%.1f of %.1f MB"), - details->size_done / 1024.0, - details->size_total / 1024.0); - } - else if (details->size_total > 0) - { - sprintf (buffer, _("%d of %d kB"), - details->size_done, - details->size_total); - } - else - { - sprintf (buffer, _("%d kB"), - details->size_done); - } - - if (details->speed > 0) - { - sprintf (buffer, _("%s at %.1f kB/s"), buffer, details->speed); - } - gtk_label_set_text (GTK_LABEL (priv->details_status), - buffer); - - format_time (buffer, details->elapsed); - gtk_label_set_text (GTK_LABEL (priv->details_elapsed), - buffer); - - format_time (buffer, details->remaining); - gtk_label_set_text (GTK_LABEL (priv->details_remaining), - buffer); + int secs, hours, mins; + secs = (int)(interval + .5); + hours = secs / 3600; + secs -= hours * 3600; + mins = secs / 60; + secs -= mins * 60; - if (details->progress >= 0) - { - gtk_progress_bar_set_fraction - (GTK_PROGRESS_BAR (priv->details_progress), - details->progress); - } - else - { - gtk_progress_bar_pulse - (GTK_PROGRESS_BAR (priv->details_progress)); + if (hours) + { + return g_strdup_printf (_("%u:%02u.%02u"), hours, mins, secs); + } + else + { + return g_strdup_printf (_("%02u.%02u"), mins, secs); } } -static gboolean -get_selected_row (DownloaderViewPrivate *priv, GtkTreeIter *iter) +static GtkTreeRowReference * +get_row_from_download (DownloaderView *dv, EphyDownload *download) { - GList *l; - GtkTreePath *node; - GtkTreeSelection *selection; - GtkTreeModel *model; - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(priv->treeview)); - l = gtk_tree_selection_get_selected_rows (selection, &model); - - if (l == NULL) return FALSE; - - node = l->data; - gtk_tree_model_get_iter (model, iter, node); - - g_list_foreach (l, (GFunc)gtk_tree_path_free, NULL); - g_list_free (l); - - return TRUE; + return g_hash_table_lookup (dv->priv->details_hash, download); } static void -downloader_view_set_download_info (DownloaderViewPrivate *priv, - DownloadDetails *details, - GtkTreeIter *iter) +download_changed_cb (EphyDownload *download, DownloaderView *dv) { - gchar buffer[50]; - GtkTreePath *path = NULL; - GtkTreePath *selected_path = NULL; - GtkTreeIter selected_iter; - GtkTreeSelection *selection; - - selection = gtk_tree_view_get_selection - (GTK_TREE_VIEW(priv->treeview)); - - if (get_selected_row (priv, &selected_iter)) - { - selected_path = gtk_tree_model_get_path - (priv->model, &selected_iter); - } - - path = gtk_tree_row_reference_get_path (details->ref); - - gtk_list_store_set (GTK_LIST_STORE (priv->model), - iter, - COL_FILENAME, details->filename, - -1); - - /* Pause Activation */ - - if (details->download_started == FALSE && - details->status != DOWNLOAD_STATUS_COMPLETED && - details->size_total != -1) - { - details->download_started = TRUE; - downloader_view_update_controls (priv); - } - - /* Progress */ - if (details->status == DOWNLOAD_STATUS_COMPLETED) - { - details->progress = 1; - if (details->size_total > 0) - { - details->size_done = details->size_total; - } - } - - sprintf (buffer, "%.1f%%", - details->progress > 0 ? - details->progress * 100.0 : - 0); - gtk_list_store_set (GTK_LIST_STORE (priv->model), - iter, - COL_PERCENT, buffer, - -1); - - /* Total */ - if (details->size_total >= 10000) - { - sprintf (buffer, "%.2f MB", details->size_total / 1024.0); - } - else if (details->size_total > 0) - { - sprintf (buffer, "%d kB", details->size_total); - } - else - { - sprintf (buffer, _("Unknown")); - } - - gtk_list_store_set (GTK_LIST_STORE (priv->model), - iter, - COL_SIZE, buffer, - -1); - - /* Remaining */ - if (details->remaining >= 0) - { - format_time (buffer, details->remaining); - } - else - { - sprintf (buffer, - details->progress > 0 ? - _("00.00") : - _("Unknown")); - } - - gtk_list_store_set (GTK_LIST_STORE (priv->model), - iter, - COL_REMAINING, buffer, + GtkTreeRowReference *row_ref; + GtkTreePath *path; + GtkTreeIter iter; + EphyDownloadState state; + int percent; + long total; + long remaining_secs; + char *remaining; + char *size; + struct tm; + + row_ref = get_row_from_download (dv, download); + g_return_if_fail (row_ref != NULL); + + total = ephy_download_get_total_progress (download) / 1024; + + /* State special casing */ + state = ephy_download_get_state (download); + switch (state) + { + case EPHY_DOWNLOAD_FAILED: + percent = -2; + remaining_secs = 0; + break; + case EPHY_DOWNLOAD_COMPLETED: + percent = 100; + remaining_secs = 0; + break; + case EPHY_DOWNLOAD_DOWNLOADING: + case EPHY_DOWNLOAD_PAUSED: + percent = ephy_download_get_percent (download); + remaining_secs = ephy_download_get_remaining_time (download); + break; + default: + percent = 0; + remaining_secs = 0; + break; + } + + size = g_strdup_printf ("%ld kB", total); + remaining = format_interval (remaining_secs); + + path = gtk_tree_row_reference_get_path (row_ref); + gtk_tree_model_get_iter (dv->priv->model, &iter, path); + gtk_list_store_set (GTK_LIST_STORE (dv->priv->model), + &iter, + COL_PERCENT, percent, + COL_SIZE, size, + COL_REMAINING, remaining, -1); - - if (gtk_tree_path_compare (path, selected_path) == 0) - { - downloader_view_update_details (priv, details); - } - gtk_tree_path_free (path); - gtk_tree_path_free (selected_path); -} -static void -ensure_selected_row (DownloaderView *dv) -{ - GtkTreeIter iter; - GtkTreeSelection *selection; - - g_return_if_fail (EPHY_IS_DOWNLOADER_VIEW(dv)); - - selection = gtk_tree_view_get_selection - (GTK_TREE_VIEW(dv->priv->treeview)); - if (get_selected_row (dv->priv, &iter)) - { - /* there is already a selection */ - return; - } - - if (gtk_tree_model_get_iter_first (dv->priv->model, &iter)) - { - gtk_tree_selection_select_iter (selection, &iter); - } + g_free (size); + g_free (remaining); } void downloader_view_add_download (DownloaderView *dv, - gchar *filename, - gchar *source, - gchar *dest, - gpointer persist_object) + EphyDownload *download) { + GtkTreeRowReference *row_ref; GtkTreeIter iter; - DownloadDetails *details; GtkTreeSelection *selection; GtkTreePath *path; + char *name; - details = g_new0 (DownloadDetails, 1); - details->filename = g_strdup (filename); - details->source = g_strdup (source); - details->dest = g_strdup (dest); - details->elapsed = -1; - details->remaining = -1; - details->speed = -1; - details->size_total = -1; - details->size_done = 0; - details->progress = -1; - details->download_started = FALSE; - dv->priv->show_details = FALSE; - - g_hash_table_insert (dv->priv->details_hash, - persist_object, - details); gtk_list_store_append (GTK_LIST_STORE (dv->priv->model), &iter); path = gtk_tree_model_get_path (GTK_TREE_MODEL (dv->priv->model), &iter); - details->ref = gtk_tree_row_reference_new - (GTK_TREE_MODEL (dv->priv->model),path); + row_ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (dv->priv->model), path); gtk_tree_path_free (path); + g_hash_table_insert (dv->priv->details_hash, + download, + row_ref); + + name = ephy_download_get_name (download); gtk_list_store_set (GTK_LIST_STORE (dv->priv->model), &iter, - COL_PERSIST_OBJECT, persist_object, + COL_FILENAME, name, + COL_DOWNLOAD_OBJECT, download, -1); + g_free (name); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(dv->priv->treeview)); gtk_tree_selection_unselect_all (selection); gtk_tree_selection_select_iter (selection, &iter); - downloader_view_set_download_info (dv->priv, details, &iter); + g_signal_connect (download, "changed", + G_CALLBACK (download_changed_cb), dv); ephy_dialog_show (EPHY_DIALOG (dv)); } -void -downloader_view_remove_download (DownloaderView *dv, - gpointer persist_object) -{ - DownloadDetails *details; - GtkTreePath *path = NULL; - GtkTreeIter iter; - - details = g_hash_table_lookup (dv->priv->details_hash, - persist_object); - g_return_if_fail (details); - - path = gtk_tree_row_reference_get_path (details->ref); - - gtk_tree_model_get_iter (GTK_TREE_MODEL (dv->priv->model), - &iter, path); - - gtk_list_store_remove (GTK_LIST_STORE (dv->priv->model), &iter); - - g_hash_table_remove (dv->priv->details_hash, - persist_object); - - ensure_selected_row (dv); - - gtk_tree_path_free (path); -} - -void -downloader_view_set_download_progress (DownloaderView *dv, - glong elapsed, - glong remaining, - gfloat speed, - gint size_total, - gint size_done, - gfloat progress, - gpointer persist_object) -{ - DownloadDetails *details; - GtkTreePath *path = NULL; - GtkTreeIter iter; - - details = g_hash_table_lookup (dv->priv->details_hash, - persist_object); - g_return_if_fail (details); - - details->elapsed = elapsed; - details->remaining = remaining; - details->speed = speed; - details->size_total = size_total; - details->size_done = size_done; - details->progress = progress; - - path = gtk_tree_row_reference_get_path (details->ref); - - gtk_tree_model_get_iter (GTK_TREE_MODEL (dv->priv->model), - &iter, path); - - downloader_view_set_download_info (dv->priv, details, &iter); - - gtk_tree_path_free (path); -} - -void -downloader_view_set_download_status (DownloaderView *dv, - DownloadStatus status, - gpointer persist_object) -{ - DownloadDetails *details; - GtkTreePath *path = NULL; - GtkTreeIter iter; - - details = g_hash_table_lookup (dv->priv->details_hash, - persist_object); - g_return_if_fail (details); - - details->status = status; - - path = gtk_tree_row_reference_get_path (details->ref); - - gtk_tree_model_get_iter (GTK_TREE_MODEL (dv->priv->model), - &iter, path); - - downloader_view_set_download_info (dv->priv, details, &iter); - downloader_view_update_controls (dv->priv); - -/* if (status == DOWNLOAD_STATUS_COMPLETED) - { - downloader_view_remove_download (dv, persist_object); - }*/ - - gtk_tree_path_free (path); -} - static void downloader_view_build_ui (DownloaderView *dv) { @@ -725,7 +325,6 @@ downloader_view_build_ui (DownloaderView *dv) GtkTreeViewColumn *column; GtkCellRenderer *renderer; GtkTreeSelection *selection; - GtkWidget *details_table; GdkPixbuf *icon; EphyDialog *d = EPHY_DIALOG (dv); @@ -737,49 +336,37 @@ downloader_view_build_ui (DownloaderView *dv) /* lookup needed widgets */ priv->window = ephy_dialog_get_control(d, PROP_WINDOW); priv->treeview = ephy_dialog_get_control (d, PROP_TREEVIEW); - priv->details_status = ephy_dialog_get_control (d, PROP_DETAILS_STATUS); - priv->details_elapsed = ephy_dialog_get_control (d, PROP_DETAILS_ELAPSED); - priv->details_remaining = ephy_dialog_get_control (d, PROP_DETAILS_REMAINING); - priv->details_progress = ephy_dialog_get_control (d, PROP_DETAILS_PROGRESS); - priv->details_button = ephy_dialog_get_control (d, PROP_DETAILS_BUTTON); priv->open_button = ephy_dialog_get_control (d, PROP_OPEN_BUTTON); priv->pause_button = ephy_dialog_get_control (d, PROP_PAUSE_BUTTON); priv->abort_button = ephy_dialog_get_control (d, PROP_ABORT_BUTTON); - details_table = ephy_dialog_get_control (d, PROP_DETAILS_TABLE); - /* create file and location details labels */ - priv->details_location = ephy_ellipsizing_label_new (""); - gtk_table_attach_defaults (GTK_TABLE(details_table), - priv->details_location, - 1, 2, 1, 2); - gtk_misc_set_alignment (GTK_MISC(priv->details_location), 0, 0); - gtk_label_set_selectable (GTK_LABEL(priv->details_location), TRUE); - gtk_widget_show (priv->details_location); + gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview)), + GTK_SELECTION_SINGLE); liststore = gtk_list_store_new (5, + G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_POINTER); + G_TYPE_OBJECT); gtk_tree_view_set_model (GTK_TREE_VIEW(priv->treeview), GTK_TREE_MODEL (liststore)); gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(priv->treeview), TRUE); - renderer = gtk_cell_renderer_text_new (); - + renderer = ephy_cell_renderer_progress_new (); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW(priv->treeview), 0, _("%"), renderer, - "text", 0, + "value", 0, NULL); column = gtk_tree_view_get_column (GTK_TREE_VIEW(priv->treeview), 0); gtk_tree_view_column_set_resizable (column, TRUE); gtk_tree_view_column_set_reorderable (column, TRUE); gtk_tree_view_column_set_sort_column_id (column, COL_PERCENT); + renderer = gtk_cell_renderer_text_new (); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW(priv->treeview), COL_FILENAME, _("Filename"), renderer, @@ -815,8 +402,6 @@ downloader_view_build_ui (DownloaderView *dv) selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(priv->treeview)); gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); - g_signal_connect (G_OBJECT (selection), "changed", - G_CALLBACK (downloader_treeview_selection_changed_cb), dv); priv->model = GTK_TREE_MODEL (liststore); @@ -833,260 +418,88 @@ download_dialog_pause_cb (GtkButton *button, DownloaderView *dv) GtkTreeSelection *selection; GtkTreeModel *model; GtkTreeIter iter; - DownloadDetails *details; GValue val = {0, }; - gpointer *persist_object; + EphyDownload *download; + EphyDownloadState state; selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(dv->priv->treeview)); if (!gtk_tree_selection_get_selected (selection, &model, &iter)) return; - gtk_tree_model_get_value (model, &iter, COL_PERSIST_OBJECT, &val); - persist_object = g_value_get_pointer (&val); + gtk_tree_model_get_value (model, &iter, COL_DOWNLOAD_OBJECT, &val); + download = g_value_get_object (&val); g_value_unset (&val); - details = g_hash_table_lookup (dv->priv->details_hash, - persist_object); - g_return_if_fail (details); + state = ephy_download_get_state (download); - if (details->status == DOWNLOAD_STATUS_COMPLETED) - { - return; - } - else if (details->status == DOWNLOAD_STATUS_DOWNLOADING || - details->status == DOWNLOAD_STATUS_RESUMING) + if (state == EPHY_DOWNLOAD_DOWNLOADING) { - g_signal_emit (G_OBJECT (dv), downloader_view_signals[DOWNLOAD_PAUSE], 0, persist_object); - downloader_view_set_download_status (dv, DOWNLOAD_STATUS_PAUSED, persist_object); + ephy_download_pause (download); } - else if (details->status == DOWNLOAD_STATUS_PAUSED) + else if (state == EPHY_DOWNLOAD_PAUSED) { - g_signal_emit (G_OBJECT (dv), downloader_view_signals[DOWNLOAD_RESUME], 0, persist_object); - downloader_view_set_download_status (dv, DOWNLOAD_STATUS_RESUMING, persist_object); + ephy_download_resume (download); } } void -download_dialog_abort_cb (GtkButton *button, DownloaderView *dv) +downloader_view_remove_download (DownloaderView *dv, EphyDownload *download) { - GList *llist, *rlist = NULL, *l, *r; - GtkTreeSelection *selection; - GtkTreeModel *model; - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(dv->priv->treeview)); - llist = gtk_tree_selection_get_selected_rows (selection, &model); - for (l = llist;l != NULL; l = l->next) - { - rlist = g_list_prepend (rlist, gtk_tree_row_reference_new - (model, (GtkTreePath *)l->data)); - } - - for (r = rlist; r != NULL; r = r->next) - { - GtkTreeRowReference *node = r->data; - GtkTreePath *path = NULL; - GValue val = {0, }; - gpointer *persist_object; - GtkTreeIter iter; - DownloadDetails *details; - - path = gtk_tree_row_reference_get_path (node); + GtkTreeRowReference *row_ref; + GtkTreePath *path = NULL; + GtkTreeIter iter; - gtk_tree_model_get_iter (model, &iter, path); + row_ref = get_row_from_download (dv, download); + g_return_if_fail (row_ref); - gtk_tree_model_get_value (model, &iter, - COL_PERSIST_OBJECT, &val); - persist_object = g_value_get_pointer (&val); - g_value_unset (&val); + path = gtk_tree_row_reference_get_path (row_ref); + gtk_tree_model_get_iter (GTK_TREE_MODEL (dv->priv->model), + &iter, path); - details = g_hash_table_lookup (dv->priv->details_hash, - persist_object); - g_return_if_fail (details); + gtk_list_store_remove (GTK_LIST_STORE (dv->priv->model), &iter); - g_signal_emit (G_OBJECT (dv), downloader_view_signals[DOWNLOAD_REMOVE], 0, persist_object); + /* FIXME: smart selection */ - downloader_view_remove_download (dv, persist_object); + g_hash_table_remove (dv->priv->details_hash, + download); - gtk_tree_row_reference_free (node); - gtk_tree_path_free (path); - } + gtk_tree_path_free (path); - g_list_foreach (llist, (GFunc)gtk_tree_path_free, NULL); - g_list_free (llist); - g_list_free (rlist); } -static void -downloader_treeview_selection_changed_cb (GtkTreeSelection *selection, - DownloaderView *dv) +void +download_dialog_abort_cb (GtkButton *button, DownloaderView *dv) { - GtkTreeIter iter; GValue val = {0, }; - gpointer *persist_object; - DownloadDetails *details = NULL; - GtkWidget *details_button; - GtkWidget *details_frame; - DownloaderViewPrivate *priv= dv->priv; - - details_button = ephy_dialog_get_control (EPHY_DIALOG(dv), - PROP_DETAILS_BUTTON); - details_frame = ephy_dialog_get_control (EPHY_DIALOG(dv), - PROP_DETAILS_FRAME); - - if (get_selected_row (priv, &iter)) - { - gtk_tree_model_get_value (priv->model, &iter, COL_PERSIST_OBJECT, &val); - persist_object = g_value_get_pointer (&val); - g_value_unset (&val); - - details = g_hash_table_lookup (priv->details_hash, - persist_object); - g_return_if_fail (details); - - gtk_widget_set_sensitive (details_button, TRUE); - gtk_widget_set_sensitive (details_frame, TRUE); - - downloader_view_update_details (priv, details); - downloader_view_update_controls (priv); - } - else - { - gtk_label_set_text (GTK_LABEL (priv->details_location), ""); - gtk_label_set_text (GTK_LABEL (priv->details_status), ""); - gtk_label_set_text (GTK_LABEL (priv->details_elapsed), ""); - gtk_label_set_text (GTK_LABEL (priv->details_remaining), ""); - gtk_progress_bar_set_fraction - (GTK_PROGRESS_BAR (priv->details_progress), - 0); - - gtk_widget_set_sensitive (details_frame, FALSE); - if (!gtk_tree_model_get_iter_first (priv->model, &iter)) - gtk_widget_set_sensitive (details_button, FALSE); - } -} - -static void -alive_download_foreach (gpointer persist_object, - DownloadDetails *details, - gboolean *alive) -{ - if (details->status != DOWNLOAD_STATUS_COMPLETED) - { - *alive = TRUE; - } -} - -static gboolean -delete_pending_foreach (gpointer persist_object, - DownloadDetails *details, - DownloaderView *dv) -{ - if (details->status != DOWNLOAD_STATUS_COMPLETED) - { - g_signal_emit (G_OBJECT (dv), downloader_view_signals[DOWNLOAD_REMOVE], - 0, persist_object); - } + GtkTreeSelection *selection; + GtkTreeIter iter; + GtkTreeModel *model; + gpointer download; - return TRUE; + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(dv->priv->treeview)); + + gtk_tree_selection_get_selected (selection, &model, &iter); + gtk_tree_model_get_value (model, &iter, COL_DOWNLOAD_OBJECT, &val); + + download = g_value_get_object (&val); + g_value_unset (&val); + g_return_if_fail (download != NULL); + + ephy_download_cancel ((EphyDownload*)download); + downloader_view_remove_download (dv, download); } gboolean download_dialog_delete_cb (GtkWidget *window, GdkEventAny *event, DownloaderView *dv) { - GtkWidget *dialog; - gboolean choice; - gboolean alive_download = FALSE; - - g_hash_table_foreach (dv->priv->details_hash, - (GHFunc)alive_download_foreach, - &alive_download); - - if (!alive_download) return FALSE; - - /* build question dialog */ - dialog = gtk_message_dialog_new ( - GTK_WINDOW (window), - GTK_DIALOG_MODAL, - GTK_MESSAGE_WARNING, - GTK_BUTTONS_YES_NO, - _("Cancel all pending downloads?")); - - /* run it */ - choice = gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - - /* do the appropriate thing */ - if (choice == GTK_RESPONSE_YES) - { - g_hash_table_foreach_remove (dv->priv->details_hash, - (GHRFunc)delete_pending_foreach, - dv); - return FALSE; - } - - return TRUE; -} - -void -download_dialog_details_cb (GtkToggleButton *button, - DownloaderView *dv) -{ - GtkWidget *details_frame; - - details_frame = ephy_dialog_get_control (EPHY_DIALOG(dv), - PROP_DETAILS_FRAME); - if (gtk_toggle_button_get_active (button)) - { - gtk_widget_show (GTK_WIDGET (details_frame)); - dv->priv->show_details = TRUE; - } - else - { - gtk_widget_hide (GTK_WIDGET (details_frame)); - dv->priv->show_details = FALSE; - } - + return FALSE; } static void open_selection_foreach (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, DownloaderView *dv) { - DownloadDetails *details; - GValue val = {0, }; - gpointer *persist_object; - GnomeVFSMimeApplication *app; - char *mime; - - gtk_tree_model_get_value (model, iter, COL_PERSIST_OBJECT, &val); - persist_object = g_value_get_pointer (&val); - g_value_unset (&val); - - details = g_hash_table_lookup (dv->priv->details_hash, - persist_object); - g_return_if_fail (details); - - if (details->status != DOWNLOAD_STATUS_COMPLETED) return; - - mime = gnome_vfs_get_mime_type (details->dest); - g_return_if_fail (mime != NULL); - - app = gnome_vfs_mime_get_default_application (mime); - if (app) - { - ephy_file_launch_application (app->command, - details->dest, - app->requires_terminal); - } - else - { - GtkWidget *parent; - parent = gtk_widget_get_toplevel (dv->priv->open_button); - ephy_embed_utils_nohandler_dialog_run (parent); - } - - g_free(mime); } void diff --git a/embed/downloader-view.h b/embed/downloader-view.h index 007b6727b..433523b30 100644 --- a/embed/downloader-view.h +++ b/embed/downloader-view.h @@ -20,6 +20,7 @@ #define DOWNLOADER_VIEW_H #include "ephy-dialog.h" +#include "ephy-download.h" #include <glib-object.h> #include <glib.h> @@ -37,14 +38,6 @@ typedef struct DownloaderView DownloaderView; typedef struct DownloaderViewClass DownloaderViewClass; typedef struct DownloaderViewPrivate DownloaderViewPrivate; -typedef enum -{ - DOWNLOAD_STATUS_DOWNLOADING, - DOWNLOAD_STATUS_PAUSED, - DOWNLOAD_STATUS_RESUMING, - DOWNLOAD_STATUS_COMPLETED -} DownloadStatus; - struct DownloaderView { EphyDialog parent; @@ -54,10 +47,6 @@ struct DownloaderView struct DownloaderViewClass { EphyDialogClass parent_class; - - void (*download_remove) (DownloaderView *dv, gpointer persist_object); - void (*download_pause) (DownloaderView *dv, gpointer persist_object); - void (*download_resume) (DownloaderView *dv, gpointer persist_object); }; GType downloader_view_get_type (void); @@ -65,26 +54,10 @@ GType downloader_view_get_type (void); DownloaderView *downloader_view_new (void); void downloader_view_add_download (DownloaderView *dv, - gchar *filename, - gchar *source, - gchar *dest, - gpointer persist_object); + EphyDownload *download); void downloader_view_remove_download (DownloaderView *dv, - gpointer persist_object); - -void downloader_view_set_download_status (DownloaderView *dv, - DownloadStatus status, - gpointer persist_object); - -void downloader_view_set_download_progress (DownloaderView *dv, - glong elapsed, - glong remaining, - gfloat speed, - gint size_total, - gint size_done, - gfloat progress, - gpointer persist_object); + EphyDownload *download); G_END_DECLS diff --git a/embed/ephy-download.c b/embed/ephy-download.c new file mode 100644 index 000000000..0e72f9d90 --- /dev/null +++ b/embed/ephy-download.c @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "ephy-download.h" + +#include <libgnomevfs/gnome-vfs-uri.h> + +static void +ephy_download_class_init (EphyDownloadClass *klass); +static void +ephy_download_init (EphyDownload *dv); + +enum +{ + CHANGED, + LAST_SIGNAL +}; + +static GObjectClass *parent_class = NULL; + +static guint ephy_download_signals[LAST_SIGNAL] = { 0 }; + +GType +ephy_download_get_type (void) +{ + static GType ephy_download_type = 0; + + if (ephy_download_type == 0) + { + static const GTypeInfo our_info = + { + sizeof (EphyDownloadClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) ephy_download_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (EphyDownload), + 0, /* n_preallocs */ + (GInstanceInitFunc) ephy_download_init + }; + + ephy_download_type = g_type_register_static (G_TYPE_OBJECT, + "EphyDownload", + &our_info, 0); + } + + return ephy_download_type; +} + +static void +ephy_download_class_init (EphyDownloadClass *klass) +{ + parent_class = g_type_class_peek_parent (klass); + + ephy_download_signals[CHANGED] = + g_signal_new ("changed", + EPHY_TYPE_DOWNLOAD, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (EphyDownloadClass, changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); +} + +static void +ephy_download_init (EphyDownload *dv) +{ +} + +EphyDownload * +ephy_download_new (void) +{ + return EPHY_DOWNLOAD (g_object_new (EPHY_TYPE_DOWNLOAD, NULL)); +} + +char * +ephy_download_get_name (EphyDownload *download) +{ + GnomeVFSURI *uri; + char *target; + char *result; + + target = ephy_download_get_target (download); + + uri = gnome_vfs_uri_new (target); + if (uri) + { + result = gnome_vfs_uri_extract_short_name (uri); + gnome_vfs_uri_unref (uri); + } + else + { + result = g_strdup ("Unknown"); + } + + return result; +} + +long +ephy_download_get_remaining_time (EphyDownload *download) +{ + long elapsed_time, remaining_time = 0; + long total, cur; + + total = ephy_download_get_total_progress (download); + cur = ephy_download_get_current_progress (download); + elapsed_time = ephy_download_get_elapsed_time (download); + + if (cur > 0) + { + remaining_time = elapsed_time * (total - cur) / cur; + } + + return remaining_time; +} + +char * +ephy_download_get_source (EphyDownload *download) +{ + EphyDownloadClass *klass = EPHY_DOWNLOAD_GET_CLASS (download); + return klass->get_source (download); +} + +char * +ephy_download_get_target (EphyDownload *download) +{ + EphyDownloadClass *klass = EPHY_DOWNLOAD_GET_CLASS (download); + return klass->get_target (download); +} + +long +ephy_download_get_current_progress (EphyDownload *download) +{ + EphyDownloadClass *klass = EPHY_DOWNLOAD_GET_CLASS (download); + return klass->get_current_progress (download); +} + +long +ephy_download_get_total_progress (EphyDownload *download) +{ + EphyDownloadClass *klass = EPHY_DOWNLOAD_GET_CLASS (download); + return klass->get_total_progress (download); +} + +int +ephy_download_get_percent (EphyDownload *download) +{ + EphyDownloadClass *klass = EPHY_DOWNLOAD_GET_CLASS (download); + return klass->get_percent (download); +} + +long +ephy_download_get_elapsed_time (EphyDownload *download) +{ + EphyDownloadClass *klass = EPHY_DOWNLOAD_GET_CLASS (download); + return klass->get_elapsed_time (download); +} + +EphyDownloadState +ephy_download_get_state (EphyDownload *download) +{ + EphyDownloadClass *klass = EPHY_DOWNLOAD_GET_CLASS (download); + return klass->get_state (download); +} + +void +ephy_download_cancel (EphyDownload *download) +{ + EphyDownloadClass *klass = EPHY_DOWNLOAD_GET_CLASS (download); + klass->cancel (download); +} + +void +ephy_download_pause (EphyDownload *download) +{ + EphyDownloadClass *klass = EPHY_DOWNLOAD_GET_CLASS (download); + klass->pause (download); +} + +void +ephy_download_resume (EphyDownload *download) +{ + EphyDownloadClass *klass = EPHY_DOWNLOAD_GET_CLASS (download); + klass->resume (download); +} diff --git a/embed/ephy-download.h b/embed/ephy-download.h new file mode 100644 index 000000000..adb82adaf --- /dev/null +++ b/embed/ephy-download.h @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef EPHY_DOWNLOAD_H +#define EPHY_DOWNLOAD_H + +#include <glib-object.h> +#include <glib.h> + +G_BEGIN_DECLS + +#define EPHY_TYPE_DOWNLOAD (ephy_download_get_type ()) +#define EPHY_DOWNLOAD(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EPHY_TYPE_DOWNLOAD, EphyDownload)) +#define EPHY_DOWNLOAD_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EPHY_TYPE_DOWNLOAD, EphyDownloadClass)) +#define EPHY_IS_DOWNLOAD(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EPHY_TYPE_DOWNLOAD)) +#define EPHY_IS_DOWNLOAD_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EPHY_TYPE_DOWNLOAD)) +#define EPHY_DOWNLOAD_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EPHY_TYPE_DOWNLOAD, EphyDownloadClass)) + +typedef struct EphyDownload EphyDownload; +typedef struct EphyDownloadClass EphyDownloadClass; +typedef struct EphyDownloadPrivate EphyDownloadPrivate; + +typedef enum +{ + EPHY_DOWNLOAD_DOWNLOADING, + EPHY_DOWNLOAD_PAUSED, + EPHY_DOWNLOAD_COMPLETED, + EPHY_DOWNLOAD_FAILED +} EphyDownloadState; + +struct EphyDownload +{ + GObject parent; +}; + +struct EphyDownloadClass +{ + GObjectClass parent_class; + + char * (* get_source) (EphyDownload *download); + char * (* get_target) (EphyDownload *download); + int (* get_percent) (EphyDownload *download); + long (* get_current_progress) (EphyDownload *download); + long (* get_total_progress) (EphyDownload *download); + long (* get_elapsed_time) (EphyDownload *download); + void (* cancel) (EphyDownload *download); + void (* pause) (EphyDownload *download); + void (* resume) (EphyDownload *download); + EphyDownloadState (* get_state) (EphyDownload *download); + + /* Signals */ + void (* changed) (EphyDownload *download); +}; + +/* Time is expressed in seconds, file sizes in bytes */ + +GType ephy_download_get_type (void); + +EphyDownload *ephy_download_new (void); + +char *ephy_download_get_name (EphyDownload *download); + +char *ephy_download_get_source (EphyDownload *download); + +char *ephy_download_get_target (EphyDownload *download); + +int ephy_download_get_percent (EphyDownload *download); + +EphyDownloadState ephy_download_get_state (EphyDownload *download); + +long ephy_download_get_current_progress (EphyDownload *download); + +long ephy_download_get_total_progress (EphyDownload *download); + +long ephy_download_get_elapsed_time (EphyDownload *download); + +long ephy_download_get_remaining_time (EphyDownload *download); + +void ephy_download_cancel (EphyDownload *download); + +void ephy_download_pause (EphyDownload *download); + +void ephy_download_resume (EphyDownload *download); + +G_END_DECLS + +#endif diff --git a/embed/ephy-embed-persist.h b/embed/ephy-embed-persist.h index e8c7753b7..ad0a702b2 100644 --- a/embed/ephy-embed-persist.h +++ b/embed/ephy-embed-persist.h @@ -39,11 +39,9 @@ typedef struct EphyEmbedPersistPrivate EphyEmbedPersistPrivate; typedef enum { - EMBED_PERSIST_SHOW_PROGRESS = 1 << 0, - EMBED_PERSIST_SAVE_CONTENT = 1 << 1, - EMBED_PERSIST_FROMCACHE = 1 << 2, - EMBED_PERSIST_BYPASSCACHE = 1 << 3, - EMBED_PERSIST_MAINDOC = 1 << 4 + EMBED_PERSIST_BYPASSCACHE = 1 << 0, + EMBED_PERSIST_MAINDOC = 1 << 1, + EMBED_PERSIST_NO_VIEW = 1 << 2 } EmbedPersistFlags; typedef struct diff --git a/embed/ephy-embed-popup-control.c b/embed/ephy-embed-popup-control.c index 9c6dd87b5..a300e0535 100644 --- a/embed/ephy-embed-popup-control.c +++ b/embed/ephy-embed-popup-control.c @@ -480,7 +480,6 @@ static void save_property_url (EphyEmbedPopupControl *popup, const char *title, gboolean ask_dest, - gboolean show_progress, const char *property) { EphyEmbedEvent *info; @@ -501,15 +500,9 @@ save_property_url (EphyEmbedPopupControl *popup, ephy_embed_persist_set_source (persist, location); - if (show_progress) - { - ephy_embed_persist_set_flags (persist, - EMBED_PERSIST_SHOW_PROGRESS); - } - ephy_embed_utils_save (window, title, CONF_STATE_DOWNLOADING_DIR, - ask_dest, FALSE, persist); + ask_dest, persist); } /* commands */ @@ -539,7 +532,7 @@ embed_popup_download_link_cmd (BonoboUIComponent *uic, _("Download Link"), eel_gconf_get_boolean (CONF_ASK_DOWNLOAD_DEST), - TRUE, "link"); + "link"); } static void @@ -547,7 +540,7 @@ embed_popup_save_image_as_cmd (BonoboUIComponent *uic, EphyEmbedPopupControl *popup, const char* verbname) { - save_property_url (popup, _("Save Image As"), TRUE, FALSE, "image"); + save_property_url (popup, _("Save Image As"), TRUE, "image"); } #define CONF_DESKTOP_BG_PICTURE "/desktop/gnome/background/picture_filename" @@ -628,7 +621,6 @@ static void save_url (EphyEmbedPopupControl *popup, const char *title, gboolean ask_dest, - gboolean show_progress, const char *url) { GtkWidget *widget; @@ -641,15 +633,9 @@ save_url (EphyEmbedPopupControl *popup, persist = ephy_embed_persist_new (popup->priv->embed); ephy_embed_persist_set_source (persist, url); - if (show_progress) - { - ephy_embed_persist_set_flags (persist, - EMBED_PERSIST_SHOW_PROGRESS); - } - ephy_embed_utils_save (window, title, CONF_STATE_DOWNLOADING_DIR, - ask_dest, FALSE, persist); + ask_dest, persist); } static void @@ -661,7 +647,7 @@ embed_popup_save_page_as_cmd (BonoboUIComponent *uic, ephy_embed_get_location (popup->priv->embed, FALSE, &location); - save_url (popup, _("Save Page As"), TRUE, FALSE, location); + save_url (popup, _("Save Page As"), TRUE, location); g_free (location); } @@ -671,7 +657,7 @@ embed_popup_save_background_as_cmd (BonoboUIComponent *uic, const char* verbname) { save_property_url (popup, _("Save Background As"), - TRUE, FALSE, "background_image"); + TRUE, "background_image"); } static void diff --git a/embed/ephy-embed-shell.c b/embed/ephy-embed-shell.c index 39e320e0c..bcf9c0d00 100644 --- a/embed/ephy-embed-shell.c +++ b/embed/ephy-embed-shell.c @@ -24,8 +24,8 @@ #include "ephy-marshal.h" #include "ephy-favicon-cache.h" #include "mozilla-embed-single.h" -#include "ephy-debug.h" #include "downloader-view.h" +#include "ephy-debug.h" #include <string.h> diff --git a/embed/ephy-embed-utils.c b/embed/ephy-embed-utils.c index 5da187c89..c6e113042 100644 --- a/embed/ephy-embed-utils.c +++ b/embed/ephy-embed-utils.c @@ -55,7 +55,6 @@ ephy_embed_utils_save (GtkWidget *window, const char *title, const char *default_dir_pref, gboolean ask_dest, - gboolean with_content, EphyEmbedPersist *persist) { GnomeVFSURI *uri; @@ -160,8 +159,6 @@ ephy_embed_utils_save (GtkWidget *window, if (ret == G_OK) { - if (with_content) flags |= EMBED_PERSIST_SAVE_CONTENT; - ephy_embed_persist_set_flags (persist, flags); ephy_embed_persist_set_dest (persist, retPath); diff --git a/embed/ephy-embed-utils.h b/embed/ephy-embed-utils.h index f6ccce7d8..8a0a52591 100644 --- a/embed/ephy-embed-utils.h +++ b/embed/ephy-embed-utils.h @@ -30,7 +30,6 @@ void ephy_embed_utils_save (GtkWidget *window, const char *title, const char *default_dir_pref, gboolean ask_dest, - gboolean with_content, EphyEmbedPersist *persist); void ephy_embed_utils_build_encodings_submenu (BonoboUIComponent *ui_component, diff --git a/embed/mozilla/ContentHandler.cpp b/embed/mozilla/ContentHandler.cpp index 48809a099..519bff738 100644 --- a/embed/mozilla/ContentHandler.cpp +++ b/embed/mozilla/ContentHandler.cpp @@ -159,7 +159,6 @@ extern "C" { #include "ephy-gui.h" #include "ephy-embed-utils.h" #include "ephy-file-helpers.h" -#include "ProgressListener.h" #include "ContentHandler.h" #include <gtk/gtkentry.h> @@ -189,9 +188,10 @@ extern "C" { #include "nsIPrefService.h" #include "nsIDOMWindow.h" #include "nsIDOMWindowInternal.h" +#include "nsIMIMEInfo.h" class GContentHandler; -class GDownloadProgressListener; +//class GDownloadProgressListener; struct MimeAskActionDialog; struct HelperAppChooserDialog; @@ -454,15 +454,20 @@ NS_METHOD GContentHandler::SetHelperApp(GnomeVFSMimeApplication *aHelperApp, NS_METHOD GContentHandler::SynchroniseMIMEInfo (void) { nsresult rv; + char *command_with_path; + nsCOMPtr<nsIMIMEInfo> mimeInfo; rv = mLauncher->GetMIMEInfo(getter_AddRefs(mimeInfo)); if(NS_FAILED(rv)) return NS_ERROR_FAILURE; + command_with_path = g_find_program_in_path (mHelperApp->command); + if (command_with_path == NULL) return NS_ERROR_FAILURE; nsCOMPtr<nsILocalFile> helperFile; - rv = NS_NewNativeLocalFile(nsDependentCString(mHelperApp->command), + rv = NS_NewNativeLocalFile(nsDependentCString(command_with_path), PR_TRUE, getter_AddRefs(helperFile)); if(NS_FAILED(rv)) return NS_ERROR_FAILURE; + g_free (command_with_path); rv = mimeInfo->SetPreferredApplicationHandler(helperFile); if(NS_FAILED(rv)) return NS_ERROR_FAILURE; diff --git a/embed/mozilla/EphyDownload.cpp b/embed/mozilla/EphyDownload.cpp deleted file mode 100644 index 062abc983..000000000 --- a/embed/mozilla/EphyDownload.cpp +++ /dev/null @@ -1,470 +0,0 @@ -/* -*- 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) 2002 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Conrad Carlen <ccarlen@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 "EphyDownload.h" - -#include "nsIExternalHelperAppService.h" -//#include "nsILocalFIleMac.h" -#include "nsDirectoryServiceDefs.h" -#include "nsDirectoryServiceUtils.h" -#include "nsIRequest.h" -#include "netCore.h" -#include "nsIObserver.h" - -//#include "UDownloadDisplay.h" -//#include "UMacUnicode.h" - -//#include "UNavServicesDialogs.h" - - -//***************************************************************************** -// EphyDownload -//***************************************************************************** -#pragma mark [EphyDownload] - -//ADownloadProgressView *EphyDownload::sProgressView; - -EphyDownload::EphyDownload() : - mGotFirstStateChange(false), mIsNetworkTransfer(false), - mUserCanceled(false), - mStatus(NS_OK) -{ -} - -EphyDownload::~EphyDownload() -{ -} - -NS_IMPL_ISUPPORTS2(EphyDownload, nsIDownload, nsIWebProgressListener) - -#pragma mark - -#pragma mark [EphyDownload::nsIDownload] - -/* void init (in nsIURI aSource, in nsILocalFile aTarget, in wstring aDisplayName, in nsIMIMEInfo aMIMEInfo, in long long startTime, in nsIWebBrowserPersist aPersist); */ -NS_IMETHODIMP -EphyDownload::Init(nsIURI *aSource, nsILocalFile *aTarget, const PRUnichar *aDisplayName, - nsIMIMEInfo *aMIMEInfo, PRInt64 startTime, nsIWebBrowserPersist *aPersist) -{ - try { - mSource = aSource; - mDestination = aTarget; - mStartTime = startTime; - mPercentComplete = 0; - mInterval = 400000; // ms - mPriorKRate = 0; - mRateChanges = 0; - mRateChangeLimit = 2; - mIsPaused = PR_FALSE; - mStartTime = PR_Now(); - mLastUpdate = mStartTime; - if (aPersist) { - mWebPersist = aPersist; - // We have to break this circular ref when the download is done - - // until nsIWebBrowserPersist supports weak refs - bug #163889. - aPersist->SetProgressListener(this); - } - // UI Rumba - mDownloaderView = EPHY_DOWNLOADER_VIEW (ephy_embed_shell_get_downloader_view - (embed_shell)); - downloader_view_add_download (mDownloaderView, "A", "B", "C", (gpointer)this); - // EnsureProgressView(); - // sProgressView->AddDownloadItem(this); - } - catch (...) { - return NS_ERROR_FAILURE; - } - return NS_OK; -} - -/* readonly attribute nsIURI source; */ -NS_IMETHODIMP -EphyDownload::GetSource(nsIURI * *aSource) -{ - NS_ENSURE_ARG_POINTER(aSource); - NS_IF_ADDREF(*aSource = mSource); - return NS_OK; -} - -/* readonly attribute nsILocalFile target; */ -NS_IMETHODIMP -EphyDownload::GetTarget(nsILocalFile * *aTarget) -{ - NS_ENSURE_ARG_POINTER(aTarget); - NS_IF_ADDREF(*aTarget = mDestination); - return NS_OK; -} - -/* readonly attribute nsIWebBrowserPersist persist; */ -NS_IMETHODIMP -EphyDownload::GetPersist(nsIWebBrowserPersist * *aPersist) -{ - NS_ENSURE_ARG_POINTER(aPersist); - NS_IF_ADDREF(*aPersist = mWebPersist); - return NS_OK; -} - -/* readonly attribute PRInt32 percentComplete; */ -NS_IMETHODIMP -EphyDownload::GetPercentComplete(PRInt32 *aPercentComplete) -{ - NS_ENSURE_ARG_POINTER(aPercentComplete); - *aPercentComplete = mPercentComplete; - return NS_OK; -} - -/* attribute wstring displayName; */ -NS_IMETHODIMP -EphyDownload::GetDisplayName(PRUnichar * *aDisplayName) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -EphyDownload::SetDisplayName(const PRUnichar * aDisplayName) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -/* readonly attribute long long startTime; */ -NS_IMETHODIMP -EphyDownload::GetStartTime(PRInt64 *aStartTime) -{ - NS_ENSURE_ARG_POINTER(aStartTime); - *aStartTime = mStartTime; - return NS_OK; -} - -/* readonly attribute nsIMIMEInfo MIMEInfo; */ -NS_IMETHODIMP -EphyDownload::GetMIMEInfo(nsIMIMEInfo * *aMIMEInfo) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -/* attribute nsIWebProgressListener listener; */ -NS_IMETHODIMP -EphyDownload::GetListener(nsIWebProgressListener * *aListener) -{ - NS_ENSURE_ARG_POINTER(aListener); - NS_IF_ADDREF(*aListener = (nsIWebProgressListener *)this); - return NS_OK; -} - -NS_IMETHODIMP -EphyDownload::SetListener(nsIWebProgressListener * aListener) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -/* attribute nsIObserver observer; */ -NS_IMETHODIMP -EphyDownload::GetObserver(nsIObserver * *aObserver) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -EphyDownload::SetObserver(nsIObserver * aObserver) -{ - if (aObserver) - aObserver->QueryInterface(NS_GET_IID(nsIHelperAppLauncher), getter_AddRefs(mHelperAppLauncher)); - return NS_OK; -} - -#pragma mark - -#pragma mark [EphyDownload::nsIWebProgressListener] - -/* void onStateChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long aStateFlags, in nsresult aStatus); */ -NS_IMETHODIMP -EphyDownload::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, - PRUint32 aStateFlags, nsresult aStatus) -{ - // For a file download via the external helper app service, we will never get a start - // notification. The helper app service has gotten that notification before it created us. - if (!mGotFirstStateChange) { - mIsNetworkTransfer = ((aStateFlags & STATE_IS_NETWORK) != 0); - mGotFirstStateChange = PR_TRUE; - //BroadcastMessage(msg_OnDLStart, this); - } - - if (NS_FAILED(aStatus) && NS_SUCCEEDED(mStatus)) - mStatus = aStatus; - - // We will get this even in the event of a cancel, - if ((aStateFlags & STATE_STOP) && (!mIsNetworkTransfer || (aStateFlags & STATE_IS_NETWORK))) { - if (mWebPersist) { - mWebPersist->SetProgressListener(nsnull); - mWebPersist = nsnull; - } - mHelperAppLauncher = nsnull; - //BroadcastMessage(msg_OnDLComplete, this); - } - - return NS_OK; -} - -/* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */ -NS_IMETHODIMP -EphyDownload::OnProgressChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, - PRInt32 aCurSelfProgress, PRInt32 aMaxSelfProgress, - PRInt32 aCurTotalProgress, PRInt32 aMaxTotalProgress) -{ - if (mUserCanceled) { - if (mHelperAppLauncher) - mHelperAppLauncher->Cancel(); - else if (aRequest) - aRequest->Cancel(NS_BINDING_ABORTED); - mUserCanceled = false; - } - if (aMaxTotalProgress == -1) - mPercentComplete = -1; - else - mPercentComplete = (PRInt32)(((float)aCurTotalProgress / (float)aMaxTotalProgress) * 100.0 + 0.5); - - //MsgOnDLProgressChangeInfo info(this, aCurTotalProgress, aMaxTotalProgress); - // From ProgressListener - PRInt64 now = PR_Now(); - mElapsed = now - mStartTime; - - if ((now - mLastUpdate < mInterval) && - (aMaxTotalProgress != -1) && - (aCurTotalProgress < aMaxTotalProgress)) - { - return NS_OK; - } - mLastUpdate = now; - - - gfloat progress = -1; - if (aMaxTotalProgress > 0) - { - progress = (gfloat)aCurTotalProgress / - (gfloat)aMaxTotalProgress; - } - - /* compute download rate */ - gfloat speed = -1; - PRInt64 currentRate; - if (mElapsed) - { - currentRate = ((PRInt64)(aCurTotalProgress)) * 1000000 / mElapsed; - } - else - { - currentRate = 0; - } - - if (!mIsPaused && currentRate) - { - PRFloat64 currentKRate = ((PRFloat64)currentRate)/1024; - if (currentKRate != mPriorKRate) - { - if (mRateChanges++ == mRateChangeLimit) - { - mPriorKRate = currentKRate; - mRateChanges = 0; - } - else - { - currentKRate = mPriorKRate; - } - } - else - { - mRateChanges = 0; - } - - speed = currentKRate; - } - - /* compute time remaining */ - gint remaining = -1; - if (currentRate && (aMaxTotalProgress > 0)) - { - remaining = (gint)((aMaxTotalProgress - aCurTotalProgress) - /currentRate + 0.5); - } - - //BroadcastMessage(msg_OnDLProgressChange, &info); - // UI Rumba - downloader_view_set_download_progress (mDownloaderView, - mElapsed / 1000000, - remaining, - speed, - aMaxTotalProgress / 1024.0 + 0.5, - aCurTotalProgress / 1024.0 + 0.5, - progress, - (gpointer)this); - - return NS_OK; -} - -/* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */ -NS_IMETHODIMP -EphyDownload::OnLocationChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsIURI *location) -{ - return NS_OK; -} - -/* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */ -NS_IMETHODIMP -EphyDownload::OnStatusChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, - nsresult aStatus, const PRUnichar *aMessage) -{ - return NS_OK; -} - -/* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */ -NS_IMETHODIMP -EphyDownload::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 state) -{ - return NS_OK; -} - -#pragma mark - -#pragma mark [EphyDownload Internal Methods] - -void -EphyDownload::Cancel() -{ - mUserCanceled = true; - // nsWebBrowserPersist does the right thing: After canceling, next time through - // OnStateChange(), aStatus != NS_OK. This isn't the case with nsExternalHelperAppService. - if (!mWebPersist) - mStatus = NS_ERROR_ABORT; -} - -void -EphyDownload::Pause() -{ -} - -void -EphyDownload::Resume() -{ -} - -/*void -EphyDownload::CreateProgressView() -{ - sProgressView = new CMultiDownloadProgress; - ThrowIfNil_(sProgressView); -}*/ - - -//***************************************************************************** -// CHelperAppLauncherDialog -//***************************************************************************** -/*#pragma mark - -#pragma mark [CHelperAppLauncherDialog] - -CHelperAppLauncherDialog::CHelperAppLauncherDialog() -{ -} - -CHelperAppLauncherDialog::~CHelperAppLauncherDialog() -{ -} - -NS_IMPL_ISUPPORTS1(CHelperAppLauncherDialog, nsIHelperAppLauncherDialog)*/ - -/* void show (in nsIHelperAppLauncher aLauncher, in nsISupports aContext, in boolean aForced); */ -/*NS_IMETHODIMP CHelperAppLauncherDialog::Show(nsIHelperAppLauncher *aLauncher, nsISupports *aContext, PRBool aForced) -{ - return aLauncher->SaveToDisk(nsnull, PR_FALSE); -}*/ - -/* nsILocalFile promptForSaveToFile (in nsIHelperAppLauncher aLauncher, in nsISupports aWindowContext, in wstring aDefaultFile, in wstring aSuggestedFileExtension); */ -/*NS_IMETHODIMP CHelperAppLauncherDialog::PromptForSaveToFile(nsIHelperAppLauncher* aLauncher, - nsISupports *aWindowContext, - const PRUnichar *aDefaultFile, - const PRUnichar *aSuggestedFileExtension, - nsILocalFile **_retval) -{ - NS_ENSURE_ARG_POINTER(_retval); - *_retval = nsnull; - - static bool sFirstTime = true; - UNavServicesDialogs::LFileDesignator designator; - - if (sFirstTime) { - // Get the default download folder and point Nav Sevices to it. - nsCOMPtr<nsIFile> defaultDownloadDir; - NS_GetSpecialDirectory(NS_MAC_DEFAULT_DOWNLOAD_DIR, getter_AddRefs(defaultDownloadDir)); - if (defaultDownloadDir) { - nsCOMPtr<nsILocalFileMac> macDir(do_QueryInterface(defaultDownloadDir)); - FSSpec defaultDownloadSpec; - if (NS_SUCCEEDED(macDir->GetFSSpec(&defaultDownloadSpec))) - designator.SetDefaultLocation(defaultDownloadSpec, true); - } - sFirstTime = false; - } - - Str255 defaultName; - CPlatformUCSConversion::GetInstance()->UCSToPlatform(nsDependentString(aDefaultFile), defaultName); - bool result = designator.AskDesignateFile(defaultName); - - // After the dialog is dismissed, process all activation an update events right away. - // The save dialog code calls UDesktop::Activate after dismissing the dialog. All that - // does is activate the now frontmost LWindow which was behind the dialog. It does not - // remove the activate event from the queue. If that event is not processed and removed - // before we show the progress window, bad things happen. Specifically, the progress - // dialog will show in front and then, shortly thereafter, the window which was behind this save - // dialog will be moved to the front. - - if (LEventDispatcher::GetCurrentEventDispatcher()) { // Can this ever be NULL? - EventRecord theEvent; - while (::WaitNextEvent(updateMask | activMask, &theEvent, 0, nil)) - LEventDispatcher::GetCurrentEventDispatcher()->DispatchEvent(theEvent); - } - - if (result) { - FSSpec destSpec; - designator.GetFileSpec(destSpec); - nsCOMPtr<nsILocalFileMac> destFile; - NS_NewLocalFileWithFSSpec(&destSpec, PR_TRUE, getter_AddRefs(destFile)); - if (!destFile) - return NS_ERROR_FAILURE; - *_retval = destFile; - NS_ADDREF(*_retval); - return NS_OK; - } - else - return NS_ERROR_ABORT; -}*/ - diff --git a/embed/mozilla/EphyHeaderSniffer.cpp b/embed/mozilla/EphyHeaderSniffer.cpp index ea5df90a0..fe0e6ac4a 100644 --- a/embed/mozilla/EphyHeaderSniffer.cpp +++ b/embed/mozilla/EphyHeaderSniffer.cpp @@ -36,11 +36,8 @@ * * ***** END LICENSE BLOCK ***** */ +#include "MozDownload.h" #include "EphyHeaderSniffer.h" -//#include "UMacUnicode.h" - -//#include "UCustomNavServicesDialogs.h" - #include "netCore.h" #include "nsIChannel.h" @@ -52,21 +49,20 @@ #include "nsIMIMEInfo.h" #include "nsIDOMHTMLDocument.h" #include "nsIDownload.h" -//#include "nsILocalFileMac.h" const char* const persistContractID = "@mozilla.org/embedding/browser/nsWebBrowserPersist;1"; -EphyHeaderSniffer::EphyHeaderSniffer(nsIWebBrowserPersist* aPersist, nsIFile* aFile, nsIURI* aURL, - nsIDOMDocument* aDocument, nsIInputStream* aPostData, - const nsAString& aSuggestedFilename, PRBool aBypassCache, ESaveFormat aSaveFormat) +EphyHeaderSniffer::EphyHeaderSniffer(nsIWebBrowserPersist* aPersist, MozillaEmbedPersist *aEmbedPersist, + nsIFile* aFile, nsIURI* aURL, nsIDOMDocument* aDocument, nsIInputStream* aPostData, + const nsAString& aSuggestedFilename, PRBool aBypassCache) : mPersist(aPersist) +, mEmbedPersist(aEmbedPersist) , mTmpFile(aFile) , mURL(aURL) , mDocument(aDocument) , mPostData(aPostData) , mDefaultFilename(aSuggestedFilename) , mBypassCache(aBypassCache) -, mSaveFormat(aSaveFormat) { } @@ -76,8 +72,6 @@ EphyHeaderSniffer::~EphyHeaderSniffer() NS_IMPL_ISUPPORTS1(EphyHeaderSniffer, nsIWebProgressListener) -#pragma mark - - // Implementation of nsIWebProgressListener /* void onStateChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aStateFlags, in unsigned long aStatus); */ NS_IMETHODIMP @@ -109,7 +103,7 @@ EphyHeaderSniffer::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequ if (exists) mTmpFile->Remove(PR_FALSE); - rv = PerformSave(origURI, mSaveFormat); + rv = PerformSave(origURI); if (NS_FAILED(rv)) { // put up some UI @@ -147,7 +141,7 @@ EphyHeaderSniffer::OnStatusChange(nsIWebProgress *aWebProgress, nsresult aStatus, const PRUnichar *aMessage) { - return NS_OK; + return NS_OK; } /* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */ @@ -157,225 +151,25 @@ EphyHeaderSniffer::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aR return NS_OK; } -#pragma mark - - -static ESaveFormat SaveFormatFromPrefValue(PRInt32 inPrefValue) -{ - switch (inPrefValue) - { - case 0: return eSaveFormatHTMLComplete; - default: // fall through - case 1: return eSaveFormatHTML; - case 2: return eSaveFormatPlainText; - } -} - -static PRInt32 PrefValueFromSaveFormat(ESaveFormat inSaveFormat) -{ - switch (inSaveFormat) - { - case eSaveFormatPlainText: return 2; - default: // fall through - case eSaveFormatHTML: return 1; - case eSaveFormatHTMLComplete: return 0; - } -} - -nsresult EphyHeaderSniffer::PerformSave(nsIURI* inOriginalURI, const ESaveFormat inSaveFormat) +nsresult EphyHeaderSniffer::PerformSave(nsIURI* inOriginalURI) { - nsresult rv; - // Are we an HTML document? If so, we will want to append an accessory view to - // the save dialog to provide the user with the option of doing a complete - // save vs. a single file save. - PRBool isHTML = (mDocument && mContentType.Equals("text/html") || - mContentType.Equals("text/xml") || - mContentType.Equals("application/xhtml+xml")); - - // Next find out the directory that we should start in. - nsCOMPtr<nsIPrefService> prefs(do_GetService("@mozilla.org/preferences-service;1", &rv)); - if (!prefs) - return rv; - nsCOMPtr<nsIPrefBranch> dirBranch; - prefs->GetBranch("browser.download.", getter_AddRefs(dirBranch)); - PRInt32 filterIndex = 0; - if (inSaveFormat != eSaveFormatUnspecified) { - filterIndex = PrefValueFromSaveFormat(inSaveFormat); - } - else if (dirBranch) { - nsresult rv = dirBranch->GetIntPref("save_converter_index", &filterIndex); - if (NS_FAILED(rv)) - filterIndex = 0; - } - - // We need to figure out what file name to use. -/* nsAutoString defaultFileName; - if (!mContentDisposition.IsEmpty()) { - // (1) Use the HTTP header suggestion. - PRInt32 index = mContentDisposition.Find("filename="); - if (index >= 0) { - // Take the substring following the prefix. - index += 9; - nsCAutoString filename; - mContentDisposition.Right(filename, mContentDisposition.Length() - index); - defaultFileName = NS_ConvertUTF8toUCS2(filename); - } - } - - if (defaultFileName.IsEmpty()) { - nsCOMPtr<nsIURL> url(do_QueryInterface(mURL)); - if (url) { - nsCAutoString fileNameCString; - url->GetFileName(fileNameCString); // (2) For file URLs, use the file name. - defaultFileName = NS_ConvertUTF8toUCS2(fileNameCString); - } - } - - if (defaultFileName.IsEmpty() && mDocument && isHTML) { - nsCOMPtr<nsIDOMHTMLDocument> htmlDoc(do_QueryInterface(mDocument)); - if (htmlDoc) - htmlDoc->GetTitle(defaultFileName); // (3) Use the title of the document. - } - - if (defaultFileName.IsEmpty()) { - // (4) Use the caller provided name. - defaultFileName = mDefaultFilename; - } - - if (defaultFileName.IsEmpty() && mURL) { - // (5) Use the host. - nsCAutoString hostName; - mURL->GetHost(hostName); - defaultFileName = NS_ConvertUTF8toUCS2(hostName); - } - - // One last case to handle about:blank and other fruity untitled pages. - if (defaultFileName.IsEmpty()) - defaultFileName.AssignWithConversion("untitled"); - - // Validate the file name to ensure legality. - for (PRUint32 i = 0; i < defaultFileName.Length(); i++) - if (defaultFileName[i] == ':' || defaultFileName[i] == '/') - defaultFileName.SetCharAt(i, PRUnichar(' ')); - - // Make sure the appropriate extension is appended to the suggested file name. - nsCOMPtr<nsIURI> fileURI(do_CreateInstance("@mozilla.org/network/standard-url;1")); - nsCOMPtr<nsIURL> fileURL(do_QueryInterface(fileURI, &rv)); - if (!fileURL) - return rv; - - fileURL->SetFilePath(NS_ConvertUCS2toUTF8(defaultFileName)); - - nsCAutoString fileExtension; - fileURL->GetFileExtension(fileExtension); - - PRBool setExtension = PR_FALSE; - if (mContentType.Equals("text/html")) { - if (fileExtension.IsEmpty() || (!fileExtension.Equals("htm") && !fileExtension.Equals("html"))) { - defaultFileName.AppendWithConversion(".html"); - setExtension = PR_TRUE; - } - } - - if (!setExtension && fileExtension.IsEmpty()) { - nsCOMPtr<nsIMIMEService> mimeService(do_GetService("@mozilla.org/mime;1", &rv)); - if (!mimeService) - return rv; - nsCOMPtr<nsIMIMEInfo> mimeInfo; - rv = mimeService->GetFromTypeAndExtension(mContentType.get(), nsnull, getter_AddRefs(mimeInfo)); - if (!mimeInfo) - return rv; - - nsCOMPtr<nsIUTF8StringEnumerator> extensions; - mimeInfo->GetFileExtensions(getter_AddRefs(extensions)); - - PRBool hasMore; - extensions->HasMore(&hasMore); - if (hasMore) { - nsCAutoString ext; - extensions->GetNext(ext); - defaultFileName.Append(PRUnichar('.')); - defaultFileName.Append(NS_ConvertUTF8toUCS2(ext)); - } - } - - // Now it's time to pose the save dialog. - FSSpec destFileSpec; - bool isReplacing = false; - - { - Str255 defaultName; - bool result; - - CPlatformUCSConversion::GetInstance()->UCSToPlatform(defaultFileName, defaultName); -#ifndef XP_MACOSX - char tempBuf1[256], tempBuf2[64]; - ::CopyPascalStringToC(defaultName, tempBuf1); - ::CopyCStringToPascal(NS_TruncNodeName(tempBuf1, tempBuf2), defaultName); -#endif - if (isHTML) { - ESaveFormat saveFormat = SaveFormatFromPrefValue(filterIndex); - UNavServicesDialogs::LCustomFileDesignator customDesignator; - result = customDesignator.AskDesignateFile(defaultName, saveFormat); - if (!result) - return NS_OK; // user canceled - filterIndex = PrefValueFromSaveFormat(saveFormat); - customDesignator.GetFileSpec(destFileSpec); - isReplacing = customDesignator.IsReplacing(); - } - else { - UNavServicesDialogs::LFileDesignator stdDesignator; - result = stdDesignator.AskDesignateFile(defaultName); - if (!result) - return NS_OK; // user canceled - stdDesignator.GetFileSpec(destFileSpec); - isReplacing = stdDesignator.IsReplacing(); - } - - // After the dialog is dismissed, process all activation an update events right away. - // The save dialog code calls UDesktop::Activate after dismissing the dialog. All that - // does is activate the now frontmost LWindow which was behind the dialog. It does not - // remove the activate event from the queue. If that event is not processed and removed - // before we show the progress window, bad things happen. Specifically, the progress - // dialog will show in front and then, shortly thereafter, the window which was behind this save - // dialog will be moved to the front. - - if (LEventDispatcher::GetCurrentEventDispatcher()) { // Can this ever be NULL? - EventRecord theEvent; - while (::WaitNextEvent(updateMask | activMask, &theEvent, 0, nil)) - LEventDispatcher::GetCurrentEventDispatcher()->DispatchEvent(theEvent); - } - } - - // only save the pref if the frontend didn't specify a format - if (inSaveFormat == eSaveFormatUnspecified && isHTML) - dirBranch->SetIntPref("save_converter_index", filterIndex); - - nsCOMPtr<nsILocalFile> destFile; - - rv = NS_NewLocalFileWithFSSpec(&destFileSpec, PR_TRUE, getter_AddRefs(destFile)); - if (NS_FAILED(rv)) - return rv; - - if (isReplacing) { - PRBool exists; - rv = destFile->Exists(&exists); - if (NS_SUCCEEDED(rv) && exists) - rv = destFile->Remove(PR_TRUE); - if (NS_FAILED(rv)) - return rv; - } - - // if the user chose plain text, set the content type - if (isHTML && filterIndex == 2) - mContentType = "text/plain"; - - nsCOMPtr<nsISupports> sourceData; - if (isHTML && filterIndex != 1) - sourceData = do_QueryInterface(mDocument); // HTML complete - else - sourceData = do_QueryInterface(mURL); // HTML or text only + nsresult rv; + + PRBool isHTML = (mDocument && mContentType.Equals("text/html") || + mContentType.Equals("text/xml") || + mContentType.Equals("application/xhtml+xml")); + + nsCOMPtr<nsILocalFile> file; + rv = NS_NewLocalFile(mDefaultFilename, PR_TRUE, getter_AddRefs(file)); + if (NS_FAILED(rv) || !file) return G_FAILED; + + nsCOMPtr<nsISupports> sourceData; + if (isHTML) + sourceData = do_QueryInterface(mDocument); + else + sourceData = do_QueryInterface(mURL); - return InitiateDownload(sourceData, destFile, inOriginalURI);*/ + return InitiateDownload(sourceData, file, inOriginalURI); } // inOriginalURI is always a URI. inSourceData can be an nsIURI or an nsIDOMDocument, depending @@ -394,11 +188,12 @@ nsresult EphyHeaderSniffer::InitiateDownload(nsISupports* inSourceData, nsILocal nsAutoString fileDisplayName; inDestFile->GetLeafName(fileDisplayName); - nsCOMPtr<nsIDownload> downloader = do_CreateInstance(NS_DOWNLOAD_CONTRACTID); + MozDownload *downloader = new MozDownload (); // dlListener attaches to its progress dialog here, which gains ownership - rv = downloader->Init(inOriginalURI, inDestFile, fileDisplayName.get(), nsnull, timeNow, webPersist); + rv = downloader->InitForEmbed (inOriginalURI, inDestFile, fileDisplayName.get(), + nsnull, timeNow, webPersist, mEmbedPersist); if (NS_FAILED(rv)) return rv; - + PRInt32 flags = nsIWebBrowserPersist::PERSIST_FLAGS_NO_CONVERSION | nsIWebBrowserPersist::PERSIST_FLAGS_REPLACE_EXISTING_FILES; if (mBypassCache) diff --git a/embed/mozilla/EphyHeaderSniffer.h b/embed/mozilla/EphyHeaderSniffer.h index 8ef6afa01..9124cfa16 100644 --- a/embed/mozilla/EphyHeaderSniffer.h +++ b/embed/mozilla/EphyHeaderSniffer.h @@ -36,7 +36,7 @@ * * ***** END LICENSE BLOCK ***** */ - #pragma once +#include "mozilla-embed-persist.h" #include "nsString.h" #include "nsIWebProgressListener.h" @@ -46,23 +46,14 @@ #include "nsIInputStream.h" #include "nsIDOMDocument.h" - -typedef enum -{ - eSaveFormatUnspecified = 0, - eSaveFormatPlainText, // items should match the MENU in resources - eSaveFormatHTML, - eSaveFormatHTMLComplete -} ESaveFormat; - // Implementation of a header sniffer class that is used when saving Web pages and images. class EphyHeaderSniffer : public nsIWebProgressListener { public: - EphyHeaderSniffer(nsIWebBrowserPersist* aPersist, nsIFile* aFile, nsIURI* aURL, - nsIDOMDocument* aDocument, nsIInputStream* aPostData, - const nsAString& aSuggestedFilename, PRBool aBypassCache, - ESaveFormat aSaveFormat = eSaveFormatUnspecified); + EphyHeaderSniffer(nsIWebBrowserPersist* aPersist, MozillaEmbedPersist *aEmbedPersist, + nsIFile* aFile, nsIURI* aURL, + nsIDOMDocument* aDocument, nsIInputStream* aPostData, + const nsAString& aSuggestedFilename, PRBool aBypassCache); virtual ~EphyHeaderSniffer(); NS_DECL_ISUPPORTS @@ -70,19 +61,19 @@ public: protected: - nsresult PerformSave(nsIURI* inOriginalURI, const ESaveFormat inSaveFormat); + nsresult PerformSave(nsIURI* inOriginalURI); nsresult InitiateDownload(nsISupports* inSourceData, nsILocalFile* inDestFile, nsIURI* inOriginalURI); private: nsIWebBrowserPersist* mPersist; // Weak. It owns us as a listener. + MozillaEmbedPersist *mEmbedPersist; nsCOMPtr<nsIFile> mTmpFile; nsCOMPtr<nsIURI> mURL; nsCOMPtr<nsIDOMDocument> mDocument; nsCOMPtr<nsIInputStream> mPostData; nsString mDefaultFilename; PRBool mBypassCache; - ESaveFormat mSaveFormat; nsCString mContentType; nsCString mContentDisposition; }; diff --git a/embed/mozilla/EphyWrapper.cpp b/embed/mozilla/EphyWrapper.cpp index a8492d055..71194438f 100644 --- a/embed/mozilla/EphyWrapper.cpp +++ b/embed/mozilla/EphyWrapper.cpp @@ -24,7 +24,7 @@ #include "EphyWrapper.h" #include "GlobalHistory.h" -#include "ProgressListener.h" +//#include "ProgressListener.h" #include "ephy-embed.h" #include "ephy-string.h" diff --git a/embed/mozilla/EphyWrapper.h b/embed/mozilla/EphyWrapper.h index 32cfe5efd..cfedf6ccc 100644 --- a/embed/mozilla/EphyWrapper.h +++ b/embed/mozilla/EphyWrapper.h @@ -22,7 +22,7 @@ #define EPHY_WRAPPER_H #include "nsIDocShell.h" -#include "ProgressListener.h" +//#include "ProgressListener.h" #include "nsIWebNavigation.h" #include "nsIWebPageDescriptor.h" #include "nsISHistory.h" diff --git a/embed/mozilla/GlobalHistory.h b/embed/mozilla/GlobalHistory.h index f1d810f6a..4315509af 100644 --- a/embed/mozilla/GlobalHistory.h +++ b/embed/mozilla/GlobalHistory.h @@ -22,6 +22,7 @@ #include "nsError.h" #include "nsIGlobalHistory.h" #include "nsIBrowserHistory.h" +#include "ephy-history.h" #define EPHY_GLOBALHISTORY_CLASSNAME \ "Epiphany's Global History Implementation" diff --git a/embed/mozilla/Makefile.am b/embed/mozilla/Makefile.am index b07ffedef..22ef72829 100644 --- a/embed/mozilla/Makefile.am +++ b/embed/mozilla/Makefile.am @@ -37,7 +37,6 @@ INCLUDES = \ $(EPIPHANY_DEPENDENCY_CFLAGS) \ -DG_DISABLE_DEPRECATED \ -DGDK_DISABLE_DEPRECATED \ - -DGTK_DISABLE_DEPRECATED \ -DGDK_PIXBUF_DISABLE_DEPRECATED \ -DGNOME_DISABLE_DEPRECATED \ -DSHARE_DIR=\"$(pkgdatadir)\" \ @@ -56,6 +55,8 @@ libephymozillaembed_la_SOURCES = \ EphyAboutRedirector.h \ EphyEventListener.cpp \ EphyEventListener.h \ + EphyHeaderSniffer.cpp \ + EphyHeaderSniffer.h \ EphyWrapper.cpp \ EphyWrapper.h \ EventContext.cpp \ @@ -70,14 +71,16 @@ libephymozillaembed_la_SOURCES = \ GlobalHistory.h \ GtkNSSDialogs.cpp \ GtkNSSDialogs.h \ + MozDownload.cpp \ + MozDownload.h \ MozillaPrivate.cpp \ MozillaPrivate.h \ MozRegisterComponents.cpp \ MozRegisterComponents.h \ PrintingPromptService.cpp \ PrintingPromptService.h \ - ProgressListener.cpp \ - ProgressListener.h \ + mozilla-download.cpp \ + mozilla-download.h \ mozilla-embed.cpp \ mozilla-embed.h \ mozilla-embed-persist.cpp \ diff --git a/embed/mozilla/MozDownload.cpp b/embed/mozilla/MozDownload.cpp new file mode 100644 index 000000000..ce8a2254d --- /dev/null +++ b/embed/mozilla/MozDownload.cpp @@ -0,0 +1,377 @@ +/* -*- 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) 2002 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Conrad Carlen <ccarlen@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 "MozDownload.h" +#include "mozilla-download.h" + +#include "nsIExternalHelperAppService.h" +#include "nsDirectoryServiceDefs.h" +#include "nsDirectoryServiceUtils.h" +#include "nsIRequest.h" +#include "netCore.h" +#include "nsIObserver.h" + +//***************************************************************************** +// MozDownload +//***************************************************************************** + +MozDownload::MozDownload() : + mGotFirstStateChange(false), mIsNetworkTransfer(false), + mUserCanceled(false), + mStatus(NS_OK), + mEmbedPersist(nsnull), + mDownloadState(EPHY_DOWNLOAD_DOWNLOADING) +{ +} + +MozDownload::~MozDownload() +{ +} + +NS_IMPL_ISUPPORTS2(MozDownload, nsIDownload, nsIWebProgressListener) + +NS_IMETHODIMP +MozDownload::InitForEmbed (nsIURI *aSource, nsILocalFile *aTarget, const PRUnichar *aDisplayName, + nsIMIMEInfo *aMIMEInfo, PRInt64 startTime, nsIWebBrowserPersist *aPersist, + MozillaEmbedPersist *aEmbedPersist) +{ + mEmbedPersist = aEmbedPersist; + return Init (aSource, aTarget, aDisplayName, aMIMEInfo, startTime, aPersist); +} + +/* void init (in nsIURI aSource, in nsILocalFile aTarget, in wstring aDisplayName, in nsIMIMEInfo aMIMEInfo, in long long startTime, in nsIWebBrowserPersist aPersist); */ +NS_IMETHODIMP +MozDownload::Init(nsIURI *aSource, nsILocalFile *aTarget, const PRUnichar *aDisplayName, + nsIMIMEInfo *aMIMEInfo, PRInt64 startTime, nsIWebBrowserPersist *aPersist) +{ + PRBool addToView = PR_TRUE; + + if (mEmbedPersist) + { + EmbedPersistFlags flags; + + ephy_embed_persist_get_flags (EPHY_EMBED_PERSIST (mEmbedPersist), &flags); + + addToView = !(flags & EMBED_PERSIST_NO_VIEW); + } + + mSource = aSource; + mDestination = aTarget; + mStartTime = startTime; + mPercentComplete = 0; + mInterval = 4000; // in ms + mLastUpdate = mStartTime; + + if (aPersist) + { + mWebPersist = aPersist; + aPersist->SetProgressListener(this); + } + + if (addToView) + { + DownloaderView *dview; + dview = EPHY_DOWNLOADER_VIEW (ephy_embed_shell_get_downloader_view + (embed_shell)); + mEphyDownload = mozilla_download_new (); + MOZILLA_DOWNLOAD (mEphyDownload)->moz_download = this; + downloader_view_add_download (dview, mEphyDownload); + } + else + { + mEphyDownload = nsnull; + } + + return NS_OK; +} + +/* readonly attribute nsIURI source; */ +NS_IMETHODIMP +MozDownload::GetSource(nsIURI * *aSource) +{ + NS_ENSURE_ARG_POINTER(aSource); + NS_IF_ADDREF(*aSource = mSource); + return NS_OK; +} + +/* readonly attribute nsILocalFile target; */ +NS_IMETHODIMP +MozDownload::GetTarget(nsILocalFile * *aTarget) +{ + NS_ENSURE_ARG_POINTER(aTarget); + NS_IF_ADDREF(*aTarget = mDestination); + return NS_OK; +} + +/* readonly attribute nsIWebBrowserPersist persist; */ +NS_IMETHODIMP +MozDownload::GetPersist(nsIWebBrowserPersist * *aPersist) +{ + NS_ENSURE_ARG_POINTER(aPersist); + NS_IF_ADDREF(*aPersist = mWebPersist); + return NS_OK; +} + +/* readonly attribute PRInt32 percentComplete; */ +NS_IMETHODIMP +MozDownload::GetPercentComplete(PRInt32 *aPercentComplete) +{ + NS_ENSURE_ARG_POINTER(aPercentComplete); + *aPercentComplete = mPercentComplete; + return NS_OK; +} + +NS_IMETHODIMP +MozDownload::GetTotalProgress(PRInt32 *aTotalProgress) +{ + NS_ENSURE_ARG_POINTER(aTotalProgress); + *aTotalProgress = mTotalProgress; + return NS_OK; +} + +NS_IMETHODIMP +MozDownload::GetCurrentProgress(PRInt32 *aCurrentProgress) +{ + NS_ENSURE_ARG_POINTER(aCurrentProgress); + *aCurrentProgress = mCurrentProgress; + return NS_OK; +} + +NS_IMETHODIMP +MozDownload::GetState(EphyDownloadState *aDownloadState) +{ + NS_ENSURE_ARG_POINTER(aDownloadState); + *aDownloadState = mDownloadState; + return NS_OK; +} + +/* attribute wstring displayName; */ +NS_IMETHODIMP +MozDownload::GetDisplayName(PRUnichar * *aDisplayName) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +MozDownload::SetDisplayName(const PRUnichar * aDisplayName) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +/* readonly attribute long long startTime; */ +NS_IMETHODIMP +MozDownload::GetStartTime(PRInt64 *aStartTime) +{ + NS_ENSURE_ARG_POINTER(aStartTime); + *aStartTime = mStartTime; + return NS_OK; +} + +NS_IMETHODIMP +MozDownload::GetElapsedTime(PRInt64 *aElapsedTime) +{ + NS_ENSURE_ARG_POINTER(aElapsedTime); + *aElapsedTime = PR_Now() - mStartTime; + return NS_OK; +} + +/* readonly attribute nsIMIMEInfo MIMEInfo; */ +NS_IMETHODIMP +MozDownload::GetMIMEInfo(nsIMIMEInfo * *aMIMEInfo) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +/* attribute nsIWebProgressListener listener; */ +NS_IMETHODIMP +MozDownload::GetListener(nsIWebProgressListener * *aListener) +{ + NS_ENSURE_ARG_POINTER(aListener); + NS_IF_ADDREF(*aListener = (nsIWebProgressListener *)this); + return NS_OK; +} + +NS_IMETHODIMP +MozDownload::SetListener(nsIWebProgressListener * aListener) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +/* attribute nsIObserver observer; */ +NS_IMETHODIMP +MozDownload::GetObserver(nsIObserver * *aObserver) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +MozDownload::SetObserver(nsIObserver * aObserver) +{ + if (aObserver) + aObserver->QueryInterface(NS_GET_IID(nsIHelperAppLauncher), getter_AddRefs(mHelperAppLauncher)); + return NS_OK; +} + +/* void onStateChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long aStateFlags, in nsresult aStatus); */ +NS_IMETHODIMP +MozDownload::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, + PRUint32 aStateFlags, nsresult aStatus) +{ + // For a file download via the external helper app service, we will never get a start + // notification. The helper app service has gotten that notification before it created us. + if (!mGotFirstStateChange) { + mIsNetworkTransfer = ((aStateFlags & STATE_IS_NETWORK) != 0); + mGotFirstStateChange = PR_TRUE; + } + + if (NS_FAILED(aStatus) && NS_SUCCEEDED(mStatus)) + mStatus = aStatus; + + // We will get this even in the event of a cancel, + if ((aStateFlags & STATE_STOP) && (!mIsNetworkTransfer || (aStateFlags & STATE_IS_NETWORK))) { + /* Keep us alive */ + nsCOMPtr<nsIDownload> kungFuDeathGrip(this); + + mDownloadState = NS_SUCCEEDED (aStatus) ? EPHY_DOWNLOAD_COMPLETED : EPHY_DOWNLOAD_FAILED; + if (mEphyDownload) + { + g_signal_emit_by_name (mEphyDownload, "changed"); + } + + if (mWebPersist) + { + mWebPersist->SetProgressListener(nsnull); + mWebPersist = nsnull; + } + mHelperAppLauncher = nsnull; + + if (mEmbedPersist) + { + if (NS_SUCCEEDED (aStatus)) + { + mozilla_embed_persist_completed (mEmbedPersist); + } + else + { + mozilla_embed_persist_cancelled (mEmbedPersist); + } + } + } + + return NS_OK; +} + +/* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */ +NS_IMETHODIMP +MozDownload::OnProgressChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, + PRInt32 aCurSelfProgress, PRInt32 aMaxSelfProgress, + PRInt32 aCurTotalProgress, PRInt32 aMaxTotalProgress) +{ + PRInt64 now = PR_Now (); + + if ((now - mLastUpdate < mInterval) && + (aMaxTotalProgress != -1) && + (aCurTotalProgress < aMaxTotalProgress)) + return NS_OK; + + mLastUpdate = now; + + if (mUserCanceled) { + if (mHelperAppLauncher) + mHelperAppLauncher->Cancel(); + else if (aRequest) + aRequest->Cancel(NS_BINDING_ABORTED); + mUserCanceled = false; + } + if (aMaxTotalProgress == -1) + mPercentComplete = -1; + else + mPercentComplete = (PRInt32)(((float)aCurTotalProgress / (float)aMaxTotalProgress) * 100.0 + 0.5); + + mTotalProgress = aMaxTotalProgress; + mCurrentProgress = aCurTotalProgress; + + if (mEphyDownload) + { + g_signal_emit_by_name (mEphyDownload, "changed"); + } + + return NS_OK; +} + +/* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */ +NS_IMETHODIMP +MozDownload::OnLocationChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsIURI *location) +{ + return NS_OK; +} + +/* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */ +NS_IMETHODIMP +MozDownload::OnStatusChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, + nsresult aStatus, const PRUnichar *aMessage) +{ + return NS_OK; +} + +/* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */ +NS_IMETHODIMP +MozDownload::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 state) +{ + return NS_OK; +} + +void +MozDownload::Cancel() +{ + mUserCanceled = true; + // nsWebBrowserPersist does the right thing: After canceling, next time through + // OnStateChange(), aStatus != NS_OK. This isn't the case with nsExternalHelperAppService. + if (!mWebPersist) + mStatus = NS_ERROR_ABORT; +} + +void +MozDownload::Pause() +{ +} + +void +MozDownload::Resume() +{ +} diff --git a/embed/mozilla/EphyDownload.h b/embed/mozilla/MozDownload.h index a3abc7067..f2fc8fe4b 100644 --- a/embed/mozilla/EphyDownload.h +++ b/embed/mozilla/MozDownload.h @@ -36,10 +36,10 @@ * * ***** END LICENSE BLOCK ***** */ -#ifndef EphyDownload_h__ -#define EphyDownload_h__ -//#pragma once +#ifndef MozDownload_h__ +#define MozDownload_h__ +#include "mozilla-embed-persist.h" #include "nsIDownload.h" #include "nsIWebProgressListener.h" #include "nsIHelperAppLauncherDialog.h" @@ -50,12 +50,11 @@ #include "nsIWebBrowserPersist.h" #include "downloader-view.h" +#include "ephy-download.h" #include "ephy-embed-shell.h" -//class ADownloadProgressView; - //***************************************************************************** -// EphyDownload +// MozDownload // // Holds information used to display a single download in the UI. This object is // created in one of two ways: @@ -67,7 +66,7 @@ // nsIDownload are controlled by the implementation of nsIWebBrowserPersist. //***************************************************************************** -#define EPHY_DOWNLOAD_CID \ +#define MOZ_DOWNLOAD_CID \ { /* d2a2f743-f126-4f1f-1234-d4e50490f112 */ \ 0xd2a2f743, \ 0xf126, \ @@ -75,122 +74,55 @@ {0x12, 0x34, 0xd4, 0xe5, 0x04, 0x90, 0xf1, 0x12} \ } -#define EPHY_DOWNLOAD_CLASSNAME "Ephy's Download Progress Dialog" -//#define EPHY_DOWNLOAD_CONTRACTID "@mozilla.org/progressdialog;1" +#define MOZ_DOWNLOAD_CLASSNAME "Ephy's Download Progress Dialog" -class EphyDownload : public nsIDownload, +class MozDownload : public nsIDownload, public nsIWebProgressListener -// public LBroadcaster { public: - - // Messages we broadcast to listeners. - enum { - msg_OnDLStart = 57723, // param is EphyDownload* - msg_OnDLComplete, // param is EphyDownload* - msg_OnDLProgressChange // param is MsgOnDLProgressChangeInfo* - }; - -/* struct MsgOnDLProgressChangeInfo - { - MsgOnDLProgressChangeInfo(EphyDownload* broadcaster, PRInt32 curProgress, PRInt32 maxProgress) : - mBroadcaster(broadcaster), mCurProgress(curProgress), mMaxProgress(maxProgress) - { } - - EphyDownload *mBroadcaster; - PRInt32 mCurProgress, mMaxProgress; - };*/ - - EphyDownload(); - virtual ~EphyDownload(); + MozDownload(); + virtual ~MozDownload(); NS_DECL_ISUPPORTS NS_DECL_NSIDOWNLOAD NS_DECL_NSIWEBPROGRESSLISTENER - + virtual void Cancel(); virtual void Pause(); virtual void Resume(); - virtual void GetStatus(nsresult& aStatus) - { aStatus = mStatus; } -//protected: - // void EnsureProgressView() - // { - // if (!sProgressView) - // CreateProgressView(); - // } - // virtual void CreateProgressView(); - // sProgressView is a singleton. This will only be called once. - + nsresult GetState (EphyDownloadState *aDownloadState); + nsresult GetCurrentProgress (PRInt32 *aCurrentProgress); + nsresult GetTotalProgress (PRInt32 *aTProgress); + nsresult GetElapsedTime (PRInt64 *aTProgress); + nsresult InitForEmbed (nsIURI *aSource, nsILocalFile *aTarget, + const PRUnichar *aDisplayName, nsIMIMEInfo *aMIMEInfo, + PRInt64 startTime, nsIWebBrowserPersist *aPersist, + MozillaEmbedPersist *aEmbedPersist); + protected: nsCOMPtr<nsIURI> mSource; nsCOMPtr<nsILocalFile> mDestination; + PRInt64 mLastUpdate; PRInt64 mStartTime; PRInt64 mElapsed; + PRInt32 mInterval; PRInt32 mPercentComplete; - + PRInt32 mTotalProgress; + PRInt32 mCurrentProgress; + bool mGotFirstStateChange, mIsNetworkTransfer; bool mUserCanceled; - bool mIsPaused; nsresult mStatus; // These two are mutually exclusive. nsCOMPtr<nsIWebBrowserPersist> mWebPersist; nsCOMPtr<nsIHelperAppLauncher> mHelperAppLauncher; - - PRFloat64 mPriorKRate; - PRInt32 mRateChanges; - PRInt32 mRateChangeLimit; - PRInt64 mLastUpdate; - PRInt32 mInterval; + + EphyDownload *mEphyDownload; DownloaderView *mDownloaderView; - // static ADownloadProgressView *sProgressView; + MozillaEmbedPersist *mEmbedPersist; + EphyDownloadState mDownloadState; }; -//***************************************************************************** -// CHelperAppLauncherDialog -// -// The implementation of nsIExternalHelperAppService in Gecko creates one of -// these at the beginning of the download and calls its Show() method. Typically, -// this will create a non-modal dialog in which the user can decide whether to -// save the file to disk or open it with an application. This implementation -// just saves the file to disk unconditionally. The user can decide what they -// wish to do with the download from the progress dialog. -//***************************************************************************** - -/*class CHelperAppLauncherDialog : public nsIHelperAppLauncherDialog -{ -public: - CHelperAppLauncherDialog(); - virtual ~CHelperAppLauncherDialog(); - - NS_DECL_ISUPPORTS - NS_DECL_NSIHELPERAPPLAUNCHERDIALOG - -protected: - -};*/ - - -//***************************************************************************** -// ADownloadProgressView -// -// An abstract class which handles the display and interaction with a download. -// Typically, it presents a progress dialog. -//***************************************************************************** - -/*class ADownloadProgressView -{ - friend class EphyDownload; - - virtual void AddDownloadItem(EphyDownload *aDownloadItem) = 0; - // A download is beginning. Initialize the UI for this download. - // Throughout the download process, the EphyDownload will broadcast - // status messages. The UI needs to call LBroadcaster::AddListener() - // on the EphyDownload at this point in order to get the messages. - -};*/ - - -#endif // EphyDownload_h__ +#endif // MozDownload_h__ diff --git a/embed/mozilla/MozRegisterComponents.cpp b/embed/mozilla/MozRegisterComponents.cpp index 29079aff2..ee2ac999b 100644 --- a/embed/mozilla/MozRegisterComponents.cpp +++ b/embed/mozilla/MozRegisterComponents.cpp @@ -25,7 +25,7 @@ #include "GlobalHistory.h" #include "ExternalProtocolHandlers.h" #include "PrintingPromptService.h" -#include "ProgressListener.h" +#include "MozDownload.h" #include "ExternalProtocolService.h" #include "EphyAboutRedirector.h" @@ -41,7 +41,7 @@ #include <glib.h> NS_GENERIC_FACTORY_CONSTRUCTOR(EphyAboutRedirector) -NS_GENERIC_FACTORY_CONSTRUCTOR(GProgressListener) +NS_GENERIC_FACTORY_CONSTRUCTOR(MozDownload) NS_GENERIC_FACTORY_CONSTRUCTOR(GFilePicker) NS_GENERIC_FACTORY_CONSTRUCTOR(GContentHandler) NS_GENERIC_FACTORY_CONSTRUCTOR(MozGlobalHistory) @@ -63,16 +63,10 @@ static const nsModuleComponentInfo sAppComps[] = { GExternalProtocolServiceConstructor }, { - G_PROGRESSDIALOG_CLASSNAME, - G_PROGRESSDIALOG_CID, - G_PROGRESSDIALOG_CONTRACTID, - GProgressListenerConstructor - }, - { - G_PROGRESSDIALOG_CLASSNAME, - G_PROGRESSDIALOG_CID, + MOZ_DOWNLOAD_CLASSNAME, + MOZ_DOWNLOAD_CID, NS_DOWNLOAD_CONTRACTID, - GProgressListenerConstructor + MozDownloadConstructor }, { G_FILEPICKER_CLASSNAME, diff --git a/embed/mozilla/ProgressListener.cpp b/embed/mozilla/ProgressListener.cpp deleted file mode 100644 index 433b2234c..000000000 --- a/embed/mozilla/ProgressListener.cpp +++ /dev/null @@ -1,648 +0,0 @@ -/* - * Copyright (C) 2001 Philip Langdale, Matthew Aubury - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * $Id$ - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "ProgressListener.h" -#include "ephy-file-helpers.h" -#include "downloader-view.h" -#include "mozilla-embed-persist.h" -#include "nsXPIDLString.h" -#include "nsCOMPtr.h" - -static void -download_remove_cb (DownloaderView *dv, GProgressListener *Changed, GProgressListener *Progress); -static void -download_resume_cb (DownloaderView *dv, GProgressListener *Changed, GProgressListener *Progress); -static void -download_pause_cb (DownloaderView *dv, GProgressListener *Changed, GProgressListener *Progress); - -NS_IMPL_ISUPPORTS4 (GProgressListener, nsIDownload, nsIWebProgressListener, - nsIProgressDialog, nsISupportsWeakReference) - -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- - -GProgressListener::GProgressListener () : mLauncher(nsnull), - mPersist(nsnull), - mHandler(nsnull), - mObserver(nsnull), - mMIMEInfo(nsnull), - mPercentComplete(0) -{ - NS_INIT_ISUPPORTS (); -} - -GProgressListener::~GProgressListener () -{ - /* destructor code */ -} - -NS_METHOD GProgressListener::InitForPersist (nsIWebBrowserPersist *aPersist, - nsIDOMWindow *aParent, - nsIURI *aURI, - nsIFile *aFile, - DownloadAction aAction, - EphyEmbedPersist *ephyPersist, - PRBool Dialog, - PRInt64 aTimeDownloadStarted) -{ - nsresult rv; - /* fill in download details */ - mAction = aAction; - mParent = aParent; - mDialog = Dialog; - mUri = aURI; - mFile = aFile; - mPersist = aPersist; - mTimeDownloadStarted = aTimeDownloadStarted; - mEphyPersist = ephyPersist; - - /* do remaining init */ - rv = PrivateInit (); - - /* pick up progress messages */ - mPersist->SetProgressListener (this); - - return rv; -} - -NS_METHOD GProgressListener::PrivateInit (void) -{ - mInterval = 500000; /* in microsecs, 0.5s */ - mPriorKRate = 0; - mRateChanges = 0; - mRateChangeLimit = 2; /* only update rate every second */ - mIsPaused = PR_FALSE; - mAbort = PR_FALSE; - mStartTime = PR_Now (); - mLastUpdate = mStartTime; - mElapsed = 0; - - if (mDialog) - { - gchar *filename, *source, *dest; - nsAutoString uTmp; - nsCAutoString cTmp; - nsresult rv; - - rv = mFile->GetLeafName (uTmp); - if (NS_FAILED (rv)) return NS_ERROR_FAILURE; - filename = g_strdup (NS_ConvertUCS2toUTF8(uTmp).get()); - - rv = mFile->GetPath (uTmp); - if (NS_FAILED (rv)) return NS_ERROR_FAILURE; - dest = g_strdup (NS_ConvertUCS2toUTF8(uTmp).get()); - - rv = mUri->GetSpec (cTmp); - if (NS_FAILED (rv)) return NS_ERROR_FAILURE; - source = g_strdup (cTmp.get()); - - mDownloaderView = EPHY_DOWNLOADER_VIEW - (ephy_embed_shell_get_downloader_view (embed_shell)); - downloader_view_add_download (mDownloaderView, filename, source, - dest, (gpointer)this); - g_free (source); - g_free (dest); - g_free (filename); - - g_signal_connect (G_OBJECT (mDownloaderView), - "download_remove", - G_CALLBACK (download_remove_cb), - this); - g_signal_connect (G_OBJECT (mDownloaderView), - "download_pause", - G_CALLBACK (download_pause_cb), - this); - g_signal_connect (G_OBJECT (mDownloaderView), - "download_resume", - G_CALLBACK (download_resume_cb), - this); - } - - return NS_OK; -} - -NS_IMETHODIMP GProgressListener::Init(nsIURI *aSource, - nsILocalFile *aTarget, - const PRUnichar *aDisplayName, - nsIMIMEInfo *aMIMEInfo, - PRInt64 aStartTime, - nsIWebBrowserPersist *aPersist) -{ - mUri = aSource; - mFile = aTarget; - mTimeDownloadStarted = aStartTime; - mStartTime = aStartTime; - mPersist = aPersist; - mMIMEInfo = aMIMEInfo; - mAction = ACTION_NONE; - if(mMIMEInfo) - { - nsMIMEInfoHandleAction mimeAction; - if(NS_SUCCEEDED(mMIMEInfo->GetPreferredAction(&mimeAction))) - { - mAction = (mimeAction == nsIMIMEInfo::useHelperApp) ? - ACTION_SAVEFORHELPER : ACTION_NONE; - } - } - mDialog = TRUE; - - return PrivateInit(); -} - -NS_IMETHODIMP GProgressListener::Open(nsIDOMWindow *aParent) -{ - mParent = aParent; - mDialog = TRUE; - - return NS_OK; -} - -/* attribute long long startTime; */ -NS_IMETHODIMP GProgressListener::GetStartTime(PRInt64 *aStartTime) -{ - *aStartTime = mStartTime; - return NS_OK; -} - -/* attribute nsIURI source; */ -NS_IMETHODIMP GProgressListener::GetSource(nsIURI * *aSource) -{ - NS_IF_ADDREF(*aSource = mUri); - return NS_OK; -} - -/* attribute nsILocalFile target; */ -NS_IMETHODIMP GProgressListener::GetTarget(nsILocalFile * *aTarget) -{ - nsCOMPtr<nsILocalFile> localFile = do_QueryInterface(mFile); - NS_IF_ADDREF(*aTarget = localFile); - return NS_OK; -} - -NS_IMETHODIMP GProgressListener::GetMIMEInfo(nsIMIMEInfo * *aMIMEInfo) -{ - NS_IF_ADDREF(*aMIMEInfo = mMIMEInfo); - return NS_OK; -} - -/* attribute nsIObserver observer; */ -NS_IMETHODIMP GProgressListener::GetObserver(nsIObserver * *aObserver) -{ - NS_IF_ADDREF(*aObserver = mObserver); - return NS_OK; -} -NS_IMETHODIMP GProgressListener::SetObserver(nsIObserver * aObserver) -{ - mObserver = aObserver; - return NS_OK; -} - -/* attribute nsIWebProgressListener listener; */ -NS_IMETHODIMP GProgressListener::GetListener(nsIWebProgressListener * *aListener) -{ - *aListener = nsnull; - return NS_OK; -} -NS_IMETHODIMP GProgressListener::SetListener(nsIWebProgressListener * aListener) -{ - return NS_OK; -} - -/* readonly attribute PRInt32 percentComplete; */ -NS_IMETHODIMP GProgressListener::GetPercentComplete(PRInt32 *aPercentComplete) -{ - return *aPercentComplete = mPercentComplete; -} - -/* attribute wstring displayName; */ -NS_IMETHODIMP GProgressListener::GetDisplayName(PRUnichar * *aDisplayName) -{ - *aDisplayName = nsnull; - return NS_OK; -} -NS_IMETHODIMP GProgressListener::SetDisplayName(const PRUnichar * aDisplayName) -{ - return NS_OK; -} - -NS_IMETHODIMP GProgressListener::GetPersist(nsIWebBrowserPersist * *aPersist) -{ - NS_IF_ADDREF(*aPersist = mPersist); - return NS_OK; -} - -NS_IMETHODIMP GProgressListener::SetDialog(nsIDOMWindow *aDialog) -{ - return NS_OK; -} - -NS_IMETHODIMP GProgressListener::GetDialog(nsIDOMWindow * *aDialog) -{ - *aDialog = nsnull; - return NS_OK; -} - -/* attribute PRBool cancelDownloadOnClose; */ -NS_IMETHODIMP GProgressListener::GetCancelDownloadOnClose(PRBool *aCancelDownloadOnClose) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP GProgressListener::SetCancelDownloadOnClose(PRBool aCancelDownloadOnClose) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP GProgressListener::LaunchHandler (PersistHandlerInfo *handler) -{ - nsresult rv; - nsCOMPtr<nsIExternalHelperAppService> helperService = - do_GetService (NS_EXTERNALHELPERAPPSERVICE_CONTRACTID); - - nsCOMPtr<nsPIExternalAppLauncher> appLauncher = - do_QueryInterface (helperService, &rv); - if (NS_SUCCEEDED(rv)) - { - appLauncher->DeleteTemporaryFileOnExit(mFile); - } - - nsAutoString uFileName; - - mFile->GetPath(uFileName); - const nsACString &cFileName = NS_ConvertUCS2toUTF8(uFileName); - - char *fname = g_strdup(PromiseFlatCString(cFileName).get()); - ephy_file_launch_application (handler->command, - fname, - handler->need_terminal); - g_free (fname); - - return NS_OK; -} - -/* - * void onStateChange (in nsIWebProgress aWebProgress, - * in nsIRequest aRequest, - * in long aStateFlags, - * in unsigned long aStatus); - */ -NS_IMETHODIMP GProgressListener::OnStateChange (nsIWebProgress *aWebProgress, - nsIRequest *aRequest, - PRUint32 aStateFlags, - PRUint32 aStatus) -{ - if (mAbort) return NS_ERROR_FAILURE; - - if (aStateFlags & nsIWebProgressListener::STATE_STOP) - { - - if (mDialog) - { - downloader_view_set_download_status (mDownloaderView, - DOWNLOAD_STATUS_COMPLETED, - (gpointer)this); - } - - switch (mAction) - { - case ACTION_SAVEFORHELPER: - LaunchHelperApp(); - break; - - case ACTION_NONE: - if (mLauncher) - { - mLauncher->CloseProgressWindow (); - } - break; - case ACTION_OBJECT_NOTIFY: - - g_return_val_if_fail (EPHY_IS_EMBED_PERSIST (mEphyPersist), - NS_ERROR_FAILURE); - - PersistHandlerInfo *handler; - - g_object_get (mEphyPersist, - "handler", &handler, - NULL); - - if (handler) - { - LaunchHandler (handler); - } - - mozilla_embed_persist_completed - (MOZILLA_EMBED_PERSIST (mEphyPersist)); - } - } - - return NS_OK; -} - -/* - * void onProgressChange (in nsIWebProgress aWebProgress, - * in nsIRequest aRequest, - * in long aCurSelfProgress, - * in long aMaxSelfProgress, - * in long aCurTotalProgress, - * in long aMaxTotalProgress); - */ -NS_IMETHODIMP GProgressListener:: - OnProgressChange (nsIWebProgress *aWebProgress, - nsIRequest *aRequest, - PRInt32 aCurSelfProgress, - PRInt32 aMaxSelfProgress, - PRInt32 aCurTotalProgress, - PRInt32 aMaxTotalProgress) -{ - if (mAbort) return NS_ERROR_FAILURE; - - /* FIXME maxsize check here */ - - if (!mDialog) return NS_OK; - - mRequest = aRequest; - - PRInt64 now = PR_Now (); - - /* get out if we're updating too quickly */ - if ((now - mLastUpdate < mInterval) && - (aMaxTotalProgress != -1) && - (aCurTotalProgress < aMaxTotalProgress)) - { - return NS_OK; - } - mLastUpdate = now; - - /* compute elapsed time */ - mElapsed = now - mStartTime; - - /* compute size done */ - PRInt32 currentKBytes = (PRInt32)(aCurTotalProgress / 1024.0 + 0.5); - - /* compute total size */ - PRInt32 totalKBytes = (PRInt32)(aMaxTotalProgress / 1024.0 + 0.5); - - /* compute progress value */ - gfloat progress = -1; - if (aMaxTotalProgress > 0) - { - progress = (gfloat)aCurTotalProgress / - (gfloat)aMaxTotalProgress; - } - - /* compute download rate */ - gfloat speed = -1; - PRInt64 currentRate; - if (mElapsed) - { - currentRate = ((PRInt64)(aCurTotalProgress)) * 1000000 / mElapsed; - } - else - { - currentRate = 0; - } - - if (!mIsPaused && currentRate) - { - PRFloat64 currentKRate = ((PRFloat64)currentRate)/1024; - if (currentKRate != mPriorKRate) - { - if (mRateChanges++ == mRateChangeLimit) - { - mPriorKRate = currentKRate; - mRateChanges = 0; - } - else - { - currentKRate = mPriorKRate; - } - } - else - { - mRateChanges = 0; - } - - speed = currentKRate; - } - - /* compute time remaining */ - gint remaining = -1; - if (currentRate && (aMaxTotalProgress > 0)) - { - remaining = (gint)((aMaxTotalProgress - aCurTotalProgress) - /currentRate + 0.5); - } - - downloader_view_set_download_progress (mDownloaderView, - mElapsed / 1000000, - remaining, - speed, - totalKBytes, - currentKBytes, - progress, - (gpointer)this); - - return NS_OK; -} - -/* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */ -NS_IMETHODIMP GProgressListener:: - OnLocationChange(nsIWebProgress *aWebProgress, - nsIRequest *aRequest, nsIURI *location) -{ - return NS_OK; -} - -/* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */ -NS_IMETHODIMP GProgressListener:: - OnStatusChange(nsIWebProgress *aWebProgress, - nsIRequest *aRequest, nsresult aStatus, - const PRUnichar *aMessage) -{ - return NS_OK; -} - -/* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long state); */ -NS_IMETHODIMP GProgressListener:: - OnSecurityChange(nsIWebProgress *aWebProgress, - nsIRequest *aRequest, - PRUint32 state) -{ - return NS_OK; -} - -//--------------------------------------------------------------------------- - -NS_METHOD GProgressListener::LaunchHelperApp (void) -{ - if (!mMIMEInfo) - return NS_ERROR_FAILURE; - - nsresult rv; - - nsCOMPtr<nsIFile> helperFile; - rv = mMIMEInfo->GetPreferredApplicationHandler(getter_AddRefs(helperFile)); - if(NS_FAILED(rv)) return NS_ERROR_FAILURE; - - nsCAutoString helperFileName; - rv = helperFile->GetNativePath(helperFileName); - if(NS_FAILED(rv)) return NS_ERROR_FAILURE; - - nsMIMEInfoHandleAction mimeAction; - rv = mMIMEInfo->GetPreferredAction(&mimeAction); - if(NS_FAILED(rv)) return NS_ERROR_FAILURE; - - nsCOMPtr<nsIExternalHelperAppService> helperService = - do_GetService (NS_EXTERNALHELPERAPPSERVICE_CONTRACTID, &rv); - if (NS_SUCCEEDED(rv)) - { - nsCOMPtr<nsPIExternalAppLauncher> appLauncher = - do_QueryInterface (helperService, &rv); - if (NS_SUCCEEDED(rv)) - { - appLauncher->DeleteTemporaryFileOnExit(mFile); - } - } - - nsCAutoString cFileName; - mFile->GetNativePath(cFileName); - if(NS_FAILED(rv)) return NS_ERROR_FAILURE; - - nsXPIDLString helperDesc; - rv = mMIMEInfo->GetApplicationDescription(getter_Copies(helperDesc)); - if(NS_FAILED(rv)) return NS_ERROR_FAILURE; - - gboolean terminalHelper = - helperDesc.Equals(NS_LITERAL_STRING("runInTerminal")) ? - TRUE : FALSE; - - ephy_file_launch_application (helperFileName.get(), - cFileName.get(), - terminalHelper); - - return NS_OK; -} - -nsresult GProgressListener::Pause (void) -{ - nsresult rv; - - if (!mIsPaused) - { - rv = mRequest->Suspend (); - if (NS_SUCCEEDED (rv)) - { - mIsPaused = PR_TRUE; - } - } - else - { - rv = NS_ERROR_FAILURE; - } - - return rv; -} - -nsresult GProgressListener::Resume (void) -{ - nsresult rv; - - if (mIsPaused) - { - rv = mRequest->Resume (); - if (NS_SUCCEEDED (rv)) - { - mIsPaused = PR_FALSE; - } - } - else - { - rv = NS_ERROR_FAILURE; - } - - return rv; -} - -nsresult GProgressListener::Abort (void) -{ - PRBool notify; - notify = (mAction == ACTION_OBJECT_NOTIFY); - mAction = ACTION_NONE; - mAbort = PR_TRUE; - - if (mObserver) - { - mObserver->Observe(NS_ISUPPORTS_CAST(nsIProgressDialog*, this), - "oncancel", nsnull); - OnStateChange(nsnull, nsnull, - nsIWebProgressListener::STATE_STOP, 0); - } - - if (mPersist) - { - mPersist->CancelSave (); - } - else if (mLauncher) - { - mLauncher->Cancel (); - } - else - { - return NS_ERROR_FAILURE; - } - - if (notify) - { - mozilla_embed_persist_cancelled - (MOZILLA_EMBED_PERSIST (mEphyPersist)); - } - - return NS_OK; -} - -static void -download_remove_cb (DownloaderView *dv, GProgressListener *Changed, GProgressListener *Progress) -{ - if (Changed == Progress){ - Progress->Abort(); - } -} - -static void -download_resume_cb (DownloaderView *dv, GProgressListener *Changed, GProgressListener *Progress) -{ - if (Changed == Progress) { - Progress->Resume(); - } -} - -static void -download_pause_cb (DownloaderView *dv, GProgressListener *Changed, GProgressListener *Progress) -{ - if (Changed == Progress) { - Progress->Pause(); - } -} diff --git a/embed/mozilla/ProgressListener.h b/embed/mozilla/ProgressListener.h deleted file mode 100644 index 1c6cf6689..000000000 --- a/embed/mozilla/ProgressListener.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (C) 2001 Philip Langdale, Matthew Aubury - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef PROGRESSLISTENER2_H__ -#define PROGRESSLISTENER2_H__ - -#include "downloader-view.h" -#include "ephy-embed-persist.h" -#include "ephy-embed-shell.h" - -#include <gtk/gtkwidget.h> -#include "nsIWebProgressListener.h" -#include "nsIHelperAppLauncherDialog.h" -#include "nsIExternalHelperAppService.h" -#include "nsCExternalHandlerService.h" -#include "nsIWebBrowserPersist.h" -#include "nsWeakReference.h" -#include "nsIURI.h" -#include "nsILocalFile.h" -#include "nsIDOMWindow.h" -#include "nsIRequest.h" -#include "nsIDownload.h" -#include "nsIObserver.h" -#include "nsIProgressDialog.h" -#include "nsIMIMEInfo.h" - -#include "ContentHandler.h" - -#define G_PROGRESSDIALOG_CID \ -{ /* d2a2f743-f126-4f1f-1234-d4e50490f112 */ \ - 0xd2a2f743, \ - 0xf126, \ - 0x4f1f, \ - {0x12, 0x34, 0xd4, 0xe5, 0x04, 0x90, 0xf1, 0x12} \ -} - -#define G_PROGRESSDIALOG_CLASSNAME "Ephy's Download Progress Dialog" -#define G_PROGRESSDIALOG_CONTRACTID "@mozilla.org/progressdialog;1" - -class GProgressListener : public nsIProgressDialog, - public nsIWebProgressListener, - public nsSupportsWeakReference -{ - public: - NS_DECL_ISUPPORTS - NS_DECL_NSIWEBPROGRESSLISTENER - NS_DECL_NSIPROGRESSDIALOG - NS_DECL_NSIDOWNLOAD - - GProgressListener (); - virtual ~GProgressListener (); - - NS_METHOD InitForPersist (nsIWebBrowserPersist *aPersist, - nsIDOMWindow *aParent, nsIURI *aURI, - nsIFile *aFile, - DownloadAction aAction, - EphyEmbedPersist *ephyPersist, - PRBool Dialog, - PRInt64 aTimeDownloadStarted = 0); - nsresult Pause (void); - nsresult Resume (void); - nsresult Abort (void); - - GTimer *mTimer; - - private: - NS_METHOD PrivateInit (void); - NS_METHOD LaunchHelperApp (void); - - NS_METHOD LaunchHandler (PersistHandlerInfo *handler); - - nsCOMPtr<nsIHelperAppLauncher> mLauncher; - nsCOMPtr<nsIWebBrowserPersist> mPersist; - nsCOMPtr<GContentHandler> mHandler; - nsCOMPtr<nsIDOMWindow> mParent; - nsCOMPtr<nsIRequest> mRequest; - - EphyEmbedPersist *mEphyPersist; - - nsCOMPtr<nsIURI> mUri; - PRInt64 mTimeDownloadStarted; - nsCOMPtr<nsIFile> mFile; - - PRInt64 mStartTime; - PRInt64 mElapsed; - - PRInt64 mLastUpdate; - PRInt32 mInterval; - - PRFloat64 mPriorKRate; - PRInt32 mRateChanges; - PRInt32 mRateChangeLimit; - - PRBool mIsPaused; - PRBool mAbort; - gboolean mDialog; - - DownloadAction mAction; - - DownloaderView *mDownloaderView; - - EphyEmbedShell *ephy_shell; - - guint mTimeoutFunc; - - nsCOMPtr<nsIObserver> mObserver; - - nsCOMPtr<nsIMIMEInfo> mMIMEInfo; - - PRInt32 mPercentComplete; -}; - -extern nsresult NS_NewProgressListenerFactory(nsIFactory** aFactory); - -#endif // PROGRESSLISTENER2_H__ - diff --git a/embed/mozilla/mozilla-download.cpp b/embed/mozilla/mozilla-download.cpp new file mode 100644 index 000000000..bb60cd0e6 --- /dev/null +++ b/embed/mozilla/mozilla-download.cpp @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2003 Xan Lopez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Id$ + */ + +#include "mozilla-download.h" + +#include "nsString.h" + +static void +mozilla_download_class_init (MozillaDownloadClass *klass); +static void +mozilla_download_init (MozillaDownload *ges); +static void +mozilla_download_finalize (GObject *object); + +static GObjectClass *parent_class = NULL; + +GType +mozilla_download_get_type (void) +{ + static GType mozilla_download_type = 0; + + if (mozilla_download_type == 0) + { + static const GTypeInfo our_info = + { + sizeof (MozillaDownloadClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) mozilla_download_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (MozillaDownload), + 0, /* n_preallocs */ + (GInstanceInitFunc) mozilla_download_init + }; + + mozilla_download_type = + g_type_register_static (EPHY_TYPE_DOWNLOAD, + "MozillaDownload", + &our_info, (GTypeFlags)0); + } + + return mozilla_download_type; +} + +static char * +impl_get_source (EphyDownload *download) +{ + nsCOMPtr<nsILocalFile> targetFile; + MozDownload *mozDownload; + + mozDownload = MOZILLA_DOWNLOAD (download)->moz_download; + + mozDownload->GetTarget (getter_AddRefs (targetFile)); + + nsCAutoString tempPathStr; + targetFile->GetNativePath (tempPathStr); + + return g_strdup (tempPathStr.get ()); +} + +static char * +impl_get_target (EphyDownload *download) +{ + nsCOMPtr<nsIURI> uri; + MozDownload *mozDownload; + nsCString spec; + + mozDownload = MOZILLA_DOWNLOAD (download)->moz_download; + + mozDownload->GetSource (getter_AddRefs (uri)); + uri->GetSpec (spec); + + return g_strdup (spec.get()); +} + +static long +impl_get_current_progress (EphyDownload *download) +{ + MozDownload *mozDownload; + PRInt32 progress; + + mozDownload = MOZILLA_DOWNLOAD (download)->moz_download; + + mozDownload->GetCurrentProgress (&progress); + + return progress; +} + +static EphyDownloadState +impl_get_state (EphyDownload *download) +{ + MozDownload *mozDownload; + EphyDownloadState state; + + mozDownload = MOZILLA_DOWNLOAD (download)->moz_download; + + mozDownload->GetState (&state); + + return state; +} + +static long +impl_get_total_progress (EphyDownload *download) +{ + MozDownload *mozDownload; + PRInt32 progress; + + mozDownload = MOZILLA_DOWNLOAD (download)->moz_download; + + mozDownload->GetTotalProgress (&progress); + + return progress; +} + +static int +impl_get_percent (EphyDownload *download) +{ + MozDownload *mozDownload; + PRInt32 percent; + + mozDownload = MOZILLA_DOWNLOAD (download)->moz_download; + + mozDownload->GetPercentComplete (&percent); + + return percent; +} + +static long +impl_get_elapsed_time (EphyDownload *download) +{ + MozDownload *mozDownload; + PRInt64 elapsed; + + mozDownload = MOZILLA_DOWNLOAD (download)->moz_download; + + mozDownload->GetElapsedTime (&elapsed); + + return elapsed / 1000000; +} + +static void +impl_cancel (EphyDownload *download) +{ + MOZILLA_DOWNLOAD (download)->moz_download->Cancel (); +} + +static void +impl_pause (EphyDownload *download) +{ +} + +static void +impl_resume (EphyDownload *download) +{ +} + +static void +mozilla_download_class_init (MozillaDownloadClass *klass) +{ + EphyDownloadClass *download_class = EPHY_DOWNLOAD_CLASS (klass); + + parent_class = (GObjectClass *) g_type_class_peek_parent (klass); + + download_class->get_elapsed_time = impl_get_elapsed_time; + download_class->get_current_progress = impl_get_current_progress; + download_class->get_total_progress = impl_get_total_progress; + download_class->get_percent = impl_get_percent; + download_class->get_target = impl_get_target; + download_class->get_source = impl_get_source; + download_class->get_state = impl_get_state; + download_class->cancel = impl_cancel; + download_class->pause = impl_pause; + download_class->resume = impl_resume; +} + +static void +mozilla_download_init (MozillaDownload *view) +{ +} + +EphyDownload * +mozilla_download_new (void) +{ + return EPHY_DOWNLOAD (g_object_new (MOZILLA_TYPE_DOWNLOAD, NULL)); +} diff --git a/embed/mozilla/mozilla-download.h b/embed/mozilla/mozilla-download.h new file mode 100644 index 000000000..3d92cc24d --- /dev/null +++ b/embed/mozilla/mozilla-download.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef MOZILLA_DOWNLOAD_H +#define MOZILLA_DOWNLOAD_H + +#include "MozDownload.h" + +#include <glib-object.h> +#include <glib.h> + +G_BEGIN_DECLS + +#define MOZILLA_TYPE_DOWNLOAD (mozilla_download_get_type ()) +#define MOZILLA_DOWNLOAD(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), MOZILLA_TYPE_DOWNLOAD, MozillaDownload)) +#define MOZILLA_DOWNLOAD_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), MOZILLA_TYPE_DOWNLOAD, MozillaDownloadClass)) +#define MOZILLA_IS_DOWNLOAD(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), MOZILLA_TYPE_DOWNLOAD)) +#define MOZILLA_IS_DOWNLOAD_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), MOZILLA_TYPE_DOWNLOAD)) +#define MOZILLA_DOWNLOAD_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), MOZILLA_TYPE_DOWNLOAD, MozillaDownloadClass)) + +typedef struct MozillaDownloadClass MozillaDownloadClass; +typedef struct MozillaDownload MozillaDownload; +typedef struct MozillaDownloadPrivate MozillaDownloadPrivate; + +struct MozillaDownload +{ + EphyDownload parent; + MozDownload *moz_download; +}; + +struct MozillaDownloadClass +{ + EphyDownloadClass parent_class; +}; + +GType mozilla_download_get_type (void); + +EphyDownload *mozilla_download_new (void); + +G_END_DECLS + +#endif diff --git a/embed/mozilla/mozilla-embed-persist.cpp b/embed/mozilla/mozilla-embed-persist.cpp index 7e120935b..8906a68f1 100644 --- a/embed/mozilla/mozilla-embed-persist.cpp +++ b/embed/mozilla/mozilla-embed-persist.cpp @@ -18,8 +18,8 @@ * $Id$ */ -#include "ProgressListener.h" #include "EphyWrapper.h" +#include "EphyHeaderSniffer.h" #include "mozilla-embed.h" #include "mozilla-embed-persist.h" @@ -28,6 +28,8 @@ #include <nsString.h> #include <nsCWebBrowserPersist.h> #include <nsNetUtil.h> +#include <nsIHistoryEntry.h> +#include <nsISHEntry.h> static void mozilla_embed_persist_class_init (MozillaEmbedPersistClass *klass); @@ -46,7 +48,7 @@ impl_cancel (EphyEmbedPersist *persist); struct MozillaEmbedPersistPrivate { nsCOMPtr<nsIWebBrowserPersist> mPersist; - GProgressListener *mProgress; +// GProgressListener *mProgress; }; static GObjectClass *parent_class = NULL; @@ -109,7 +111,6 @@ mozilla_embed_persist_finalize (GObject *object) { MozillaEmbedPersist *persist = MOZILLA_EMBED_PERSIST (object); - persist->priv->mPersist->SetProgressListener (nsnull); persist->priv->mPersist = nsnull; G_OBJECT_CLASS (parent_class)->finalize (object); @@ -152,9 +153,10 @@ impl_save (EphyEmbedPersist *persist) int max_size; EphyEmbed *embed; EmbedPersistFlags flags; - EphyWrapper *wrapper = NULL; PRUint32 persistFlags = 0; + /* FIXME implement max size */ + g_object_ref (persist); g_object_get (persist, @@ -167,76 +169,48 @@ impl_save (EphyEmbedPersist *persist) g_return_val_if_fail (filename != NULL, G_FAILED); - nsCOMPtr<nsIWebBrowserPersist> bpersist = + nsCOMPtr<nsIWebBrowserPersist> webPersist = MOZILLA_EMBED_PERSIST (persist)->priv->mPersist; - if (!bpersist) return G_FAILED; - - nsCOMPtr<nsIURI> linkURI; - linkURI = nsnull; + if (!webPersist) return G_FAILED; + + /* Get a temp filename to save to */ + nsCOMPtr<nsIProperties> dirService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv)); + if (!dirService) return G_FAILED; + nsCOMPtr<nsIFile> tmpFile; + dirService->Get("TmpD", NS_GET_IID(nsIFile), getter_AddRefs(tmpFile)); + static short unsigned int tmpRandom = 0; + nsAutoString tmpNo; + tmpNo.AppendInt(tmpRandom++); + nsAutoString saveFile(NS_LITERAL_STRING("-sav")); + saveFile += tmpNo; + saveFile += NS_LITERAL_STRING("tmp"); + tmpFile->Append(saveFile); + + /* Get the uri to save to */ + nsCOMPtr<nsIURI> inURI; if (uri) { + nsAutoString s; s.AssignWithConversion(uri); - rv = NS_NewURI(getter_AddRefs(linkURI), s); - if (NS_FAILED(rv) || !linkURI) return G_FAILED; - } - - nsCOMPtr<nsILocalFile> file; - rv = NS_NewLocalFile(NS_ConvertUTF8toUCS2(filename), PR_TRUE, getter_AddRefs(file)); - if (NS_FAILED(rv) || !file) return G_FAILED; - - nsCOMPtr<nsILocalFile> path; - if (flags & EMBED_PERSIST_SAVE_CONTENT) - { - char *datapath; - datapath = g_strconcat (filename, ".content", NULL); - NS_NewLocalFile(NS_ConvertUTF8toUCS2(datapath), PR_TRUE, getter_AddRefs(path)); - g_free (datapath); - } - else - { - path = nsnull; - } - - nsCOMPtr<nsIDOMWindow> parent; - parent = nsnull; - - if (embed) - { - wrapper = (EphyWrapper *) mozilla_embed_get_ephy_wrapper (MOZILLA_EMBED(embed)); - g_return_val_if_fail (wrapper != NULL, G_FAILED); - wrapper->GetDOMWindow (getter_AddRefs (parent)); - } - - persistFlags = nsIWebBrowserPersist::PERSIST_FLAGS_REPLACE_EXISTING_FILES; - - size_t len = strlen(filename); - if((filename[len-1] == 'z' && filename[len-2] == 'g') || - (filename[len-1] == 'Z' && filename[len-2] == 'G')) - { - persistFlags |= nsIWebBrowserPersist::PERSIST_FLAGS_NO_CONVERSION; + rv = NS_NewURI(getter_AddRefs(inURI), s); + if (NS_FAILED(rv) || !inURI) return G_FAILED; } - if (flags & EMBED_PERSIST_BYPASSCACHE) - { - persistFlags |= nsIWebBrowserPersist::PERSIST_FLAGS_BYPASS_CACHE; - } + /* Filename to save to */ + nsAutoString inFilename; + inFilename.AssignWithConversion (filename); - if (flags & EMBED_PERSIST_FROMCACHE) + nsCOMPtr<nsIDOMDocument> DOMDocument; + nsCOMPtr<nsIInputStream> postData; + if (!uri) { - persistFlags |= nsIWebBrowserPersist::PERSIST_FLAGS_FROM_CACHE; - } - - bpersist->SetPersistFlags (persistFlags); + EphyWrapper *wrapper; - GProgressListener *aProgress = new GProgressListener (); - MOZILLA_EMBED_PERSIST (persist)->priv->mProgress = aProgress; - - if (uri == NULL) - { + g_return_val_if_fail (embed != NULL, G_FAILED); + wrapper = (EphyWrapper *) mozilla_embed_get_ephy_wrapper (MOZILLA_EMBED(embed)); g_return_val_if_fail (wrapper != NULL, G_FAILED); - nsCOMPtr<nsIDOMDocument> DOMDocument; - + /* Get the DOM document */ if (flags & EMBED_PERSIST_MAINDOC) { rv = wrapper->GetMainDOMDocument (getter_AddRefs(DOMDocument)); @@ -247,35 +221,32 @@ impl_save (EphyEmbedPersist *persist) } if (NS_FAILED(rv) || !DOMDocument) return G_FAILED; - nsCOMPtr<nsIDocument> document = - do_QueryInterface (DOMDocument, &rv); - if (NS_FAILED(rv) || !document) return G_FAILED; - - nsCOMPtr<nsIURI> uri; - rv = document->GetDocumentURL (getter_AddRefs(uri)); - if (NS_FAILED(rv) || !uri) return G_FAILED; + nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(wrapper->mWebBrowser)); + nsCOMPtr<nsISHistory> sessionHistory; + webNav->GetSessionHistory(getter_AddRefs(sessionHistory)); + nsCOMPtr<nsIHistoryEntry> entry; + + /* Get post data */ + PRInt32 sindex; + sessionHistory->GetIndex(&sindex); + sessionHistory->GetEntryAtIndex(sindex, PR_FALSE, getter_AddRefs(entry)); + nsCOMPtr<nsISHEntry> shEntry(do_QueryInterface(entry)); + if (shEntry) + { + shEntry->GetPostData(getter_AddRefs(postData)); + } + } - aProgress->InitForPersist (bpersist, parent, - uri, file, - ACTION_OBJECT_NOTIFY, - persist, - (flags & EMBED_PERSIST_SHOW_PROGRESS)); + EphyHeaderSniffer* sniffer = new EphyHeaderSniffer + (webPersist, MOZILLA_EMBED_PERSIST (persist), + tmpFile, inURI, DOMDocument, postData, + inFilename, flags & EMBED_PERSIST_BYPASSCACHE); + if (!sniffer) return G_FAILED; + + webPersist->SetProgressListener(sniffer); + + rv = webPersist->SaveURI(inURI, nsnull, nsnull, nsnull, nsnull, tmpFile); + if (NS_FAILED (rv)) return G_FAILED; - rv = bpersist->SaveDocument (DOMDocument, file, path, nsnull, 0, 0); - if (NS_FAILED(rv)) return G_FAILED; - } - else - { - aProgress->InitForPersist (bpersist, parent, - linkURI, file, - ACTION_OBJECT_NOTIFY, - persist, - (flags & EMBED_PERSIST_SHOW_PROGRESS)); - - rv = bpersist->SaveURI (linkURI, nsnull, nsnull, nsnull, nsnull, file); - if (NS_FAILED(rv)) return G_FAILED; - } - return G_OK; } - diff --git a/lib/widgets/Makefile.am b/lib/widgets/Makefile.am index 6a8835728..17c02ef73 100644 --- a/lib/widgets/Makefile.am +++ b/lib/widgets/Makefile.am @@ -16,6 +16,8 @@ libephywidgets_la_SOURCES = \ ephy-arrow-toolbutton.h \ ephy-ellipsizing-label.c \ ephy-ellipsizing-label.h \ + ephy-cell-renderer-progress.h \ + ephy-cell-renderer-progress.c \ ephy-location-entry.c \ ephy-location-entry.h \ ephy-node-view.c \ diff --git a/lib/widgets/ephy-cell-renderer-progress.c b/lib/widgets/ephy-cell-renderer-progress.c new file mode 100644 index 000000000..5e96dc601 --- /dev/null +++ b/lib/widgets/ephy-cell-renderer-progress.c @@ -0,0 +1,308 @@ +/* gtkcellrenderer.c + * Copyright (C) 2002 Naba Kumar <kh_naba@users.sourceforge.net> + * heavily modified by Jörgen Scheibengruber <mfcn@gmx.de> + * heavily modified by Marco Pesenti Gritti <marco@gnome.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <config.h> +#include <stdlib.h> +#include <bonobo/bonobo-i18n.h> + +#include "ephy-cell-renderer-progress.h" + +static void ephy_cell_renderer_progress_init (EphyCellRendererProgress *celltext); +static void ephy_cell_renderer_progress_class_init (EphyCellRendererProgressClass *class); + +#define EPHY_CELL_RENDERER_PROGRESS_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_CELL_RENDERER_PROGRESS, EphyCellRendererProgressPrivate)) + +#define XPAD 4 +#define YPAD 2 +#define UNKNOWN_STRING _("Unknown") + +enum +{ + PROP_0, + PROP_VALUE +}; + +struct _EphyCellRendererProgressPrivate +{ + int value; + char *text; + int min_h; + int min_w; +}; + +static gpointer parent_class; + +GtkType +ephy_cell_renderer_progress_get_type (void) +{ + static GtkType cell_progress_type = 0; + + if (!cell_progress_type) + { + static const GTypeInfo cell_progress_info = + { + sizeof (EphyCellRendererProgressClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) ephy_cell_renderer_progress_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (EphyCellRendererProgress), + 0, /* n_preallocs */ + (GInstanceInitFunc) ephy_cell_renderer_progress_init, + }; + cell_progress_type = g_type_register_static (GTK_TYPE_CELL_RENDERER, + "EphyCellRendererProgress", + &cell_progress_info, 0); + } + + return cell_progress_type; +} + +static void +ephy_cell_renderer_progress_init (EphyCellRendererProgress *cellprogress) +{ + cellprogress->priv = EPHY_CELL_RENDERER_PROGRESS_GET_PRIVATE (cellprogress); + cellprogress->priv->value = 0; + cellprogress->priv->text = NULL; + cellprogress->priv->min_w = -1; +} + +static void +ephy_cell_renderer_progress_set_value (EphyCellRendererProgress *cellprogress, int value) +{ + char *text; + + cellprogress->priv->value = value; + + if (cellprogress->priv->value == EPHY_PROGRESS_CELL_FAILED) + { + text = g_strdup (_("Failed")); + } + else if (cellprogress->priv->value == EPHY_PROGRESS_CELL_UNKNOWN) + { + text = g_strdup (UNKNOWN_STRING); + } + else + { + text = g_strdup_printf ("%d %%", cellprogress->priv->value); + } + + g_free (cellprogress->priv->text); + cellprogress->priv->text = text; +} + +static void +ephy_cell_renderer_progress_get_property (GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec) +{ + EphyCellRendererProgress *cellprogress = EPHY_CELL_RENDERER_PROGRESS (object); + + switch (param_id) + { + case PROP_VALUE: + g_value_set_int (value, cellprogress->priv->value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + } +} + +static void +ephy_cell_renderer_progress_set_property (GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec) +{ + EphyCellRendererProgress *cellprogress = EPHY_CELL_RENDERER_PROGRESS (object); + + switch (param_id) + { + case PROP_VALUE: + ephy_cell_renderer_progress_set_value + (cellprogress, g_value_get_int (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + } + g_object_notify (object, "value"); +} + +static void +compute_dimensions (GtkWidget *widget, const char *text, int *width, int *height) +{ + PangoRectangle logical_rect; + PangoLayout *layout; + + layout = gtk_widget_create_pango_layout (widget, text); + pango_layout_get_pixel_extents (layout, NULL, &logical_rect); + + if (width) + { + *width = logical_rect.width + XPAD * 2 + + widget->style->xthickness * 2; + } + + if (height) + { + *height = logical_rect.height + YPAD * 2 + + widget->style->ythickness * 2; + } + + g_object_unref (G_OBJECT (layout)); +} + +static void +ephy_cell_renderer_progress_get_size (GtkCellRenderer *cell, + GtkWidget *widget, + GdkRectangle *cell_area, + gint *x_offset, + gint *y_offset, + gint *width, + gint *height) +{ + EphyCellRendererProgress *cellprogress = EPHY_CELL_RENDERER_PROGRESS (cell); + int w, h; + + if (cellprogress->priv->min_w < 0) + { + compute_dimensions (widget, UNKNOWN_STRING, + &cellprogress->priv->min_w, + &cellprogress->priv->min_h); + } + + compute_dimensions (widget, cellprogress->priv->text, &w, &h); + + if (width) + { + *width = MAX (cellprogress->priv->min_w, w); + } + + if (height) + { + *height = MIN (cellprogress->priv->min_h, h); + } +} + +GtkCellRenderer* +ephy_cell_renderer_progress_new (void) +{ + return GTK_CELL_RENDERER (g_object_new (ephy_cell_renderer_progress_get_type (), NULL)); +} + +static void +ephy_cell_renderer_progress_render (GtkCellRenderer *cell, + GdkWindow *window, + GtkWidget *widget, + GdkRectangle *background_area, + GdkRectangle *cell_area, + GdkRectangle *expose_area, + guint flags) +{ + EphyCellRendererProgress *cellprogress = (EphyCellRendererProgress *) cell; + GdkGC *gc; + PangoLayout *layout; + PangoRectangle logical_rect; + GtkStateType state; + int x, y, w, h, perc_w, pos; + + gc = gdk_gc_new (window); + + x = cell_area->x + XPAD; + y = cell_area->y + YPAD; + + w = cell_area->width - XPAD * 2; + h = cell_area->height - YPAD * 2; + + gdk_gc_set_rgb_fg_color (gc, &widget->style->fg[GTK_STATE_NORMAL]); + gdk_draw_rectangle (window, gc, TRUE, x, y, w, h); + + x += widget->style->xthickness; + y += widget->style->ythickness; + w -= widget->style->xthickness * 2; + h -= widget->style->ythickness * 2; + gdk_gc_set_rgb_fg_color (gc, &widget->style->bg[GTK_STATE_NORMAL]); + gdk_draw_rectangle (window, gc, TRUE, x, y, w, h); + + gdk_gc_set_rgb_fg_color (gc, &widget->style->bg[GTK_STATE_SELECTED]); + perc_w = w * cellprogress->priv->value / 100; + gdk_draw_rectangle (window, gc, TRUE, x, y, perc_w, h); + + layout = gtk_widget_create_pango_layout (widget, cellprogress->priv->text); + pango_layout_get_pixel_extents (layout, NULL, &logical_rect); + + pos = (w - logical_rect.width)/2; + + if (perc_w < pos + logical_rect.width/2) + { + state = GTK_STATE_NORMAL; + } + else + { + state = GTK_STATE_SELECTED; + } + + gtk_paint_layout (widget->style, window, state, + FALSE, cell_area, widget, "progressbar", + x + pos, y + (h - logical_rect.height)/2, + layout); + + g_object_unref (G_OBJECT (layout)); + g_object_unref (G_OBJECT (gc)); +} + +static void +ephy_cell_renderer_progress_finalize (GObject *object) +{ + EphyCellRendererProgress *cellprogress = EPHY_CELL_RENDERER_PROGRESS (object); + + g_free (cellprogress->priv->text); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +ephy_cell_renderer_progress_class_init (EphyCellRendererProgressClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (class); + + parent_class = g_type_class_peek_parent (class); + + object_class->finalize = ephy_cell_renderer_progress_finalize; + object_class->get_property = ephy_cell_renderer_progress_get_property; + object_class->set_property = ephy_cell_renderer_progress_set_property; + + cell_class->get_size = ephy_cell_renderer_progress_get_size; + cell_class->render = ephy_cell_renderer_progress_render; + + g_object_class_install_property (object_class, + PROP_VALUE, + g_param_spec_int ("value", + "Value", + "Value of the progress bar.", + -2, 100, 0, + G_PARAM_READWRITE)); + + g_type_class_add_private (object_class, sizeof (EphyCellRendererProgressPrivate)); +} diff --git a/lib/widgets/ephy-cell-renderer-progress.h b/lib/widgets/ephy-cell-renderer-progress.h new file mode 100644 index 000000000..85b632b2e --- /dev/null +++ b/lib/widgets/ephy-cell-renderer-progress.h @@ -0,0 +1,57 @@ +/* cellrenderer.h + * Copyright (C) 2002 Naba Kumar <kh_naba@users.sourceforge.net> + * modified by Jörgen Scheibengruber <mfcn@gmx.de> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef EPHY_CELL_RENDERER_PROGRESS_H +#define EPHY_CELL_RENDERER_PROGRESS_H + +#include <gtk/gtkcellrenderer.h> + +G_BEGIN_DECLS + +#define EPHY_TYPE_CELL_RENDERER_PROGRESS (ephy_cell_renderer_progress_get_type ()) +#define EPHY_CELL_RENDERER_PROGRESS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EPHY_TYPE_CELL_RENDERER_PROGRESS, EphyCellRendererProgress)) + +typedef struct _EphyCellRendererProgress EphyCellRendererProgress; +typedef struct _EphyCellRendererProgressClass EphyCellRendererProgressClass; +typedef struct _EphyCellRendererProgressPrivate EphyCellRendererProgressPrivate; + +enum +{ + EPHY_PROGRESS_CELL_UNKNOWN = -1, + EPHY_PROGRESS_CELL_FAILED = -2 +}; + +struct _EphyCellRendererProgress +{ + GtkCellRenderer parent_instance; + EphyCellRendererProgressPrivate *priv; +}; + +struct _EphyCellRendererProgressClass +{ + GtkCellRendererClass parent_class; +}; + +GtkType ephy_cell_renderer_progress_get_type (void); +GtkCellRenderer* ephy_cell_renderer_progress_new (void); + +G_END_DECLS + +#endif diff --git a/src/popup-commands.c b/src/popup-commands.c index c1557eb7f..e1d2a046e 100644 --- a/src/popup-commands.c +++ b/src/popup-commands.c @@ -262,7 +262,6 @@ save_property_url (GtkAction *action, const char *title, EphyWindow *window, gboolean ask_dest, - gboolean show_progress, const char *property) { EphyEmbedEvent *info; @@ -285,15 +284,9 @@ save_property_url (GtkAction *action, ephy_embed_persist_set_source (persist, location); - if (show_progress) - { - ephy_embed_persist_set_flags (persist, - EMBED_PERSIST_SHOW_PROGRESS); - } - ephy_embed_utils_save (GTK_WIDGET (window), title, CONF_STATE_DOWNLOADING_DIR, - ask_dest, FALSE, persist); + ask_dest, persist); g_object_unref (G_OBJECT(persist)); } @@ -324,7 +317,7 @@ popup_cmd_download_link (GtkAction *action, save_property_url (action, _("Download link"), window, eel_gconf_get_boolean (CONF_ASK_DOWNLOAD_DEST), - TRUE, "link"); + "link"); } void @@ -332,7 +325,7 @@ popup_cmd_save_image_as (GtkAction *action, EphyWindow *window) { save_property_url (action, _("Save Image As"), - window, TRUE, FALSE, "image"); + window, TRUE, "image"); } #define CONF_DESKTOP_BG_PICTURE "/desktop/gnome/background/picture_filename" @@ -420,7 +413,7 @@ popup_cmd_save_background_as (GtkAction *action, EphyWindow *window) { save_property_url (action, _("Save Background As"), - window, TRUE, FALSE, "background_image"); + window, TRUE, "background_image"); } void diff --git a/src/window-commands.c b/src/window-commands.c index 5f5dea0d5..60eaf8c3b 100644 --- a/src/window-commands.c +++ b/src/window-commands.c @@ -383,9 +383,7 @@ window_cmd_file_save_as (GtkAction *action, ephy_embed_utils_save (GTK_WIDGET(window), _("Save As"), CONF_STATE_SAVE_DIR, - TRUE, - TRUE, - persist); + TRUE, persist); g_object_unref (G_OBJECT(persist)); } |