Updated Hungarian translation
[evolution.git] / e-util / e-html-editor-link-dialog.c
blob3cd0a60acdffecf714c06af5399855a9415364f6
1 /*
2 * e-html-editor-link-dialog.h
4 * Copyright (C) 2012 Dan Vrátil <dvratil@redhat.com>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) version 3.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with the program; if not, see <http://www.gnu.org/licenses/>
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
25 #include "e-html-editor-link-dialog.h"
26 #include "e-html-editor-selection.h"
27 #include "e-html-editor-utils.h"
28 #include "e-html-editor-view.h"
30 #include <glib/gi18n-lib.h>
32 #define E_HTML_EDITOR_LINK_DIALOG_GET_PRIVATE(obj) \
33 (G_TYPE_INSTANCE_GET_PRIVATE \
34 ((obj), E_TYPE_HTML_EDITOR_LINK_DIALOG, EHTMLEditorLinkDialogPrivate))
36 G_DEFINE_TYPE (
37 EHTMLEditorLinkDialog,
38 e_html_editor_link_dialog,
39 E_TYPE_HTML_EDITOR_DIALOG);
41 struct _EHTMLEditorLinkDialogPrivate {
42 GtkWidget *url_edit;
43 GtkWidget *label_edit;
44 GtkWidget *test_button;
46 GtkWidget *remove_link_button;
47 GtkWidget *ok_button;
49 gboolean label_autofill;
52 static void
53 html_editor_link_dialog_test_link (EHTMLEditorLinkDialog *dialog)
55 gtk_show_uri (
56 gtk_window_get_screen (GTK_WINDOW (dialog)),
57 gtk_entry_get_text (GTK_ENTRY (dialog->priv->url_edit)),
58 GDK_CURRENT_TIME,
59 NULL);
62 static void
63 html_editor_link_dialog_url_changed (EHTMLEditorLinkDialog *dialog)
65 if (dialog->priv->label_autofill &&
66 gtk_widget_is_sensitive (dialog->priv->label_edit)) {
67 const gchar *text;
69 text = gtk_entry_get_text (
70 GTK_ENTRY (dialog->priv->url_edit));
71 gtk_entry_set_text (
72 GTK_ENTRY (dialog->priv->label_edit), text);
76 static gboolean
77 html_editor_link_dialog_description_changed (EHTMLEditorLinkDialog *dialog)
79 const gchar *text;
81 text = gtk_entry_get_text (GTK_ENTRY (dialog->priv->label_edit));
82 dialog->priv->label_autofill = (*text == '\0');
84 return FALSE;
87 static void
88 html_editor_link_dialog_remove_link (EHTMLEditorLinkDialog *dialog)
90 EHTMLEditor *editor;
91 EHTMLEditorView *view;
92 EHTMLEditorSelection *selection;
94 editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
95 view = e_html_editor_get_view (editor);
96 selection = e_html_editor_view_get_selection (view);
97 e_html_editor_selection_unlink (selection);
99 gtk_widget_hide (GTK_WIDGET (dialog));
102 static void
103 html_editor_link_dialog_ok (EHTMLEditorLinkDialog *dialog)
105 EHTMLEditor *editor;
106 EHTMLEditorView *view;
107 EHTMLEditorSelection *selection;
108 WebKitDOMDocument *document;
109 WebKitDOMDOMWindow *window;
110 WebKitDOMDOMSelection *dom_selection;
111 WebKitDOMRange *range;
112 WebKitDOMElement *link;
114 editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
115 view = e_html_editor_get_view (editor);
116 selection = e_html_editor_view_get_selection (view);
118 document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
119 window = webkit_dom_document_get_default_view (document);
120 dom_selection = webkit_dom_dom_window_get_selection (window);
122 if (!dom_selection ||
123 (webkit_dom_dom_selection_get_range_count (dom_selection) == 0)) {
124 gtk_widget_hide (GTK_WIDGET (dialog));
125 return;
128 range = webkit_dom_dom_selection_get_range_at (dom_selection, 0, NULL);
129 link = e_html_editor_dom_node_find_parent_element (
130 webkit_dom_range_get_start_container (range, NULL), "A");
131 if (!link) {
132 if ((webkit_dom_range_get_start_container (range, NULL) !=
133 webkit_dom_range_get_end_container (range, NULL)) ||
134 (webkit_dom_range_get_start_offset (range, NULL) !=
135 webkit_dom_range_get_end_offset (range, NULL))) {
137 WebKitDOMDocumentFragment *fragment;
138 fragment = webkit_dom_range_extract_contents (range, NULL);
139 link = e_html_editor_dom_node_find_child_element (
140 WEBKIT_DOM_NODE (fragment), "A");
141 webkit_dom_range_insert_node (
142 range, WEBKIT_DOM_NODE (fragment), NULL);
144 webkit_dom_dom_selection_set_base_and_extent (
145 dom_selection,
146 webkit_dom_range_get_start_container (range, NULL),
147 webkit_dom_range_get_start_offset (range, NULL),
148 webkit_dom_range_get_end_container (range, NULL),
149 webkit_dom_range_get_end_offset (range, NULL),
150 NULL);
151 } else {
152 WebKitDOMNode *node;
154 /* get element that was clicked on */
155 node = webkit_dom_range_get_common_ancestor_container (range, NULL);
156 if (node && !WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (node)) {
157 link = e_html_editor_dom_node_find_parent_element (node, "A");
158 if (link && !WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (link))
159 link = NULL;
160 } else
161 link = WEBKIT_DOM_ELEMENT (node);
165 if (link) {
166 webkit_dom_html_anchor_element_set_href (
167 WEBKIT_DOM_HTML_ANCHOR_ELEMENT (link),
168 gtk_entry_get_text (GTK_ENTRY (dialog->priv->url_edit)));
169 webkit_dom_html_element_set_inner_html (
170 WEBKIT_DOM_HTML_ELEMENT (link),
171 gtk_entry_get_text (GTK_ENTRY (dialog->priv->label_edit)),
172 NULL);
173 } else {
174 gchar *text;
176 /* Check whether a text is selected or not */
177 text = webkit_dom_range_get_text (range);
178 if (text && *text) {
179 e_html_editor_selection_create_link (
180 selection,
181 gtk_entry_get_text (
182 GTK_ENTRY (dialog->priv->url_edit)));
183 } else {
184 gchar *html = g_strdup_printf (
185 "<a href=\"%s\">%s</a>",
186 gtk_entry_get_text (
187 GTK_ENTRY (dialog->priv->url_edit)),
188 gtk_entry_get_text (
189 GTK_ENTRY (dialog->priv->label_edit)));
191 e_html_editor_view_exec_command (
192 view, E_HTML_EDITOR_VIEW_COMMAND_INSERT_HTML, html);
194 g_free (html);
198 g_free (text);
201 gtk_widget_hide (GTK_WIDGET (dialog));
204 static gboolean
205 html_editor_link_dialog_entry_key_pressed (EHTMLEditorLinkDialog *dialog,
206 GdkEventKey *event)
208 /* We can't do thins in key_released, because then you could not open
209 * this dialog from main menu by pressing enter on Insert->Link action */
210 if (event->keyval == GDK_KEY_Return) {
211 html_editor_link_dialog_ok (dialog);
212 return TRUE;
215 return FALSE;
218 static void
219 html_editor_link_dialog_show (GtkWidget *widget)
221 EHTMLEditor *editor;
222 EHTMLEditorView *view;
223 EHTMLEditorLinkDialog *dialog;
224 WebKitDOMDocument *document;
225 WebKitDOMDOMWindow *window;
226 WebKitDOMDOMSelection *dom_selection;
227 WebKitDOMRange *range;
228 WebKitDOMElement *link;
230 dialog = E_HTML_EDITOR_LINK_DIALOG (widget);
231 editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
232 view = e_html_editor_get_view (editor);
234 document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view));
235 window = webkit_dom_document_get_default_view (document);
236 dom_selection = webkit_dom_dom_window_get_selection (window);
238 /* Reset to default values */
239 gtk_entry_set_text (GTK_ENTRY (dialog->priv->url_edit), "http://");
240 gtk_entry_set_text (GTK_ENTRY (dialog->priv->label_edit), "");
241 gtk_widget_set_sensitive (dialog->priv->label_edit, TRUE);
242 gtk_widget_set_sensitive (dialog->priv->remove_link_button, TRUE);
243 dialog->priv->label_autofill = TRUE;
245 /* No selection at all */
246 if (!dom_selection ||
247 webkit_dom_dom_selection_get_range_count (dom_selection) < 1) {
248 gtk_widget_set_sensitive (dialog->priv->remove_link_button, FALSE);
249 goto chainup;
252 range = webkit_dom_dom_selection_get_range_at (dom_selection, 0, NULL);
253 link = e_html_editor_dom_node_find_parent_element (
254 webkit_dom_range_get_start_container (range, NULL), "A");
255 if (!link) {
256 if ((webkit_dom_range_get_start_container (range, NULL) !=
257 webkit_dom_range_get_end_container (range, NULL)) ||
258 (webkit_dom_range_get_start_offset (range, NULL) !=
259 webkit_dom_range_get_end_offset (range, NULL))) {
261 WebKitDOMDocumentFragment *fragment;
262 fragment = webkit_dom_range_clone_contents (range, NULL);
263 link = e_html_editor_dom_node_find_child_element (
264 WEBKIT_DOM_NODE (fragment), "A");
265 } else {
266 WebKitDOMNode *node;
268 node = webkit_dom_range_get_common_ancestor_container (range, NULL);
269 if (node && !WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (node)) {
270 link = e_html_editor_dom_node_find_parent_element (node, "A");
271 if (link && !WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT (link))
272 link = NULL;
273 } else
274 link = WEBKIT_DOM_ELEMENT (node);
278 if (link) {
279 gchar *href, *text;
281 href = webkit_dom_html_anchor_element_get_href (
282 WEBKIT_DOM_HTML_ANCHOR_ELEMENT (link));
283 text = webkit_dom_html_element_get_inner_text (
284 WEBKIT_DOM_HTML_ELEMENT (link));
286 gtk_entry_set_text (
287 GTK_ENTRY (dialog->priv->url_edit), href);
288 gtk_entry_set_text (
289 GTK_ENTRY (dialog->priv->label_edit), text);
291 g_free (text);
292 g_free (href);
293 } else {
294 gchar *text;
296 text = webkit_dom_range_get_text (range);
297 if (text && *text) {
298 gtk_entry_set_text (
299 GTK_ENTRY (dialog->priv->label_edit), text);
300 gtk_widget_set_sensitive (
301 dialog->priv->label_edit, FALSE);
302 gtk_widget_set_sensitive (
303 dialog->priv->remove_link_button, FALSE);
305 g_free (text);
308 chainup:
309 /* Chain up to parent implementation */
310 GTK_WIDGET_CLASS (e_html_editor_link_dialog_parent_class)->show (widget);
313 static void
314 e_html_editor_link_dialog_class_init (EHTMLEditorLinkDialogClass *class)
316 GtkWidgetClass *widget_class;
318 g_type_class_add_private (class, sizeof (EHTMLEditorLinkDialogPrivate));
320 widget_class = GTK_WIDGET_CLASS (class);
321 widget_class->show = html_editor_link_dialog_show;
324 static void
325 e_html_editor_link_dialog_init (EHTMLEditorLinkDialog *dialog)
327 GtkGrid *main_layout;
328 GtkBox *button_box;
329 GtkWidget *widget;
331 dialog->priv = E_HTML_EDITOR_LINK_DIALOG_GET_PRIVATE (dialog);
333 main_layout = e_html_editor_dialog_get_container (E_HTML_EDITOR_DIALOG (dialog));
335 widget = gtk_entry_new ();
336 gtk_grid_attach (main_layout, widget, 1, 0, 1, 1);
337 g_signal_connect_swapped (
338 widget, "notify::text",
339 G_CALLBACK (html_editor_link_dialog_url_changed), dialog);
340 g_signal_connect_swapped (
341 widget, "key-press-event",
342 G_CALLBACK (html_editor_link_dialog_entry_key_pressed), dialog);
343 dialog->priv->url_edit = widget;
345 widget = gtk_label_new_with_mnemonic (_("_URL:"));
346 gtk_label_set_justify (GTK_LABEL (widget), GTK_JUSTIFY_RIGHT);
347 gtk_label_set_mnemonic_widget (GTK_LABEL (widget), dialog->priv->url_edit);
348 gtk_grid_attach (main_layout, widget, 0, 0, 1, 1);
350 widget = gtk_button_new_with_mnemonic (_("_Test URL..."));
351 gtk_grid_attach (main_layout, widget, 2, 0, 1, 1);
352 g_signal_connect_swapped (
353 widget, "clicked",
354 G_CALLBACK (html_editor_link_dialog_test_link), dialog);
355 dialog->priv->test_button = widget;
357 widget = gtk_entry_new ();
358 gtk_grid_attach (main_layout, widget, 1, 1, 2, 1);
359 g_signal_connect_swapped (
360 widget, "key-release-event",
361 G_CALLBACK (html_editor_link_dialog_description_changed), dialog);
362 g_signal_connect_swapped (
363 widget, "key-press-event",
364 G_CALLBACK (html_editor_link_dialog_entry_key_pressed), dialog);
365 dialog->priv->label_edit = widget;
367 widget = gtk_label_new_with_mnemonic (_("_Description:"));
368 gtk_label_set_justify (GTK_LABEL (widget), GTK_JUSTIFY_RIGHT);
369 gtk_label_set_mnemonic_widget (GTK_LABEL (widget), dialog->priv->label_edit);
370 gtk_grid_attach (main_layout, widget, 0, 1, 1, 1);
372 button_box = e_html_editor_dialog_get_button_box (E_HTML_EDITOR_DIALOG (dialog));
374 widget = gtk_button_new_with_mnemonic (_("_Remove Link"));
375 g_signal_connect_swapped (
376 widget, "clicked",
377 G_CALLBACK (html_editor_link_dialog_remove_link), dialog);
378 gtk_box_pack_start (button_box, widget, FALSE, FALSE, 5);
379 dialog->priv->remove_link_button = widget;
381 widget = gtk_button_new_with_mnemonic (_("_OK"));
382 g_signal_connect_swapped (
383 widget, "clicked",
384 G_CALLBACK (html_editor_link_dialog_ok), dialog);
385 gtk_box_pack_end (button_box, widget, FALSE, FALSE, 5);
386 dialog->priv->ok_button = widget;
388 gtk_widget_show_all (GTK_WIDGET (main_layout));
391 GtkWidget *
392 e_html_editor_link_dialog_new (EHTMLEditor *editor)
394 return GTK_WIDGET (
395 g_object_new (
396 E_TYPE_HTML_EDITOR_LINK_DIALOG,
397 "editor", editor,
398 "icon-name", "insert-link",
399 "title", N_("Link Properties"),
400 NULL));