1 /*
2 * e-editor-selection.c
3 *
4 * This program 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 of the License, or (at your option) version 3.
8 *
9 * This program 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 the program; if not, see <http://www.gnu.org/licenses/>
16 *
17 */
18
19 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
22
23 #include "biji-editor-selection.h"
24
25 #include <string.h>
26 #include <stdlib.h>
27 #include <ctype.h>
28
29 struct _EEditorSelectionPrivate {
30 WebKitWebView *webview;
31 WebKitEditorTypingAttributes attrs;
32 };
33
34 G_DEFINE_TYPE_WITH_PRIVATE (
35 EEditorSelection,
36 e_editor_selection,
37 G_TYPE_OBJECT
38 );
39
40 enum {
41 PROP_0,
42 PROP_WEBVIEW,
43 PROP_BOLD,
44 PROP_ITALIC,
45 PROP_STRIKE_THROUGH,
46 };
47
48 static void
check_and_update_typing_attr(EEditorSelection * selection,WebKitEditorTypingAttributes attrs,unsigned attr,const char * poperty_name)49 check_and_update_typing_attr (EEditorSelection *selection,
50 WebKitEditorTypingAttributes attrs,
51 unsigned attr,
52 const char *poperty_name)
53 {
54 if (attrs & attr) {
55 if (!(selection->priv->attrs & attr)) {
56 selection->priv->attrs |= attr;
57 g_object_notify (G_OBJECT (selection), poperty_name);
58 }
59 } else if (!(attrs & attr)) {
60 if (selection->priv->attrs & attr) {
61 selection->priv->attrs &= ~attr;
62 g_object_notify (G_OBJECT (selection), poperty_name);
63 }
64 }
65 }
66
67 static void
webview_typing_attributes_changed(WebKitEditorState * editor,GParamSpec * spec,EEditorSelection * selection)68 webview_typing_attributes_changed (WebKitEditorState *editor,
69 GParamSpec *spec,
70 EEditorSelection *selection)
71 {
72 WebKitEditorTypingAttributes attrs;
73
74 attrs = webkit_editor_state_get_typing_attributes (editor);
75
76 g_object_freeze_notify (G_OBJECT (selection));
77 check_and_update_typing_attr (selection, attrs, WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD, "bold");
78 check_and_update_typing_attr (selection, attrs, WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC, "italic");
79 check_and_update_typing_attr (selection, attrs, WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH, "strike-through");
80 g_object_thaw_notify (G_OBJECT (selection));
81 }
82
83 static void
editor_selection_set_webview(EEditorSelection * selection,WebKitWebView * webview)84 editor_selection_set_webview (EEditorSelection *selection,
85 WebKitWebView *webview)
86 {
87 WebKitEditorState *editor;
88
89 g_clear_object (&selection->priv->webview);
90 selection->priv->webview = g_object_ref (webview);
91
92 editor = webkit_web_view_get_editor_state (webview);
93 selection->priv->attrs = webkit_editor_state_get_typing_attributes (editor);
94 g_signal_connect (
95 editor, "notify::typing-attributes",
96 G_CALLBACK (webview_typing_attributes_changed), selection);
97 }
98
99
100 static void
e_editor_selection_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)101 e_editor_selection_get_property (GObject *object,
102 guint property_id,
103 GValue *value,
104 GParamSpec *pspec)
105 {
106 EEditorSelection *selection = E_EDITOR_SELECTION (object);
107
108 switch (property_id) {
109 case PROP_BOLD:
110 g_value_set_boolean (value,
111 e_editor_selection_get_bold (selection));
112 break;
113
114 case PROP_ITALIC:
115 g_value_set_boolean (value,
116 e_editor_selection_get_italic (selection));
117 break;
118
119 case PROP_STRIKE_THROUGH:
120 g_value_set_boolean (value,
121 e_editor_selection_get_strike_through (selection));
122 break;
123
124 default:
125 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
126 break;
127 }
128 }
129
130 static void
e_editor_selection_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)131 e_editor_selection_set_property (GObject *object,
132 guint property_id,
133 const GValue *value,
134 GParamSpec *pspec)
135 {
136 EEditorSelection *selection = E_EDITOR_SELECTION (object);
137
138 switch (property_id) {
139 case PROP_WEBVIEW:
140 editor_selection_set_webview (
141 selection, g_value_get_object (value));
142 break;
143
144 case PROP_BOLD:
145 e_editor_selection_set_bold (
146 selection, g_value_get_boolean (value));
147 break;
148
149 case PROP_ITALIC:
150 e_editor_selection_set_italic (
151 selection, g_value_get_boolean (value));
152 break;
153
154 case PROP_STRIKE_THROUGH:
155 e_editor_selection_set_strike_through (
156 selection, g_value_get_boolean (value));
157 break;
158
159 default:
160 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
161 }
162 }
163
164 static void
e_editor_selection_finalize(GObject * object)165 e_editor_selection_finalize (GObject *object)
166 {
167 EEditorSelection *selection = E_EDITOR_SELECTION (object);
168
169 g_object_unref (selection->priv->webview);
170
171 G_OBJECT_CLASS (e_editor_selection_parent_class)->finalize (object);
172 }
173
174 static void
e_editor_selection_class_init(EEditorSelectionClass * klass)175 e_editor_selection_class_init (EEditorSelectionClass *klass)
176 {
177 GObjectClass *object_class;
178
179 object_class = G_OBJECT_CLASS (klass);
180 object_class->get_property = e_editor_selection_get_property;
181 object_class->set_property = e_editor_selection_set_property;
182 object_class->finalize = e_editor_selection_finalize;
183
184 g_object_class_install_property (
185 object_class,
186 PROP_WEBVIEW,
187 g_param_spec_object (
188 "webview",
189 NULL,
190 NULL,
191 WEBKIT_TYPE_WEB_VIEW,
192 G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
193
194 g_object_class_install_property (
195 object_class,
196 PROP_BOLD,
197 g_param_spec_boolean (
198 "bold",
199 NULL,
200 NULL,
201 FALSE,
202 G_PARAM_READWRITE));
203
204 g_object_class_install_property (
205 object_class,
206 PROP_ITALIC,
207 g_param_spec_boolean (
208 "italic",
209 NULL,
210 NULL,
211 FALSE,
212 G_PARAM_READWRITE));
213
214 g_object_class_install_property (
215 object_class,
216 PROP_STRIKE_THROUGH,
217 g_param_spec_boolean (
218 "strike-through",
219 NULL,
220 NULL,
221 FALSE,
222 G_PARAM_READWRITE));
223 }
224
225
226 static void
e_editor_selection_init(EEditorSelection * selection)227 e_editor_selection_init (EEditorSelection *selection)
228 {
229 selection->priv = e_editor_selection_get_instance_private (selection);
230 }
231
232 EEditorSelection *
e_editor_selection_new(WebKitWebView * parent_view)233 e_editor_selection_new (WebKitWebView *parent_view)
234 {
235 g_return_val_if_fail (WEBKIT_IS_WEB_VIEW (parent_view), NULL);
236
237 return g_object_new (
238 E_TYPE_EDITOR_SELECTION,
239 "webview", parent_view, NULL);
240 }
241
242 gboolean
e_editor_selection_get_bold(EEditorSelection * selection)243 e_editor_selection_get_bold (EEditorSelection *selection)
244 {
245 g_return_val_if_fail (E_IS_EDITOR_SELECTION (selection), FALSE);
246
247 return selection->priv->attrs & WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD;
248 }
249
250 void
e_editor_selection_set_bold(EEditorSelection * selection,gboolean bold)251 e_editor_selection_set_bold (EEditorSelection *selection,
252 gboolean bold)
253 {
254 g_return_if_fail (E_IS_EDITOR_SELECTION (selection));
255
256 if ((e_editor_selection_get_bold (selection) ? TRUE : FALSE)
257 == (bold ? TRUE : FALSE)) {
258 return;
259 }
260
261 webkit_web_view_execute_editing_command (selection->priv->webview, "Bold");
262 }
263
264 gboolean
e_editor_selection_get_italic(EEditorSelection * selection)265 e_editor_selection_get_italic (EEditorSelection *selection)
266 {
267 g_return_val_if_fail (E_IS_EDITOR_SELECTION (selection), FALSE);
268
269 return selection->priv->attrs & WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC;
270 }
271
272 void
e_editor_selection_set_italic(EEditorSelection * selection,gboolean italic)273 e_editor_selection_set_italic (EEditorSelection *selection,
274 gboolean italic)
275 {
276 g_return_if_fail (E_IS_EDITOR_SELECTION (selection));
277
278 if ((e_editor_selection_get_italic (selection) ? TRUE : FALSE)
279 == (italic ? TRUE : FALSE)) {
280 return;
281 }
282
283 webkit_web_view_execute_editing_command (selection->priv->webview, "Italic");
284 }
285
286 gboolean
e_editor_selection_get_strike_through(EEditorSelection * selection)287 e_editor_selection_get_strike_through (EEditorSelection *selection)
288 {
289 g_return_val_if_fail (E_IS_EDITOR_SELECTION (selection), FALSE);
290
291 return selection->priv->attrs & WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH;
292 }
293
294 void
e_editor_selection_set_strike_through(EEditorSelection * selection,gboolean strike_through)295 e_editor_selection_set_strike_through (EEditorSelection *selection,
296 gboolean strike_through)
297 {
298 g_return_if_fail (E_IS_EDITOR_SELECTION (selection));
299
300 if ((e_editor_selection_get_strike_through (selection) ? TRUE : FALSE)
301 == (strike_through? TRUE : FALSE)) {
302 return;
303 }
304
305 webkit_web_view_execute_editing_command (selection->priv->webview, "Strikethrough");
306 }
307