1.12.42
[gnumeric.git] / src / dialogs / dialog-so-styled.c
blob5f32b04ea3c29f88823f7a955ffe199331a87f4c
2 /*
3 * dialog-so-styled.c: Pref dialog for objects with a GOStyle 'style' property
5 * Copyright (C) 2004 Jody Goldberg (jody@gnome.org)
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) version 3.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
20 * USA
23 #include <gnumeric-config.h>
24 #include <glib/gi18n-lib.h>
25 #include <gnumeric.h>
26 #include <dialogs/dialogs.h>
28 #include <gui-util.h>
29 #include <dialogs/help.h>
30 #include <wbc-gtk.h>
31 #include <commands.h>
32 #include <sheet-object.h>
33 #include <gnm-so-line.h>
34 #include <goffice/goffice.h>
35 #include <widgets/gnm-text-view.h>
37 typedef struct {
38 GObject *so;
39 WBCGtk *wbcg;
40 GSList *orig_props;
42 so_styled_t extent;
43 } DialogSOStyled;
45 #define GNM_SO_STYLED_KEY "gnm-so-styled-key"
47 static void
48 dialog_so_styled_free (DialogSOStyled *state)
50 go_object_properties_apply (state->so, state->orig_props, TRUE);
51 go_object_properties_free (state->orig_props);
52 g_free (state);
55 static void
56 force_new_style (GObject *so)
58 GOStyle *style;
60 /* Ensure we have a new style object. */
61 g_object_get (so, "style", &style, NULL);
62 g_object_set (so, "style", style, NULL);
63 g_object_unref (style);
66 static void
67 cb_set_props (gpointer a, gpointer b, gpointer data)
69 go_object_properties_apply (a, b, TRUE);
72 static GOUndo *
73 make_undo (GObject *so, GSList *props)
75 return go_undo_binary_new (g_object_ref (so), props,
76 cb_set_props,
77 g_object_unref,
78 (GFreeFunc)go_object_properties_free);
81 static void
82 cb_dialog_so_styled_response (GtkWidget *dialog,
83 gint response_id, DialogSOStyled *state)
85 if (response_id == GTK_RESPONSE_HELP)
86 return;
87 if (response_id == GTK_RESPONSE_OK) {
88 GSList *new_props = go_object_properties_collect (state->so);
89 force_new_style (state->so);
90 cmd_generic (GNM_WBC (state->wbcg),
91 _("Format Object"),
92 make_undo (state->so, state->orig_props),
93 make_undo (state->so, new_props));
94 state->orig_props = NULL;
96 gtk_widget_destroy (dialog);
99 static void
100 cb_dialog_so_styled_text_widget_changed (GnmTextView *gtv, DialogSOStyled *state)
102 gchar *text;
103 PangoAttrList *attr;
105 g_object_get (gtv, "text", &text, NULL);
106 g_object_set (state->so, "text", text, NULL);
107 g_free (text);
109 g_object_get (gtv, "attributes", &attr, NULL);
110 g_object_set (state->so, "markup", attr, NULL);
111 pango_attr_list_unref (attr);
116 static GtkWidget *
117 dialog_so_styled_text_widget (DialogSOStyled *state)
119 GnmTextView *gtv = gnm_text_view_new ();
120 char *strval;
121 PangoAttrList *markup;
123 g_object_get (state->so, "text", &strval, NULL);
124 g_object_set (gtv, "text", (strval == NULL) ? "" : strval, NULL);
125 g_free (strval);
127 g_object_get (state->so, "markup", &markup, NULL);
128 g_object_set (gtv, "attributes", markup, NULL);
129 /* unref? */
131 g_signal_connect (G_OBJECT (gtv), "changed",
132 G_CALLBACK (cb_dialog_so_styled_text_widget_changed), state);
134 return GTK_WIDGET (gtv);
137 static void
138 cb_arrow_changed (GOArrowSel *as,
139 G_GNUC_UNUSED GParamSpec *pspec,
140 DialogSOStyled *state)
142 const char *prop = g_object_get_data (G_OBJECT (as), "prop");
143 g_object_set (state->so,
144 prop, go_arrow_sel_get_arrow (as),
145 NULL);
148 static GtkWidget *
149 dialog_so_styled_line_widget (DialogSOStyled *state, const char *prop)
151 GtkWidget *w = go_arrow_sel_new ();
152 GOArrow *arrow;
154 g_object_get (state->so, prop, &arrow, NULL);
155 go_arrow_sel_set_arrow (GO_ARROW_SEL (w), arrow);
156 g_free (arrow);
158 g_object_set_data_full (G_OBJECT (w), "prop", g_strdup (prop), g_free);
160 g_signal_connect (G_OBJECT (w),
161 "notify::arrow",
162 G_CALLBACK (cb_arrow_changed),
163 state);
165 return w;
168 void
169 dialog_so_styled (WBCGtk *wbcg, GObject *so, GOStyle *default_style,
170 char const *title, so_styled_t extent)
172 DialogSOStyled *state;
173 GtkWidget *dialog, *help, *editor;
174 GOStyle *style;
176 /* Only pop up one copy per workbook */
177 if (gnm_dialog_raise_if_exists (wbcg, GNM_SO_STYLED_KEY)) {
178 g_object_unref (default_style);
179 return;
182 state = g_new0 (DialogSOStyled, 1);
183 state->so = G_OBJECT (so);
184 state->wbcg = wbcg;
185 state->orig_props = go_object_properties_collect (so);
186 force_new_style (state->so);
188 dialog = gtk_dialog_new_with_buttons
189 (title,
190 wbcg_toplevel (state->wbcg),
191 GTK_DIALOG_DESTROY_WITH_PARENT,
192 NULL, NULL);
193 state->extent = extent;
195 gnm_dialog_setup_destroy_handlers (GTK_DIALOG (dialog),
196 state->wbcg,
197 GNM_DIALOG_DESTROY_CURRENT_SHEET_REMOVED);
199 help = gtk_dialog_add_button (GTK_DIALOG (dialog),
200 GTK_STOCK_HELP, GTK_RESPONSE_HELP);
201 gnm_init_help_button (help, "sect-graphics-drawings");
203 gtk_dialog_add_buttons (GTK_DIALOG (dialog),
204 GNM_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
205 GNM_STOCK_OK, GTK_RESPONSE_OK,
206 NULL);
208 g_object_get (so, "style", &style, NULL);
209 editor = go_style_get_editor (style, default_style,
210 GO_CMD_CONTEXT (wbcg), G_OBJECT (so));
211 g_object_unref (style);
213 gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
214 editor, TRUE, TRUE, TRUE);
215 g_object_unref (default_style);
217 if (extent & SO_STYLED_TEXT) {
218 GtkWidget *text_w = dialog_so_styled_text_widget (state);
219 gtk_widget_show_all (text_w);
220 if (GTK_IS_NOTEBOOK (editor))
221 gtk_notebook_append_page (GTK_NOTEBOOK (editor),
222 text_w,
223 gtk_label_new (_("Content")));
224 else
225 gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
226 text_w, TRUE, TRUE, TRUE);
229 if (extent & SO_STYLED_LINE) {
230 GtkWidget *w = dialog_so_styled_line_widget (state, "end-arrow");
231 gtk_widget_show_all (w);
232 if (GTK_IS_NOTEBOOK (editor))
233 gtk_notebook_append_page (GTK_NOTEBOOK (editor), w,
234 gtk_label_new (_("Head")));
235 else
236 gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
237 w, TRUE, TRUE, TRUE);
240 if (extent & SO_STYLED_LINE) {
241 GtkWidget *w = dialog_so_styled_line_widget (state, "start-arrow");
242 gtk_widget_show_all (w);
243 if (GTK_IS_NOTEBOOK (editor))
244 gtk_notebook_append_page (GTK_NOTEBOOK (editor), w,
245 gtk_label_new (_("Tail")));
246 else
247 gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
248 w, TRUE, TRUE, TRUE);
251 g_signal_connect (G_OBJECT (dialog), "response",
252 G_CALLBACK (cb_dialog_so_styled_response), state);
253 gnm_keyed_dialog (state->wbcg, GTK_WINDOW (dialog),
254 GNM_SO_STYLED_KEY);
255 g_object_set_data_full (G_OBJECT (dialog),
256 "state", state, (GDestroyNotify) dialog_so_styled_free);
257 go_gtk_nonmodal_dialog (wbcg_toplevel (state->wbcg),
258 GTK_WINDOW (dialog));
259 wbc_gtk_attach_guru (state->wbcg, dialog);
260 gtk_widget_show (dialog);