1 /*
2 * e-html-editor-cell-dialog.c
3 *
4 * Copyright (C) 2012 Dan Vrátil <dvratil@redhat.com>
5 *
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.
10 *
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.
15 *
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/>
18 *
19 */
20
21 #include "evolution-config.h"
22
23 #include "e-html-editor-cell-dialog.h"
24
25 #include <glib/gi18n-lib.h>
26 #include <stdlib.h>
27
28 #include "e-color-combo.h"
29 #include "e-dialog-widgets.h"
30 #include "e-image-chooser-dialog.h"
31 #include "e-misc-utils.h"
32
33 #define E_HTML_EDITOR_CELL_DIALOG_GET_PRIVATE(obj) \
34 (G_TYPE_INSTANCE_GET_PRIVATE \
35 ((obj), E_TYPE_HTML_EDITOR_CELL_DIALOG, EHTMLEditorCellDialogPrivate))
36
37 struct _EHTMLEditorCellDialogPrivate {
38 GtkWidget *scope_cell_button;
39 GtkWidget *scope_table_button;
40 GtkWidget *scope_row_button;
41 GtkWidget *scope_column_button;
42
43 GtkWidget *halign_combo;
44 GtkWidget *valign_combo;
45
46 GtkWidget *wrap_text_check;
47 GtkWidget *header_style_check;
48
49 GtkWidget *width_check;
50 GtkWidget *width_edit;
51 GtkWidget *width_units;
52
53 GtkWidget *row_span_edit;
54 GtkWidget *col_span_edit;
55
56 GtkWidget *background_color_picker;
57 GtkWidget *background_image_chooser;
58
59 GtkWidget *remove_image_button;
60
61 guint scope;
62 };
63
64 enum {
65 SCOPE_CELL,
66 SCOPE_ROW,
67 SCOPE_COLUMN,
68 SCOPE_TABLE
69 } DialogScope;
70
71 static GdkRGBA transparent = { 0, 0, 0, 0 };
72
73 G_DEFINE_TYPE (
74 EHTMLEditorCellDialog,
75 e_html_editor_cell_dialog,
76 E_TYPE_HTML_EDITOR_DIALOG);
77
78 static void
html_editor_cell_dialog_set_scope(EHTMLEditorCellDialog * dialog)79 html_editor_cell_dialog_set_scope (EHTMLEditorCellDialog *dialog)
80 {
81 if (gtk_toggle_button_get_active (
82 GTK_TOGGLE_BUTTON (dialog->priv->scope_cell_button))) {
83
84 dialog->priv->scope = SCOPE_CELL;
85
86 } else if (gtk_toggle_button_get_active (
87 GTK_TOGGLE_BUTTON (dialog->priv->scope_row_button))) {
88
89 dialog->priv->scope = SCOPE_ROW;
90
91 } else if (gtk_toggle_button_get_active (
92 GTK_TOGGLE_BUTTON (dialog->priv->scope_column_button))) {
93
94 dialog->priv->scope = SCOPE_COLUMN;
95
96 } else if (gtk_toggle_button_get_active (
97 GTK_TOGGLE_BUTTON (dialog->priv->scope_table_button))) {
98
99 dialog->priv->scope = SCOPE_TABLE;
100
101 }
102 }
103
104 static void
html_editor_cell_dialog_set_valign(EHTMLEditorCellDialog * dialog)105 html_editor_cell_dialog_set_valign (EHTMLEditorCellDialog *dialog)
106 {
107 EHTMLEditor *editor;
108 EContentEditor *cnt_editor;
109
110 editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
111 cnt_editor = e_html_editor_get_content_editor (editor);
112
113 e_content_editor_cell_set_v_align (
114 cnt_editor,
115 gtk_combo_box_get_active_id (
116 GTK_COMBO_BOX (dialog->priv->valign_combo)),
117 dialog->priv->scope);
118 }
119
120 static void
html_editor_cell_dialog_set_halign(EHTMLEditorCellDialog * dialog)121 html_editor_cell_dialog_set_halign (EHTMLEditorCellDialog *dialog)
122 {
123 EHTMLEditor *editor;
124 EContentEditor *cnt_editor;
125
126 editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
127 cnt_editor = e_html_editor_get_content_editor (editor);
128
129 e_content_editor_cell_set_align (
130 cnt_editor,
131 gtk_combo_box_get_active_id (
132 GTK_COMBO_BOX (dialog->priv->halign_combo)),
133 dialog->priv->scope);
134 }
135
136 static void
html_editor_cell_dialog_set_wrap_text(EHTMLEditorCellDialog * dialog)137 html_editor_cell_dialog_set_wrap_text (EHTMLEditorCellDialog *dialog)
138 {
139 EHTMLEditor *editor;
140 EContentEditor *cnt_editor;
141
142 editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
143 cnt_editor = e_html_editor_get_content_editor (editor);
144
145 e_content_editor_cell_set_wrap (
146 cnt_editor,
147 gtk_toggle_button_get_active (
148 GTK_TOGGLE_BUTTON (dialog->priv->wrap_text_check)),
149 dialog->priv->scope);
150 }
151
152 static void
html_editor_cell_dialog_set_header_style(EHTMLEditorCellDialog * dialog)153 html_editor_cell_dialog_set_header_style (EHTMLEditorCellDialog *dialog)
154 {
155 EHTMLEditor *editor;
156 EContentEditor *cnt_editor;
157
158 editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
159 cnt_editor = e_html_editor_get_content_editor (editor);
160
161 e_content_editor_cell_set_header_style (
162 cnt_editor,
163 gtk_toggle_button_get_active (
164 GTK_TOGGLE_BUTTON (dialog->priv->header_style_check)),
165 dialog->priv->scope);
166 }
167
168 static void
html_editor_cell_dialog_set_width(EHTMLEditorCellDialog * dialog)169 html_editor_cell_dialog_set_width (EHTMLEditorCellDialog *dialog)
170 {
171 EHTMLEditor *editor;
172 EContentEditor *cnt_editor;
173
174 editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
175 cnt_editor = e_html_editor_get_content_editor (editor);
176
177 if (gtk_toggle_button_get_active (
178 GTK_TOGGLE_BUTTON (dialog->priv->width_check))) {
179
180 e_content_editor_cell_set_width (
181 cnt_editor,
182 gtk_spin_button_get_value_as_int (
183 GTK_SPIN_BUTTON (dialog->priv->width_edit)),
184 (gtk_combo_box_get_active (
185 GTK_COMBO_BOX (dialog->priv->width_units)) == 0) ?
186 E_CONTENT_EDITOR_UNIT_PIXEL :
187 E_CONTENT_EDITOR_UNIT_PERCENTAGE,
188 dialog->priv->scope);
189 } else
190 e_content_editor_cell_set_width (
191 cnt_editor, 0, E_CONTENT_EDITOR_UNIT_AUTO, dialog->priv->scope);
192 }
193
194 static void
html_editor_cell_dialog_width_units_changed(GtkWidget * widget,EHTMLEditorCellDialog * dialog)195 html_editor_cell_dialog_width_units_changed (GtkWidget *widget,
196 EHTMLEditorCellDialog *dialog)
197 {
198 if (gtk_combo_box_get_active (GTK_COMBO_BOX (dialog->priv->width_units)) == 0) {
199 gtk_spin_button_set_range (
200 GTK_SPIN_BUTTON (dialog->priv->width_edit), 0, G_MAXUINT);
201 } else
202 gtk_spin_button_set_range (
203 GTK_SPIN_BUTTON (dialog->priv->width_edit), 0, 100);
204
205 html_editor_cell_dialog_set_width (dialog);
206 }
207
208 static void
html_editor_cell_dialog_set_column_span(EHTMLEditorCellDialog * dialog)209 html_editor_cell_dialog_set_column_span (EHTMLEditorCellDialog *dialog)
210 {
211 EHTMLEditor *editor;
212 EContentEditor *cnt_editor;
213
214 editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
215 cnt_editor = e_html_editor_get_content_editor (editor);
216
217 e_content_editor_cell_set_col_span (
218 cnt_editor,
219 gtk_spin_button_get_value_as_int (
220 GTK_SPIN_BUTTON (dialog->priv->col_span_edit)),
221 dialog->priv->scope);
222 }
223
224 static void
html_editor_cell_dialog_set_row_span(EHTMLEditorCellDialog * dialog)225 html_editor_cell_dialog_set_row_span (EHTMLEditorCellDialog *dialog)
226 {
227 EHTMLEditor *editor;
228 EContentEditor *cnt_editor;
229
230 editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
231 cnt_editor = e_html_editor_get_content_editor (editor);
232
233 e_content_editor_cell_set_row_span (
234 cnt_editor,
235 gtk_spin_button_get_value_as_int (
236 GTK_SPIN_BUTTON (dialog->priv->row_span_edit)),
237 dialog->priv->scope);
238 }
239
240 static void
html_editor_cell_dialog_set_background_color(EHTMLEditorCellDialog * dialog)241 html_editor_cell_dialog_set_background_color (EHTMLEditorCellDialog *dialog)
242 {
243 EHTMLEditor *editor;
244 EContentEditor *cnt_editor;
245 GdkRGBA rgba;
246
247 editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
248 cnt_editor = e_html_editor_get_content_editor (editor);
249
250 e_color_combo_get_current_color (
251 E_COLOR_COMBO (dialog->priv->background_color_picker), &rgba);
252 e_content_editor_cell_set_background_color (cnt_editor, &rgba, dialog->priv->scope);
253 }
254
255 static void
html_editor_cell_dialog_set_background_image(EHTMLEditorCellDialog * dialog)256 html_editor_cell_dialog_set_background_image (EHTMLEditorCellDialog *dialog)
257 {
258 EHTMLEditor *editor;
259 EContentEditor *cnt_editor;
260 gchar *uri;
261
262 editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
263 cnt_editor = e_html_editor_get_content_editor (editor);
264
265 uri = gtk_file_chooser_get_uri (
266 GTK_FILE_CHOOSER (dialog->priv->background_image_chooser));
267
268 e_content_editor_cell_set_background_image_uri (cnt_editor, uri);
269
270 gtk_widget_set_sensitive (dialog->priv->remove_image_button, uri && *uri);
271
272 g_free (uri);
273 }
274
275 static void
html_editor_cell_dialog_remove_image(EHTMLEditorCellDialog * dialog)276 html_editor_cell_dialog_remove_image (EHTMLEditorCellDialog *dialog)
277 {
278 EHTMLEditor *editor;
279 EContentEditor *cnt_editor;
280
281 editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
282 cnt_editor = e_html_editor_get_content_editor (editor);
283
284 e_content_editor_cell_set_background_image_uri (cnt_editor, NULL);
285
286 gtk_file_chooser_unselect_all (
287 GTK_FILE_CHOOSER (dialog->priv->background_image_chooser));
288
289 gtk_widget_set_sensitive (dialog->priv->remove_image_button, FALSE);
290 }
291
292 static void
html_editor_cell_dialog_show(GtkWidget * widget)293 html_editor_cell_dialog_show (GtkWidget *widget)
294 {
295 EHTMLEditor *editor;
296 EContentEditor *cnt_editor;
297 EContentEditorUnit unit;
298 EHTMLEditorCellDialog *dialog;
299 GdkRGBA rgba;
300 gchar *alignment, *uri;
301 gint width;
302
303 dialog = E_HTML_EDITOR_CELL_DIALOG (widget);
304 editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
305 cnt_editor = e_html_editor_get_content_editor (editor);
306
307 e_content_editor_on_dialog_open (cnt_editor, E_CONTENT_EDITOR_DIALOG_CELL);
308
309 gtk_toggle_button_set_active (
310 GTK_TOGGLE_BUTTON (dialog->priv->scope_cell_button), TRUE);
311
312 alignment = e_content_editor_cell_get_align (cnt_editor);
313 gtk_combo_box_set_active_id (
314 GTK_COMBO_BOX (dialog->priv->halign_combo),
315 (alignment && *alignment) ? alignment : "left");
316 g_free (alignment);
317
318 alignment = e_content_editor_cell_get_v_align (cnt_editor);
319 gtk_combo_box_set_active_id (
320 GTK_COMBO_BOX (dialog->priv->valign_combo),
321 (alignment && *alignment) ? alignment : "middle");
322 g_free (alignment);
323
324 gtk_toggle_button_set_active (
325 GTK_TOGGLE_BUTTON (dialog->priv->wrap_text_check),
326 e_content_editor_cell_get_wrap (cnt_editor));
327
328 gtk_toggle_button_set_active (
329 GTK_TOGGLE_BUTTON (dialog->priv->header_style_check),
330 e_content_editor_cell_is_header (cnt_editor));
331
332 width = e_content_editor_cell_get_width (cnt_editor, &unit);
333 gtk_spin_button_set_value (
334 GTK_SPIN_BUTTON (dialog->priv->width_edit), width);
335 gtk_toggle_button_set_active (
336 GTK_TOGGLE_BUTTON (dialog->priv->width_check),
337 unit != E_CONTENT_EDITOR_UNIT_AUTO);
338 gtk_combo_box_set_active_id (
339 GTK_COMBO_BOX (dialog->priv->width_units),
340 (unit == E_CONTENT_EDITOR_UNIT_PIXEL) ? "units-px" : "units-percent");
341
342 gtk_spin_button_set_value (
343 GTK_SPIN_BUTTON (dialog->priv->row_span_edit),
344 e_content_editor_cell_get_row_span (cnt_editor));
345
346 gtk_spin_button_set_value (
347 GTK_SPIN_BUTTON (dialog->priv->col_span_edit),
348 e_content_editor_cell_get_col_span (cnt_editor));
349
350 uri = e_content_editor_cell_get_background_image_uri (cnt_editor);
351 if (uri && *uri)
352 gtk_file_chooser_set_uri (
353 GTK_FILE_CHOOSER (dialog->priv->background_image_chooser), uri);
354 else
355 gtk_file_chooser_unselect_all (
356 GTK_FILE_CHOOSER (dialog->priv->background_image_chooser));
357 g_free (uri);
358
359 e_content_editor_cell_get_background_color (cnt_editor, &rgba);
360 e_color_combo_set_current_color (
361 E_COLOR_COMBO (dialog->priv->background_color_picker), &rgba);
362
363 GTK_WIDGET_CLASS (e_html_editor_cell_dialog_parent_class)->show (widget);
364 }
365
366 static void
html_editor_cell_dialog_hide(GtkWidget * widget)367 html_editor_cell_dialog_hide (GtkWidget *widget)
368 {
369 EHTMLEditor *editor;
370 EHTMLEditorCellDialog *dialog;
371 EContentEditor *cnt_editor;
372
373 dialog = E_HTML_EDITOR_CELL_DIALOG (widget);
374 editor = e_html_editor_dialog_get_editor (E_HTML_EDITOR_DIALOG (dialog));
375 cnt_editor = e_html_editor_get_content_editor (editor);
376
377 e_content_editor_on_dialog_close (cnt_editor, E_CONTENT_EDITOR_DIALOG_CELL);
378
379 GTK_WIDGET_CLASS (e_html_editor_cell_dialog_parent_class)->hide (widget);
380 }
381
382 static void
e_html_editor_cell_dialog_class_init(EHTMLEditorCellDialogClass * class)383 e_html_editor_cell_dialog_class_init (EHTMLEditorCellDialogClass *class)
384 {
385 GtkWidgetClass *widget_class;
386
387 g_type_class_add_private (class, sizeof (EHTMLEditorCellDialogPrivate));
388
389 widget_class = GTK_WIDGET_CLASS (class);
390 widget_class->show = html_editor_cell_dialog_show;
391 widget_class->hide = html_editor_cell_dialog_hide;
392 }
393
394 static void
e_html_editor_cell_dialog_init(EHTMLEditorCellDialog * dialog)395 e_html_editor_cell_dialog_init (EHTMLEditorCellDialog *dialog)
396 {
397 GtkBox *box;
398 GtkGrid *main_layout, *grid;
399 GtkWidget *widget;
400 GtkFileFilter *file_filter;
401
402 dialog->priv = E_HTML_EDITOR_CELL_DIALOG_GET_PRIVATE (dialog);
403
404 main_layout = e_html_editor_dialog_get_container (E_HTML_EDITOR_DIALOG (dialog));
405
406 /* == Scope == */
407 widget = gtk_label_new ("");
408 gtk_label_set_markup (GTK_LABEL (widget), _("<b>Scope</b>"));
409 gtk_misc_set_alignment (GTK_MISC (widget), 0, 0.5);
410 gtk_grid_attach (main_layout, widget, 0, 0, 1, 1);
411
412 grid = GTK_GRID (gtk_grid_new ());
413 gtk_grid_set_row_spacing (grid, 5);
414 gtk_grid_set_column_spacing (grid, 5);
415 gtk_grid_attach (main_layout, GTK_WIDGET (grid), 0, 1, 1, 1);
416 gtk_widget_set_margin_left (GTK_WIDGET (grid), 10);
417
418 /* Scope: cell */
419 widget = gtk_image_new_from_icon_name ("stock_select-cell", GTK_ICON_SIZE_BUTTON);
420 gtk_grid_attach (grid, widget, 0, 0, 1, 1);
421
422 widget = gtk_radio_button_new_with_mnemonic (NULL, _("C_ell"));
423 gtk_grid_attach (grid, widget, 1, 0, 1, 1);
424 dialog->priv->scope_cell_button = widget;
425
426 g_signal_connect_swapped (
427 widget, "toggled",
428 G_CALLBACK (html_editor_cell_dialog_set_scope), dialog);
429
430 /* Scope: row */
431 widget = gtk_image_new_from_icon_name ("stock_select-row", GTK_ICON_SIZE_BUTTON);
432 gtk_grid_attach (grid, widget, 2, 0, 1, 1);
433
434 widget = gtk_radio_button_new_with_mnemonic_from_widget (
435 GTK_RADIO_BUTTON (dialog->priv->scope_cell_button), _("_Row"));
436 gtk_grid_attach (grid, widget, 3, 0, 1, 1);
437 dialog->priv->scope_row_button = widget;
438
439 g_signal_connect_swapped (
440 widget, "toggled",
441 G_CALLBACK (html_editor_cell_dialog_set_scope), dialog);
442
443 /* Scope: table */
444 widget = gtk_image_new_from_icon_name ("stock_select-table", GTK_ICON_SIZE_BUTTON);
445 gtk_grid_attach (grid, widget, 0, 1, 1, 1);
446
447 widget = gtk_radio_button_new_with_mnemonic_from_widget (
448 GTK_RADIO_BUTTON (dialog->priv->scope_cell_button), _("_Table"));
449 gtk_grid_attach (grid, widget, 1, 1, 1, 1);
450 dialog->priv->scope_table_button = widget;
451
452 g_signal_connect_swapped (
453 widget, "toggled",
454 G_CALLBACK (html_editor_cell_dialog_set_scope), dialog);
455
456 /* Scope: column */
457 widget = gtk_image_new_from_icon_name ("stock_select-column", GTK_ICON_SIZE_BUTTON);
458 gtk_grid_attach (grid, widget, 2, 1, 1, 1);
459
460 widget = gtk_radio_button_new_with_mnemonic_from_widget (
461 GTK_RADIO_BUTTON (dialog->priv->scope_cell_button), _("Col_umn"));
462 gtk_grid_attach (grid, widget, 3, 1, 1, 1);
463 dialog->priv->scope_column_button = widget;
464
465 g_signal_connect_swapped (
466 widget, "toggled",
467 G_CALLBACK (html_editor_cell_dialog_set_scope), dialog);
468
469 /* == Alignment & Behavior == */
470 widget = gtk_label_new ("");
471 gtk_label_set_markup (GTK_LABEL (widget), _("<b>Alignment & Behavior</b>"));
472 gtk_misc_set_alignment (GTK_MISC (widget), 0, 0.5);
473 gtk_grid_attach (main_layout, widget, 0, 2, 1, 1);
474
475 grid = GTK_GRID (gtk_grid_new ());
476 gtk_grid_set_row_spacing (grid, 5);
477 gtk_grid_set_column_spacing (grid, 5);
478 gtk_grid_attach (main_layout, GTK_WIDGET (grid), 0, 3, 1, 1);
479 gtk_widget_set_margin_left (GTK_WIDGET (grid), 10);
480
481 /* Horizontal */
482 widget = gtk_combo_box_text_new ();
483 gtk_widget_set_hexpand (widget, TRUE);
484 gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (widget), "left", _("Left"));
485 gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (widget), "center", _("Center"));
486 gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (widget), "right", _("Right"));
487 gtk_grid_attach (grid, widget, 1, 0, 1, 1);
488 dialog->priv->halign_combo = widget;
489
490 g_signal_connect_swapped (
491 widget, "changed",
492 G_CALLBACK (html_editor_cell_dialog_set_halign), dialog);
493
494 widget = gtk_label_new_with_mnemonic (_("_Horizontal:"));
495 gtk_label_set_justify (GTK_LABEL (widget), GTK_JUSTIFY_RIGHT);
496 gtk_label_set_mnemonic_widget (GTK_LABEL (widget), dialog->priv->halign_combo);
497 gtk_grid_attach (grid, widget, 0, 0, 1, 1);
498
499 /* Vertical */
500 widget = gtk_combo_box_text_new ();
501 gtk_widget_set_hexpand (widget, TRUE);
502 gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (widget), "top", _("Top"));
503 gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (widget), "middle", _("Middle"));
504 gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (widget), "bottom", _("Bottom"));
505 gtk_grid_attach (grid, widget, 3, 0, 1, 1);
506 dialog->priv->valign_combo = widget;
507
508 g_signal_connect_swapped (
509 widget, "changed",
510 G_CALLBACK (html_editor_cell_dialog_set_valign), dialog);
511
512 widget = gtk_label_new_with_mnemonic (_("_Vertical:"));
513 gtk_label_set_justify (GTK_LABEL (widget), GTK_JUSTIFY_RIGHT);
514 gtk_label_set_mnemonic_widget (GTK_LABEL (widget), dialog->priv->valign_combo);
515 gtk_grid_attach (grid, widget, 2, 0, 1, 1);
516
517 /* Wrap Text */
518 widget = gtk_check_button_new_with_mnemonic (_("_Wrap Text"));
519 dialog->priv->wrap_text_check = widget;
520
521 g_signal_connect_swapped (
522 widget, "toggled",
523 G_CALLBACK (html_editor_cell_dialog_set_wrap_text), dialog);
524
525 /* Header Style */
526 widget = gtk_check_button_new_with_mnemonic (_("_Header Style"));
527 dialog->priv->header_style_check = widget;
528
529 g_signal_connect_swapped (
530 widget, "toggled",
531 G_CALLBACK (html_editor_cell_dialog_set_header_style), dialog);
532
533 widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
534 gtk_box_pack_start (GTK_BOX (widget), dialog->priv->wrap_text_check, FALSE, FALSE, 0);
535 gtk_box_pack_start (GTK_BOX (widget), dialog->priv->header_style_check, FALSE, FALSE, 0);
536 gtk_grid_attach (grid, widget, 0, 1, 4, 1);
537
538 /* == Layout == */
539 widget = gtk_label_new ("");
540 gtk_label_set_markup (GTK_LABEL (widget), _("<b>Layout</b>"));
541 gtk_misc_set_alignment (GTK_MISC (widget), 0, 0.5);
542 gtk_grid_attach (main_layout, widget, 0, 4, 1, 1);
543
544 grid = GTK_GRID (gtk_grid_new ());
545 gtk_grid_set_row_spacing (grid, 5);
546 gtk_grid_set_column_spacing (grid, 5);
547 gtk_grid_attach (main_layout, GTK_WIDGET (grid), 0, 5, 1, 1);
548 gtk_widget_set_margin_left (GTK_WIDGET (grid), 10);
549
550 /* Width */
551 widget = gtk_check_button_new_with_mnemonic (_("_Width"));
552 gtk_grid_attach (grid, widget, 0, 0, 1, 1);
553 dialog->priv->width_check = widget;
554
555 widget = gtk_spin_button_new_with_range (1, 100, 1);
556 gtk_spin_button_set_digits (GTK_SPIN_BUTTON (widget), 0);
557 gtk_grid_attach (grid, widget, 1, 0, 1, 1);
558 dialog->priv->width_edit = widget;
559
560 g_signal_connect_swapped (
561 widget, "value-changed",
562 G_CALLBACK (html_editor_cell_dialog_set_width), dialog);
563 e_binding_bind_property (
564 dialog->priv->width_check, "active",
565 widget, "sensitive",
566 G_BINDING_SYNC_CREATE);
567
568 widget = gtk_combo_box_text_new ();
569 gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (widget), "units-px", "px");
570 gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (widget), "units-percent", "%");
571 gtk_grid_attach (grid, widget, 2, 0, 1, 1);
572 dialog->priv->width_units = widget;
573
574 g_signal_connect (
575 widget, "changed",
576 G_CALLBACK (html_editor_cell_dialog_width_units_changed), dialog);
577 e_binding_bind_property (
578 dialog->priv->width_check, "active",
579 widget, "sensitive",
580 G_BINDING_SYNC_CREATE);
581
582 /* Row Span */
583 widget = gtk_spin_button_new_with_range (0, G_MAXUINT, 1);
584 gtk_grid_attach (grid, widget, 4, 0, 1, 1);
585 dialog->priv->row_span_edit = widget;
586
587 g_signal_connect_swapped (
588 widget, "value-changed",
589 G_CALLBACK (html_editor_cell_dialog_set_row_span), dialog);
590
591 widget = gtk_label_new_with_mnemonic (_("Row S_pan:"));
592 gtk_label_set_justify (GTK_LABEL (widget), GTK_JUSTIFY_RIGHT);
593 gtk_label_set_mnemonic_widget (GTK_LABEL (widget), dialog->priv->row_span_edit);
594 gtk_grid_attach (grid, widget, 3, 0, 1, 1);
595
596 /* Column Span */
597 widget = gtk_spin_button_new_with_range (0, G_MAXUINT, 1);
598 gtk_grid_attach (grid, widget, 4, 1, 1, 1);
599 dialog->priv->col_span_edit = widget;
600
601 g_signal_connect_swapped (
602 widget, "value-changed",
603 G_CALLBACK (html_editor_cell_dialog_set_column_span), dialog);
604
605 widget = gtk_label_new_with_mnemonic (_("Co_lumn Span:"));
606 gtk_label_set_justify (GTK_LABEL (widget), GTK_JUSTIFY_RIGHT);
607 gtk_label_set_mnemonic_widget (GTK_LABEL (widget), dialog->priv->col_span_edit);
608 gtk_grid_attach (grid, widget, 3, 1, 1, 1);
609
610 /* == Background == */
611 widget = gtk_label_new ("");
612 gtk_label_set_markup (GTK_LABEL (widget), _("<b>Background</b>"));
613 gtk_misc_set_alignment (GTK_MISC (widget), 0, 0.5);
614 gtk_grid_attach (main_layout, widget, 0, 6, 1, 1);
615
616 grid = GTK_GRID (gtk_grid_new ());
617 gtk_grid_set_row_spacing (grid, 5);
618 gtk_grid_set_column_spacing (grid, 5);
619 gtk_grid_attach (main_layout, GTK_WIDGET (grid), 0, 7, 1, 1);
620 gtk_widget_set_margin_left (GTK_WIDGET (grid), 10);
621
622 /* Color */
623 widget = e_color_combo_new ();
624 e_color_combo_set_default_color (E_COLOR_COMBO (widget), &transparent);
625 e_color_combo_set_default_label (E_COLOR_COMBO (widget), _("Transparent"));
626 gtk_widget_set_hexpand (widget, TRUE);
627 gtk_grid_attach (grid, widget, 1, 0, 1, 1);
628 g_signal_connect_swapped (
629 widget, "notify::current-color",
630 G_CALLBACK (html_editor_cell_dialog_set_background_color), dialog);
631 dialog->priv->background_color_picker = widget;
632
633 widget = gtk_label_new_with_mnemonic (_("C_olor:"));
634 gtk_label_set_justify (GTK_LABEL (widget), GTK_JUSTIFY_RIGHT);
635 gtk_label_set_mnemonic_widget (
636 GTK_LABEL (widget), dialog->priv->background_color_picker);
637 gtk_grid_attach (grid, widget, 0, 0, 1, 1);
638
639 file_filter = gtk_file_filter_new ();
640 gtk_file_filter_set_name (file_filter, _("Images"));
641 gtk_file_filter_add_mime_type (file_filter, "image/*");
642
643 /* Image */
644 if (e_util_is_running_flatpak ()) {
645 widget = gtk_file_chooser_button_new (_("Choose Background Image"), GTK_FILE_CHOOSER_ACTION_OPEN);
646 } else {
647 widget = e_image_chooser_dialog_new (
648 _("Choose Background Image"),
649 GTK_WINDOW (dialog));
650
651 widget = gtk_file_chooser_button_new_with_dialog (widget);
652 }
653
654 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (widget), file_filter);
655 gtk_widget_set_hexpand (widget, TRUE);
656 gtk_grid_attach (grid, widget, 1, 1, 1, 1);
657 g_signal_connect_swapped (
658 widget, "file-set",
659 G_CALLBACK (html_editor_cell_dialog_set_background_image), dialog);
660 dialog->priv->background_image_chooser = widget;
661
662 widget =gtk_label_new_with_mnemonic (_("_Image:"));
663 gtk_label_set_justify (GTK_LABEL (widget), GTK_JUSTIFY_RIGHT);
664 gtk_label_set_mnemonic_widget (
665 GTK_LABEL (widget), dialog->priv->background_image_chooser);
666 gtk_grid_attach (grid, widget, 0, 1, 1, 1);
667
668 box = e_html_editor_dialog_get_button_box (E_HTML_EDITOR_DIALOG (dialog));
669 widget = e_dialog_button_new_with_icon (NULL, _("_Remove image"));
670 g_signal_connect_swapped (
671 widget, "clicked",
672 G_CALLBACK (html_editor_cell_dialog_remove_image), dialog);
673 dialog->priv->remove_image_button = widget;
674
675 gtk_widget_set_sensitive (dialog->priv->remove_image_button, FALSE);
676 gtk_box_pack_start (box, widget, FALSE, FALSE, 5);
677 gtk_box_reorder_child (box, widget, 0);
678
679 gtk_widget_show_all (GTK_WIDGET (main_layout));
680 }
681
682 GtkWidget *
e_html_editor_cell_dialog_new(EHTMLEditor * editor)683 e_html_editor_cell_dialog_new (EHTMLEditor *editor)
684 {
685 return GTK_WIDGET (
686 g_object_new (
687 E_TYPE_HTML_EDITOR_CELL_DIALOG,
688 "editor", editor,
689 "title", _("Cell Properties"),
690 NULL));
691 }
692