]> git.0d.be Git - empathy.git/blob - libempathy-gtk/empathy-webkit-utils.c
remove released flag
[empathy.git] / libempathy-gtk / empathy-webkit-utils.c
1 /*
2  * Copyright (C) 2008-2009 Collabora Ltd.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  *
18  * Authors: Xavier Claessens <xclaesse@gmail.com>
19  */
20
21 #include "config.h"
22 #include "empathy-webkit-utils.h"
23
24 #include <glib/gi18n-lib.h>
25
26 #include "empathy-smiley-manager.h"
27 #include "empathy-string-parser.h"
28 #include "empathy-theme-adium.h"
29 #include "empathy-ui-utils.h"
30
31 #define BORING_DPI_DEFAULT 96
32
33 static void
34 empathy_webkit_match_newline (const gchar *text,
35     gssize len,
36     TpawStringReplace replace_func,
37     TpawStringParser *sub_parsers,
38     gpointer user_data)
39 {
40   GString *string = user_data;
41   gint i;
42   gint prev = 0;
43
44   if (len < 0)
45     len = G_MAXSSIZE;
46
47   /* Replace \n by <br/> */
48   for (i = 0; i < len && text[i] != '\0'; i++)
49     {
50       if (text[i] == '\n')
51         {
52           tpaw_string_parser_substr (text + prev, i - prev,
53               sub_parsers, user_data);
54           g_string_append (string, "<br/>");
55           prev = i + 1;
56         }
57     }
58
59   tpaw_string_parser_substr (text + prev, i - prev,
60               sub_parsers, user_data);
61 }
62
63 static void
64 empathy_webkit_replace_smiley (const gchar *text,
65     gssize len,
66     gpointer match_data,
67     gpointer user_data)
68 {
69   EmpathySmileyHit *hit = match_data;
70   GString *string = user_data;
71
72   /* Replace smiley by a <img/> tag */
73   g_string_append_printf (string,
74       "<img src=\"%s\" alt=\"%.*s\" title=\"%.*s\"/>",
75       hit->path, (int)len, text, (int)len, text);
76 }
77
78 static TpawStringParser string_parsers[] = {
79   { tpaw_string_match_link, tpaw_string_replace_link },
80   { empathy_webkit_match_newline, NULL },
81   { tpaw_string_match_all, tpaw_string_replace_escaped },
82   { NULL, NULL}
83 };
84
85 static TpawStringParser string_parsers_with_smiley[] = {
86   { tpaw_string_match_link, tpaw_string_replace_link },
87   { empathy_string_match_smiley, empathy_webkit_replace_smiley },
88   { empathy_webkit_match_newline, NULL },
89   { tpaw_string_match_all, tpaw_string_replace_escaped },
90   { NULL, NULL }
91 };
92
93 TpawStringParser *
94 empathy_webkit_get_string_parser (gboolean smileys)
95 {
96   if (smileys)
97     return string_parsers_with_smiley;
98   else
99     return string_parsers;
100 }
101
102 static gboolean
103 webkit_get_font_family (GValue *value,
104     GVariant *variant,
105     gpointer user_data)
106 {
107   PangoFontDescription *font = pango_font_description_from_string (
108       g_variant_get_string (variant, NULL));
109
110   if (font == NULL)
111     return FALSE;
112
113   g_value_set_string (value, pango_font_description_get_family (font));
114   pango_font_description_free (font);
115
116   return TRUE;
117 }
118
119 static gboolean
120 webkit_get_font_size (GValue *value,
121     GVariant *variant,
122     gpointer user_data)
123 {
124   PangoFontDescription *font = pango_font_description_from_string (
125       g_variant_get_string (variant, NULL));
126   int size;
127
128   if (font == NULL)
129     return FALSE;
130
131   size = pango_font_description_get_size (font) / PANGO_SCALE;
132
133   if (pango_font_description_get_size_is_absolute (font))
134     {
135       GdkScreen *screen = gdk_screen_get_default ();
136       double dpi;
137
138       if (screen != NULL)
139         dpi = gdk_screen_get_resolution (screen);
140       else
141         dpi = BORING_DPI_DEFAULT;
142
143       size = (gint) (size / (dpi / 72));
144     }
145
146   g_value_set_int (value, size);
147   pango_font_description_free (font);
148
149   return TRUE;
150 }
151
152 void
153 empathy_webkit_bind_font_setting (WebKitWebView *webview,
154     GSettings *gsettings,
155     const char *key)
156 {
157   WebKitWebSettings *settings = webkit_web_view_get_settings (webview);
158
159   g_settings_bind_with_mapping (gsettings, key,
160       settings, "default-font-family",
161       G_SETTINGS_BIND_GET,
162       webkit_get_font_family,
163       NULL,
164       NULL, NULL);
165
166   g_settings_bind_with_mapping (gsettings, key,
167       settings, "default-font-size",
168       G_SETTINGS_BIND_GET,
169       webkit_get_font_size,
170       NULL,
171       NULL, NULL);
172 }
173
174 static void
175 empathy_webkit_copy_address_cb (GtkMenuItem *menuitem,
176     gpointer user_data)
177 {
178   WebKitHitTestResult *hit_test_result = WEBKIT_HIT_TEST_RESULT (user_data);
179   gchar *uri;
180   GtkClipboard *clipboard;
181
182   g_object_get (G_OBJECT (hit_test_result),
183       "link-uri", &uri,
184       NULL);
185
186   clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
187   gtk_clipboard_set_text (clipboard, uri, -1);
188
189   clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
190   gtk_clipboard_set_text (clipboard, uri, -1);
191
192   g_free (uri);
193 }
194
195 static void
196 empathy_webkit_open_address_cb (GtkMenuItem *menuitem,
197     gpointer     user_data)
198 {
199   WebKitHitTestResult *hit_test_result = WEBKIT_HIT_TEST_RESULT (user_data);
200   gchar *uri;
201
202   g_object_get (G_OBJECT (hit_test_result),
203       "link-uri", &uri,
204       NULL);
205
206   empathy_url_show (GTK_WIDGET (menuitem), uri);
207
208   g_free (uri);
209 }
210
211 static void
212 empathy_webkit_inspect_cb (GtkMenuItem *menuitem,
213     WebKitWebView *view)
214 {
215   empathy_webkit_show_inspector (view);
216 }
217
218 static void
219 empathy_webkit_context_menu_selection_done_cb (GtkMenuShell *menu,
220     gpointer user_data)
221 {
222   WebKitHitTestResult *hit_test_result = WEBKIT_HIT_TEST_RESULT (user_data);
223
224   g_object_unref (hit_test_result);
225 }
226
227 GtkWidget *
228 empathy_webkit_create_context_menu (WebKitWebView *view,
229     WebKitHitTestResult *hit_test_result,
230     EmpathyWebKitMenuFlags flags)
231 {
232   WebKitHitTestResultContext context;
233   GtkWidget *menu;
234   GtkWidget *item;
235
236   g_object_get (G_OBJECT (hit_test_result),
237       "context", &context,
238       NULL);
239
240   /* The menu */
241   menu = empathy_context_menu_new (GTK_WIDGET (view));
242
243   /* Select all item */
244   item = gtk_image_menu_item_new_from_stock (GTK_STOCK_SELECT_ALL, NULL);
245   gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
246
247   g_signal_connect_swapped (item, "activate",
248       G_CALLBACK (webkit_web_view_select_all),
249       view);
250
251   /* Copy menu item */
252   if (webkit_web_view_can_copy_clipboard (view))
253     {
254       item = gtk_image_menu_item_new_from_stock (GTK_STOCK_COPY, NULL);
255       gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
256
257       g_signal_connect_swapped (item, "activate",
258           G_CALLBACK (webkit_web_view_copy_clipboard),
259           view);
260     }
261
262   /* Clear menu item */
263   if (flags & EMPATHY_WEBKIT_MENU_CLEAR)
264     {
265       item = gtk_separator_menu_item_new ();
266       gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
267
268       item = gtk_image_menu_item_new_from_stock (GTK_STOCK_CLEAR, NULL);
269       gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
270
271       g_signal_connect_swapped (item, "activate",
272           G_CALLBACK (empathy_theme_adium_clear),
273           view);
274     }
275
276   /* We will only add the following menu items if we are
277    * right-clicking a link */
278   if (context & WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK)
279     {
280       /* Separator */
281       item = gtk_separator_menu_item_new ();
282       gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
283
284       /* Copy Link Address menu item */
285       item = gtk_menu_item_new_with_mnemonic (_("_Copy Link Address"));
286       g_signal_connect (item, "activate",
287           G_CALLBACK (empathy_webkit_copy_address_cb),
288           hit_test_result);
289       gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
290
291       /* Open Link menu item */
292       item = gtk_menu_item_new_with_mnemonic (_("_Open Link"));
293       g_signal_connect (item, "activate",
294           G_CALLBACK (empathy_webkit_open_address_cb),
295           hit_test_result);
296       gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
297     }
298
299   if ((flags & EMPATHY_WEBKIT_MENU_INSPECT) != 0)
300     {
301       /* Separator */
302       item = gtk_separator_menu_item_new ();
303       gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
304
305       /* Inspector */
306       item = gtk_menu_item_new_with_mnemonic (_("Inspect HTML"));
307       g_signal_connect (item, "activate",
308           G_CALLBACK (empathy_webkit_inspect_cb), view);
309       gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
310     }
311
312   g_signal_connect (GTK_MENU_SHELL (menu), "selection-done",
313       G_CALLBACK (empathy_webkit_context_menu_selection_done_cb),
314       g_object_ref (hit_test_result));
315
316   return menu;
317 }
318
319 void
320 empathy_webkit_context_menu_for_event (WebKitWebView *view,
321     GdkEventButton *event,
322     EmpathyWebKitMenuFlags flags)
323 {
324   GtkWidget *menu;
325   WebKitHitTestResult *hit_test_result;
326
327   hit_test_result = webkit_web_view_get_hit_test_result (view, event);
328
329   menu = empathy_webkit_create_context_menu (view, hit_test_result, flags);
330
331   gtk_widget_show_all (menu);
332   gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
333       event->button, event->time);
334
335   g_object_unref (hit_test_result);
336 }
337
338 void
339 empathy_webkit_show_inspector (WebKitWebView *view)
340 {
341   WebKitWebInspector *inspector;
342
343   g_object_set (G_OBJECT (webkit_web_view_get_settings (view)),
344       "enable-developer-extras", TRUE, NULL);
345
346   inspector = webkit_web_view_get_inspector (view);
347   webkit_web_inspector_show (inspector);
348 }