/midori/midori-preferences.c

https://bitbucket.org/edgimar/midori · C · 520 lines · 433 code · 45 blank · 42 comment · 17 complexity · 033624e241c8600bff22c6f8cd328191 MD5 · raw file

  1. /*
  2. Copyright (C) 2007-2009 Christian Dywan <christian@twotoasts.de>
  3. This library is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU Lesser General Public
  5. License as published by the Free Software Foundation; either
  6. version 2.1 of the License, or (at your option) any later version.
  7. See the file COPYING for the full license text.
  8. */
  9. #include "midori-preferences.h"
  10. #include "midori-app.h"
  11. #include "midori-core.h"
  12. #include "midori-platform.h"
  13. #include <string.h>
  14. #include <glib/gi18n.h>
  15. #include <libsoup/soup.h>
  16. #if WEBKIT_CHECK_VERSION (1, 3, 11)
  17. #define LIBSOUP_USE_UNSTABLE_REQUEST_API
  18. #include <libsoup/soup-cache.h>
  19. #endif
  20. #include <config.h>
  21. #if HAVE_LIBNOTIFY
  22. #include <libnotify/notify.h>
  23. #endif
  24. struct _MidoriPreferences
  25. {
  26. KatzePreferences parent_instance;
  27. gpointer settings;
  28. };
  29. G_DEFINE_TYPE (MidoriPreferences, midori_preferences, KATZE_TYPE_PREFERENCES);
  30. enum
  31. {
  32. PROP_0,
  33. PROP_SETTINGS
  34. };
  35. static void
  36. midori_preferences_finalize (GObject* object);
  37. static void
  38. midori_preferences_set_property (GObject* object,
  39. guint prop_id,
  40. const GValue* value,
  41. GParamSpec* pspec);
  42. static void
  43. midori_preferences_get_property (GObject* object,
  44. guint prop_id,
  45. GValue* value,
  46. GParamSpec* pspec);
  47. static void
  48. midori_preferences_class_init (MidoriPreferencesClass* class)
  49. {
  50. GObjectClass* gobject_class = G_OBJECT_CLASS (class);
  51. gobject_class->finalize = midori_preferences_finalize;
  52. gobject_class->set_property = midori_preferences_set_property;
  53. gobject_class->get_property = midori_preferences_get_property;
  54. /**
  55. * MidoriPreferences:settings:
  56. *
  57. * The settings to proxy properties from.
  58. */
  59. g_object_class_install_property (gobject_class,
  60. PROP_SETTINGS,
  61. g_param_spec_object (
  62. "settings",
  63. "Settings",
  64. "Settings instance to provide properties",
  65. MIDORI_TYPE_WEB_SETTINGS,
  66. G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  67. }
  68. static void
  69. midori_preferences_init (MidoriPreferences* preferences)
  70. {
  71. preferences->settings = NULL;
  72. }
  73. static void
  74. midori_preferences_finalize (GObject* object)
  75. {
  76. G_OBJECT_CLASS (midori_preferences_parent_class)->finalize (object);
  77. }
  78. static void
  79. midori_preferences_set_property (GObject* object,
  80. guint prop_id,
  81. const GValue* value,
  82. GParamSpec* pspec)
  83. {
  84. MidoriPreferences* preferences = MIDORI_PREFERENCES (object);
  85. switch (prop_id)
  86. {
  87. case PROP_SETTINGS:
  88. midori_preferences_set_settings (preferences,
  89. g_value_get_object (value));
  90. break;
  91. default:
  92. G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
  93. break;
  94. }
  95. }
  96. static void
  97. midori_preferences_get_property (GObject* object,
  98. guint prop_id,
  99. GValue* value,
  100. GParamSpec* pspec)
  101. {
  102. MidoriPreferences* preferences = MIDORI_PREFERENCES (object);
  103. switch (prop_id)
  104. {
  105. case PROP_SETTINGS:
  106. g_value_set_object (value, preferences->settings);
  107. break;
  108. default:
  109. G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
  110. break;
  111. }
  112. }
  113. /**
  114. * midori_preferences_new:
  115. * @parent: the parent window
  116. * @settings: the settings
  117. *
  118. * Creates a new preferences dialog.
  119. *
  120. * Since 0.1.2 @parent may be %NULL.
  121. *
  122. * Return value: a new #MidoriPreferences
  123. **/
  124. GtkWidget*
  125. midori_preferences_new (GtkWindow* parent,
  126. MidoriWebSettings* settings)
  127. {
  128. MidoriPreferences* preferences;
  129. g_return_val_if_fail (!parent || GTK_IS_WINDOW (parent), NULL);
  130. g_return_val_if_fail (MIDORI_IS_WEB_SETTINGS (settings), NULL);
  131. preferences = g_object_new (MIDORI_TYPE_PREFERENCES,
  132. "transient-for", parent,
  133. "settings", settings,
  134. NULL);
  135. return GTK_WIDGET (preferences);
  136. }
  137. static void
  138. midori_preferences_homepage_current_clicked_cb (GtkWidget* button,
  139. MidoriWebSettings* settings)
  140. {
  141. GtkWidget* preferences = gtk_widget_get_toplevel (button);
  142. GtkWidget* browser = katze_object_get_object (preferences, "transient-for");
  143. if (GTK_IS_WINDOW (browser))
  144. {
  145. gchar* uri = katze_object_get_string (browser, "uri");
  146. if (uri && *uri)
  147. g_object_set (settings, "homepage", uri, NULL);
  148. else
  149. g_object_set (settings, "homepage", "about:blank", NULL);
  150. g_free (uri);
  151. }
  152. }
  153. #if !HAVE_HILDON
  154. static void
  155. midori_preferences_notify_proxy_type_cb (MidoriWebSettings* settings,
  156. GParamSpec* pspec,
  157. GtkWidget* entry)
  158. {
  159. MidoriProxy proxy_type = katze_object_get_enum (settings, "proxy-type");
  160. gtk_widget_set_sensitive (entry, proxy_type == MIDORI_PROXY_HTTP);
  161. }
  162. #endif
  163. #if HAVE_OSX
  164. static void
  165. midori_preferences_toolbutton_clicked_cb (GtkWidget* toolbutton,
  166. GtkWidget* page)
  167. {
  168. gpointer notebook = g_object_get_data (G_OBJECT (toolbutton), "notebook");
  169. guint n = gtk_notebook_page_num (notebook, page);
  170. gtk_notebook_set_current_page (notebook, n);
  171. }
  172. #endif
  173. static inline void
  174. midori_preferences_add_toolbutton (GtkWidget* toolbar,
  175. GtkWidget** toolbutton,
  176. const gchar* icon,
  177. const gchar* label,
  178. GtkWidget* page)
  179. {
  180. #if HAVE_OSX
  181. *toolbutton = GTK_WIDGET (*toolbutton ? gtk_radio_tool_button_new_from_widget (
  182. GTK_RADIO_TOOL_BUTTON (*toolbutton)) : gtk_radio_tool_button_new (NULL));
  183. gtk_tool_button_set_label (GTK_TOOL_BUTTON (*toolbutton), label);
  184. gtk_tool_button_set_stock_id (GTK_TOOL_BUTTON (*toolbutton), icon);
  185. gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (*toolbutton), -1);
  186. g_signal_connect (*toolbutton, "clicked",
  187. G_CALLBACK (midori_preferences_toolbutton_clicked_cb), page);
  188. #endif
  189. }
  190. #if 0
  191. static void
  192. midori_preferences_list_dicts_cb (const gchar* lang_tag,
  193. const gchar* provider_name,
  194. const gchar* provider_desc,
  195. const gchar* provider_file,
  196. GList** dicts)
  197. {
  198. *dicts = g_list_prepend (*dicts, (gchar*)lang_tag);
  199. }
  200. static GList*
  201. midori_preferences_get_spell_languages (void)
  202. {
  203. GList* dicts = NULL;
  204. gpointer broker = enchant_broker_init ();
  205. enchant_broker_list_dicts (broker, (GCallback)midori_preferences_list_dicts_cb, &dicts);
  206. enchant_broker_free (broker);
  207. return dicts;
  208. }
  209. #endif
  210. /**
  211. * midori_preferences_set_settings:
  212. * @settings: the settings
  213. *
  214. * Assigns a settings instance to a preferences dialog.
  215. *
  216. * Note: This must not be called more than once.
  217. *
  218. * Since 0.1.2 this is equal to setting #MidoriPreferences:settings:.
  219. **/
  220. void
  221. midori_preferences_set_settings (MidoriPreferences* preferences,
  222. MidoriWebSettings* settings)
  223. {
  224. GtkWidget* header;
  225. GtkWindow* parent;
  226. const gchar* icon_name;
  227. KatzePreferences* _preferences;
  228. GtkWidget* label;
  229. GtkWidget* button;
  230. GtkWidget* entry;
  231. g_return_if_fail (MIDORI_IS_PREFERENCES (preferences));
  232. g_return_if_fail (MIDORI_IS_WEB_SETTINGS (settings));
  233. g_return_if_fail (!preferences->settings);
  234. preferences->settings = settings;
  235. g_object_get (preferences, "transient-for", &parent, NULL);
  236. icon_name = parent ? gtk_window_get_icon_name (parent) : NULL;
  237. if ((header = sokoke_xfce_header_new (icon_name,
  238. gtk_window_get_title (GTK_WINDOW (preferences)))))
  239. {
  240. GtkWidget* vbox = gtk_dialog_get_content_area (GTK_DIALOG (preferences));
  241. gtk_box_pack_start (GTK_BOX (vbox), header, FALSE, FALSE, 0);
  242. gtk_widget_show_all (header);
  243. }
  244. _preferences = KATZE_PREFERENCES (preferences);
  245. #define PAGE_NEW(__icon, __label) \
  246. katze_preferences_add_category (_preferences, __label, __icon)
  247. #define FRAME_NEW(__label) \
  248. katze_preferences_add_group (_preferences, __label)
  249. #define FILLED_ADD(__widget) \
  250. katze_preferences_add_widget (_preferences, __widget, "filled")
  251. #define INDENTED_ADD(__widget) \
  252. katze_preferences_add_widget (_preferences, __widget, "indented")
  253. #define SPANNED_ADD(__widget) \
  254. katze_preferences_add_widget (_preferences, __widget, "spanned")
  255. /* Page "General" */
  256. if (!midori_paths_is_readonly ())
  257. {
  258. PAGE_NEW (GTK_STOCK_HOME, _("Startup"));
  259. FRAME_NEW (NULL);
  260. label = katze_property_label (settings, "load-on-startup");
  261. INDENTED_ADD (label);
  262. button = katze_property_proxy (settings, "load-on-startup", NULL);
  263. SPANNED_ADD (button);
  264. label = gtk_label_new (_("Homepage:"));
  265. gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
  266. INDENTED_ADD (label);
  267. entry = katze_property_proxy (settings, "homepage", "address");
  268. SPANNED_ADD (entry);
  269. if (parent && katze_object_has_property (parent, "uri"))
  270. {
  271. #if 0
  272. button = gtk_button_new_with_mnemonic (_("Use _current page"));
  273. #else
  274. label = gtk_label_new (NULL);
  275. INDENTED_ADD (label);
  276. button = gtk_button_new_with_label (_("Use current page as homepage"));
  277. #endif
  278. g_signal_connect (button, "clicked",
  279. G_CALLBACK (midori_preferences_homepage_current_clicked_cb), settings);
  280. SPANNED_ADD (button);
  281. }
  282. }
  283. /* Page "Appearance" */
  284. PAGE_NEW (GTK_STOCK_SELECT_FONT, _("Fonts"));
  285. FRAME_NEW (NULL);
  286. #if !HAVE_HILDON
  287. label = gtk_label_new (_("Proportional Font Family"));
  288. gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
  289. INDENTED_ADD (label);
  290. button = katze_property_proxy (settings, "default-font-family", "font");
  291. gtk_widget_set_tooltip_text (button, _("The default font family used to display text"));
  292. SPANNED_ADD (button);
  293. entry = katze_property_proxy (settings, "default-font-size", NULL);
  294. gtk_widget_set_tooltip_text (entry, _("The default font size used to display text"));
  295. SPANNED_ADD (entry);
  296. label = gtk_label_new (_("Fixed-width Font Family"));
  297. gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
  298. INDENTED_ADD (label);
  299. button = katze_property_proxy (settings, "monospace-font-family", "font-monospace");
  300. gtk_widget_set_tooltip_text (button, _("The font family used to display fixed-width text"));
  301. SPANNED_ADD (button);
  302. entry = katze_property_proxy (settings, "default-monospace-font-size", NULL);
  303. gtk_widget_set_tooltip_text (entry, _("The font size used to display fixed-width text"));
  304. SPANNED_ADD (entry);
  305. label = gtk_label_new (_("Minimum Font Size"));
  306. gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
  307. INDENTED_ADD (label);
  308. entry = katze_property_proxy (settings, "minimum-font-size", NULL);
  309. gtk_widget_set_tooltip_text (entry, _("The minimum font size used to display text"));
  310. SPANNED_ADD (entry);
  311. button = katze_property_proxy (settings, "enforce-font-family", NULL);
  312. INDENTED_ADD (button);
  313. #endif
  314. label = katze_property_label (settings, "preferred-encoding");
  315. INDENTED_ADD (label);
  316. button = katze_property_proxy (settings, "preferred-encoding", "custom-default-encoding");
  317. SPANNED_ADD (button);
  318. /* Page "Behavior" */
  319. PAGE_NEW (GTK_STOCK_SELECT_COLOR, _("Behavior"));
  320. FRAME_NEW (NULL);
  321. #if !HAVE_HILDON
  322. button = katze_property_proxy (settings, "auto-load-images", NULL);
  323. gtk_button_set_label (GTK_BUTTON (button), _("Load images automatically"));
  324. INDENTED_ADD (button);
  325. button = katze_property_proxy (settings, "enable-spell-checking", NULL);
  326. gtk_button_set_label (GTK_BUTTON (button), _("Enable Spell Checking"));
  327. SPANNED_ADD (button);
  328. /* Disable spell check option if there are no enchant modules */
  329. {
  330. gchar* enchant_path = midori_paths_get_lib_path ("enchant");
  331. if (enchant_path == NULL)
  332. {
  333. gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
  334. gtk_widget_set_sensitive (button, FALSE);
  335. }
  336. else
  337. g_free (enchant_path);
  338. }
  339. button = katze_property_proxy (settings, "enable-scripts", NULL);
  340. gtk_button_set_label (GTK_BUTTON (button), _("Enable scripts"));
  341. INDENTED_ADD (button);
  342. button = katze_property_proxy (settings, "enable-plugins", NULL);
  343. gtk_button_set_label (GTK_BUTTON (button), _("Enable Netscape plugins"));
  344. gtk_widget_set_sensitive (button, midori_web_settings_has_plugin_support ());
  345. SPANNED_ADD (button);
  346. #endif
  347. button = katze_property_proxy (settings, "zoom-text-and-images", NULL);
  348. gtk_button_set_label (GTK_BUTTON (button), _("Zoom Text and Images"));
  349. INDENTED_ADD (button);
  350. button = katze_property_proxy (settings, "javascript-can-open-windows-automatically", NULL);
  351. gtk_button_set_label (GTK_BUTTON (button), _("Allow scripts to open popups"));
  352. gtk_widget_set_tooltip_text (button, _("Whether scripts are allowed to open popup windows automatically"));
  353. SPANNED_ADD (button);
  354. if (katze_widget_has_touchscreen_mode (parent ?
  355. GTK_WIDGET (parent) : GTK_WIDGET (preferences)))
  356. {
  357. button = katze_property_proxy (settings, "kinetic-scrolling", NULL);
  358. gtk_button_set_label (GTK_BUTTON (button), _("Kinetic scrolling"));
  359. gtk_widget_set_tooltip_text (button, _("Whether scrolling should kinetically move according to speed"));
  360. }
  361. else
  362. {
  363. button = katze_property_proxy (settings, "middle-click-opens-selection", NULL);
  364. gtk_button_set_label (GTK_BUTTON (button), _("Middle click opens Selection"));
  365. gtk_widget_set_tooltip_text (button, _("Load an address from the selection via middle click"));
  366. }
  367. INDENTED_ADD (button);
  368. if (katze_object_has_property (settings, "enable-webgl"))
  369. {
  370. button = katze_property_proxy (settings, "enable-webgl", NULL);
  371. gtk_button_set_label (GTK_BUTTON (button), _("Enable WebGL support"));
  372. SPANNED_ADD (button);
  373. }
  374. #ifndef G_OS_WIN32
  375. button = katze_property_proxy (settings, "flash-window-on-new-bg-tabs", NULL);
  376. gtk_button_set_label (GTK_BUTTON (button), _("Flash window on background tabs"));
  377. INDENTED_ADD (button);
  378. #endif
  379. FRAME_NEW (NULL);
  380. button = katze_property_label (settings, "preferred-languages");
  381. INDENTED_ADD (button);
  382. entry = katze_property_proxy (settings, "preferred-languages", "languages");
  383. SPANNED_ADD (entry);
  384. label = gtk_label_new (_("Save downloaded files to:"));
  385. gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
  386. INDENTED_ADD (label);
  387. button = katze_property_proxy (settings, "download-folder", "folder");
  388. SPANNED_ADD (button);
  389. /* Page "Interface" */
  390. PAGE_NEW (GTK_STOCK_CONVERT, _("Browsing"));
  391. #if !HAVE_HILDON
  392. if (!g_getenv ("DESKTOP_SESSION"))
  393. {
  394. FRAME_NEW (NULL);
  395. INDENTED_ADD (katze_property_label (settings, "toolbar-style"));
  396. button = katze_property_proxy (settings, "toolbar-style", NULL);
  397. SPANNED_ADD (button);
  398. }
  399. #endif
  400. FRAME_NEW (NULL);
  401. label = katze_property_label (settings, "open-new-pages-in");
  402. INDENTED_ADD (label);
  403. button = katze_property_proxy (settings, "open-new-pages-in", NULL);
  404. SPANNED_ADD (button);
  405. button = katze_property_proxy (settings, "close-buttons-on-tabs", NULL);
  406. gtk_button_set_label (GTK_BUTTON (button), _("Close Buttons on Tabs"));
  407. INDENTED_ADD (button);
  408. #ifndef HAVE_GRANITE
  409. button = katze_property_proxy (settings, "always-show-tabbar", NULL);
  410. gtk_button_set_label (GTK_BUTTON (button), _("Always Show Tabbar"));
  411. SPANNED_ADD (button);
  412. #endif
  413. button = katze_property_proxy (settings, "open-tabs-next-to-current", NULL);
  414. gtk_button_set_label (GTK_BUTTON (button), _("Open Tabs next to Current"));
  415. gtk_widget_set_tooltip_text (button, _("Whether to open new tabs next to the current tab or after the last one"));
  416. INDENTED_ADD (button);
  417. button = katze_property_proxy (settings, "open-tabs-in-the-background", NULL);
  418. gtk_button_set_label (GTK_BUTTON (button), _("Open tabs in the background"));
  419. SPANNED_ADD (button);
  420. INDENTED_ADD (gtk_label_new (NULL));
  421. label = gtk_label_new (_("Text Editor"));
  422. gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
  423. INDENTED_ADD (label);
  424. entry = katze_property_proxy (settings, "text-editor", "application-text/plain");
  425. SPANNED_ADD (entry);
  426. label = gtk_label_new (_("News Aggregator"));
  427. gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
  428. INDENTED_ADD (label);
  429. entry = katze_property_proxy (settings, "news-aggregator", "application-News");
  430. SPANNED_ADD (entry);
  431. /* Page "Network" */
  432. PAGE_NEW (GTK_STOCK_NETWORK, _("Network"));
  433. FRAME_NEW (NULL);
  434. label = gtk_label_new (_("Proxy server"));
  435. gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
  436. INDENTED_ADD (label);
  437. button = katze_property_proxy (settings, "proxy-type", NULL);
  438. SPANNED_ADD (button);
  439. label = gtk_label_new (_("Hostname"));
  440. gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
  441. INDENTED_ADD (label);
  442. entry = katze_property_proxy (settings, "http-proxy", "address");
  443. SPANNED_ADD (entry);
  444. g_signal_connect (settings, "notify::proxy-type",
  445. G_CALLBACK (midori_preferences_notify_proxy_type_cb), entry);
  446. midori_preferences_notify_proxy_type_cb (settings, NULL, entry);
  447. label = gtk_label_new (_("Port"));
  448. gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
  449. INDENTED_ADD (label);
  450. entry = katze_property_proxy (settings, "http-proxy-port", NULL);
  451. SPANNED_ADD (entry);
  452. g_signal_connect (settings, "notify::proxy-type",
  453. G_CALLBACK (midori_preferences_notify_proxy_type_cb), entry);
  454. midori_preferences_notify_proxy_type_cb (settings, NULL, entry);
  455. #if WEBKIT_CHECK_VERSION (1, 3, 11)
  456. if (soup_session_get_feature (webkit_get_default_session (), SOUP_TYPE_CACHE))
  457. {
  458. label = gtk_label_new (_("Web Cache"));
  459. gtk_widget_set_tooltip_text (label, _("The maximum size of cached pages on disk"));
  460. INDENTED_ADD (label);
  461. button = katze_property_proxy (settings, "maximum-cache-size", NULL);
  462. gtk_widget_set_tooltip_text (button, _("The maximum size of cached pages on disk"));
  463. SPANNED_ADD (button);
  464. label = gtk_label_new (_("MB"));
  465. gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
  466. SPANNED_ADD (label);
  467. }
  468. #endif
  469. label = katze_property_label (settings, "identify-as");
  470. INDENTED_ADD (label);
  471. button = katze_property_proxy (settings, "identify-as", "custom-user-agent");
  472. SPANNED_ADD (button);
  473. }