downloads.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. // BadWolf: Minimalist and privacy-oriented WebKitGTK+ browser
  2. // Copyright © 2019 Haelwenn (lanodan) Monnier <contact@hacktivis.me>
  3. // SPDX-License-Identifier: BSD-3-Clause
  4. #include "downloads.h"
  5. #include "badwolf.h"
  6. #include "config.h"
  7. #include <glib/gi18n.h> /* _() and other internationalization/localization helpers */
  8. static void
  9. download_stop_iconCb_clicked(GtkButton *stop_icon, gpointer user_data)
  10. {
  11. (void)stop_icon;
  12. WebKitDownload *webkit_download = (WebKitDownload *)user_data;
  13. webkit_download_cancel(webkit_download);
  14. }
  15. void
  16. download_format_elapsed(char *formatted, size_t formatted_size, char *format, int total)
  17. {
  18. snprintf(formatted,
  19. formatted_size,
  20. format,
  21. total / 3600, /* hours */
  22. (total % 3600) / 60, /* minutes */
  23. total % 60); /* seconds */
  24. }
  25. void
  26. download_new_entry(WebKitDownload *webkit_download, struct Download *download)
  27. {
  28. download->error = 0;
  29. download->container = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, BADWOLF_DOWNLOAD_PADDING);
  30. download->progress = gtk_progress_bar_new();
  31. download->file_path = gtk_label_new(NULL);
  32. download->status = gtk_label_new(_("Download starting…"));
  33. download->icon =
  34. gtk_image_new_from_icon_name("network-idle-symbolic", GTK_ICON_SIZE_SMALL_TOOLBAR);
  35. download->stop_icon = gtk_button_new_from_icon_name("process-stop", GTK_ICON_SIZE_SMALL_TOOLBAR);
  36. gtk_progress_bar_set_show_text(GTK_PROGRESS_BAR(download->progress), TRUE);
  37. gtk_label_set_ellipsize(GTK_LABEL(download->file_path), BADWOLF_DOWNLOAD_FILE_PATH_ELLIPSIZE);
  38. g_signal_connect(
  39. download->stop_icon, "clicked", G_CALLBACK(download_stop_iconCb_clicked), webkit_download);
  40. gtk_box_pack_start(GTK_BOX(download->container), download->icon, FALSE, FALSE, 0);
  41. gtk_box_pack_start(GTK_BOX(download->container), download->progress, FALSE, FALSE, 0);
  42. gtk_box_pack_start(GTK_BOX(download->container), download->stop_icon, FALSE, FALSE, 0);
  43. gtk_box_pack_start(GTK_BOX(download->container), download->status, FALSE, FALSE, 0);
  44. gtk_box_pack_start(GTK_BOX(download->container), download->file_path, FALSE, FALSE, 0);
  45. gtk_list_box_insert(GTK_LIST_BOX(download->window->downloads_tab), download->container, -1);
  46. gtk_widget_show_all(download->container);
  47. }
  48. void
  49. downloadCb_created_destination(WebKitDownload *webkit_download,
  50. gchar *destination,
  51. gpointer user_data)
  52. {
  53. (void)webkit_download;
  54. char *markup;
  55. struct Download *download = (struct Download *)user_data;
  56. markup = g_markup_printf_escaped(
  57. "<a href=\"%s\">%s</a>", destination, webkit_uri_for_display(destination));
  58. gtk_label_set_markup(GTK_LABEL(download->file_path), markup);
  59. g_free(markup);
  60. }
  61. gboolean
  62. downloadCb_decide_destination(WebKitDownload *webkit_download,
  63. gchar *suggested_filename,
  64. gpointer user_data)
  65. {
  66. struct Client *browser = (struct Client *)user_data;
  67. gint chooser_response;
  68. GtkWindow *parent_window = GTK_WINDOW(browser->window->main_window);
  69. GtkFileChooserNative *file_dialog =
  70. gtk_file_chooser_native_new(NULL, parent_window, GTK_FILE_CHOOSER_ACTION_SAVE, NULL, NULL);
  71. GtkFileChooser *file_chooser = GTK_FILE_CHOOSER(file_dialog);
  72. gtk_file_chooser_set_current_name(file_chooser, suggested_filename);
  73. gtk_file_chooser_set_do_overwrite_confirmation(file_chooser, TRUE);
  74. webkit_download_set_allow_overwrite(webkit_download, TRUE);
  75. chooser_response = gtk_native_dialog_run(GTK_NATIVE_DIALOG(file_dialog));
  76. if(chooser_response == GTK_RESPONSE_ACCEPT)
  77. webkit_download_set_destination(webkit_download, gtk_file_chooser_get_uri(file_chooser));
  78. else
  79. webkit_download_cancel(webkit_download);
  80. g_object_unref(file_dialog);
  81. return FALSE; /* Let it propagate */
  82. }
  83. void
  84. downloadCb_failed(WebKitDownload *webkit_download, GError *error, gpointer user_data)
  85. {
  86. struct Download *download = (struct Download *)user_data;
  87. char formatted[BUFSIZ];
  88. int total = (int)webkit_download_get_elapsed_time(webkit_download);
  89. char *format;
  90. download->error = error;
  91. if(g_error_matches(error, WEBKIT_DOWNLOAD_ERROR, WEBKIT_DOWNLOAD_ERROR_CANCELLED_BY_USER))
  92. format = _("%02i:%02i:%02i Download cancelled");
  93. else
  94. format = _("%02i:%02i:%02i Download error");
  95. download_format_elapsed(formatted, sizeof(formatted), format, total);
  96. gtk_label_set_text(GTK_LABEL(download->status), formatted);
  97. gtk_widget_destroy(download->stop_icon);
  98. gtk_image_set_from_icon_name(
  99. GTK_IMAGE(download->icon), "network-error-symbolic", GTK_ICON_SIZE_SMALL_TOOLBAR);
  100. }
  101. void
  102. downloadCb_finished(WebKitDownload *webkit_download, gpointer user_data)
  103. {
  104. struct Download *download = (struct Download *)user_data;
  105. char formatted[BUFSIZ];
  106. int total = (int)webkit_download_get_elapsed_time(webkit_download);
  107. gchar *format_size = g_format_size(webkit_download_get_received_data_length(webkit_download));
  108. download_format_elapsed(
  109. formatted, sizeof(formatted), _("%02i:%02i:%02i Download finished"), total);
  110. gtk_widget_destroy(download->stop_icon);
  111. if(download->error == 0)
  112. {
  113. gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(download->progress), 1);
  114. gtk_progress_bar_set_text(GTK_PROGRESS_BAR(download->progress), format_size);
  115. gtk_label_set_text(GTK_LABEL(download->status), formatted);
  116. gtk_image_set_from_icon_name(
  117. GTK_IMAGE(download->icon), "network-idle-symbolic", GTK_ICON_SIZE_SMALL_TOOLBAR);
  118. }
  119. // TODO: Send notification
  120. }
  121. void
  122. downloadCb_received_data(WebKitDownload *webkit_download, guint64 data_lenght, gpointer user_data)
  123. {
  124. (void)data_lenght;
  125. struct Download *download = (struct Download *)user_data;
  126. char formatted[BUFSIZ];
  127. int total = (int)webkit_download_get_elapsed_time(webkit_download);
  128. gchar *format_size = g_format_size(webkit_download_get_received_data_length(webkit_download));
  129. download_format_elapsed(formatted, sizeof(formatted), _("%02i:%02i:%02i Downloading…"), total);
  130. gtk_image_set_from_icon_name(
  131. GTK_IMAGE(download->icon), "network-receive-symbolic", GTK_ICON_SIZE_SMALL_TOOLBAR);
  132. gtk_label_set_text(GTK_LABEL(download->status), formatted);
  133. gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(download->progress),
  134. webkit_download_get_estimated_progress(webkit_download));
  135. gtk_progress_bar_set_text(GTK_PROGRESS_BAR(download->progress), format_size);
  136. g_free(format_size);
  137. }
  138. GtkWidget *
  139. badwolf_downloads_tab_new()
  140. {
  141. return gtk_list_box_new();
  142. }
  143. void
  144. badwolf_downloads_tab_attach(struct Window *window)
  145. {
  146. int tab_box_width;
  147. int tab_label_charwidth = BADWOLF_TAB_LABEL_CHARWIDTH;
  148. int tab_hexpand = false;
  149. GtkWidget *scrolled_window = gtk_scrolled_window_new(NULL, NULL);
  150. gtk_widget_set_name(scrolled_window, "browser__scrollwin_downloads");
  151. gtk_container_add(GTK_CONTAINER(scrolled_window), window->downloads_tab);
  152. gtk_notebook_insert_page(GTK_NOTEBOOK(window->notebook), scrolled_window, NULL, 0);
  153. gtk_notebook_set_tab_reorderable(GTK_NOTEBOOK(window->notebook), scrolled_window, TRUE);
  154. GtkWidget *tab_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
  155. gtk_widget_set_name(tab_box, "browser__tabbox");
  156. GtkWidget *icon = gtk_image_new_from_icon_name("emblem-downloads", GTK_ICON_SIZE_SMALL_TOOLBAR);
  157. gtk_widget_set_name(icon, "browser__tabbox__icon");
  158. GtkWidget *label = gtk_label_new(_("Badwolf Downloads"));
  159. gtk_widget_set_name(label, "browser__tabbox__label");
  160. if(config_lookup_int(&config, "tab.box_width", &tab_box_width) == CONFIG_TRUE)
  161. {
  162. gtk_widget_set_size_request(label, tab_box_width, -1);
  163. }
  164. else
  165. {
  166. config_lookup_int(&config, "tab.label_charwidth", &tab_label_charwidth);
  167. gtk_label_set_width_chars(GTK_LABEL(label), tab_label_charwidth);
  168. }
  169. config_lookup_bool(&config, "tab.hexpand", &tab_hexpand);
  170. gtk_widget_set_hexpand(tab_box, tab_hexpand);
  171. gtk_label_set_ellipsize(GTK_LABEL(label), BADWOLF_TAB_LABEL_ELLIPSIZE);
  172. gtk_label_set_single_line_mode(GTK_LABEL(label), TRUE);
  173. gtk_box_pack_start(GTK_BOX(tab_box), icon, FALSE, FALSE, 0);
  174. gtk_box_pack_start(GTK_BOX(tab_box), label, TRUE, TRUE, 0);
  175. gtk_widget_set_tooltip_text(tab_box, _("Badwolf Downloads"));
  176. gtk_notebook_set_tab_label(GTK_NOTEBOOK(window->notebook), scrolled_window, tab_box);
  177. gtk_notebook_set_menu_label_text(
  178. GTK_NOTEBOOK(window->notebook), scrolled_window, _("Badwolf Downloads"));
  179. gtk_widget_show_all(tab_box);
  180. }