Merge lp:~aauzi/midori/fix-1177553-3 into lp:midori
- fix-1177553-3
- Merge into trunk
Status: | Superseded |
---|---|
Proposed branch: | lp:~aauzi/midori/fix-1177553-3 |
Merge into: | lp:midori |
Diff against target: |
1940 lines (+1825/-37) 5 files modified
katze/katze-cellrenderer2pixbufs.c (+359/-0) katze/katze-cellrenderer2pixbufs.h (+59/-0) katze/katze-cellrenderer2texts.c (+1136/-0) katze/katze-cellrenderer2texts.h (+71/-0) midori/midori-browser.c (+200/-37) |
To merge this branch: | bzr merge lp:~aauzi/midori/fix-1177553-3 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Cris Dywan | Needs Fixing | ||
Review via email: mp+172463@code.launchpad.net |
This proposal has been superseded by a proposal from 2013-07-18.
Commit message
Description of the change
This last step for Bookmark folder tree reflection addresses the bookmarks edit dialog combo box.
The combo box is reworked to display a tree view of the bookmark folders.
Folder icons are added and give, in the combo box, a display of folders that aims to have consistent aspect with bookmark bar, bookmark menu and bookmark panel.
The combo box population algorithm is reworked to handle the case of sub-folders referring to a previously populated parent folder.
After this process, remaining items of the retrieved folders list are orphaned folder entries.
NOTE: such orphaned folders are actually created when deleting non empty folders.
It looks like the statements "FOREIGN KEY(parentid) REFERENCES bookmarks(id) ON DELETE CASCADE" used in the bookmarks table structure does not work as expected. This should should be traced in another bug.
NOTE 1: I finally dropped the idea of displaying the folder's path in the combo box button.
First, the solution I had was only working with GTK2 and, second, I think it's more consistent this way.
- 6245. By André Auzi
-
merge lp:midori
- 6246. By André Auzi
-
manage a way to render combobox opened folder differently
- 6247. By André Auzi
-
implement only combo box text cell renderer by derivation
Unmerged revisions
Preview Diff
1 | === added file 'katze/katze-cellrenderer2pixbufs.c' |
2 | --- katze/katze-cellrenderer2pixbufs.c 1970-01-01 00:00:00 +0000 |
3 | +++ katze/katze-cellrenderer2pixbufs.c 2013-07-18 19:43:28 +0000 |
4 | @@ -0,0 +1,359 @@ |
5 | +/* |
6 | + Copyright (C) 2008-2013 Christian Dywan <christian@twotoasts.de> |
7 | + |
8 | + This library is free software; you can redistribute it and/or |
9 | + modify it under the terms of the GNU Lesser General Public |
10 | + License as published by the Free Software Foundation; either |
11 | + version 2.1 of the License, or (at your option) any later version. |
12 | + |
13 | + See the file COPYING for the full license text. |
14 | +*/ |
15 | + |
16 | +#include "katze-cellrenderer2pixbufs.h" |
17 | + |
18 | +#include "marshal.h" |
19 | + |
20 | +#include <gdk/gdk.h> |
21 | + |
22 | +#define P_(String) (String) |
23 | +#define I_(String) (String) |
24 | +#define GTK_PARAM_READABLE G_PARAM_READABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB |
25 | +#define GTK_PARAM_WRITABLE G_PARAM_WRITABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB |
26 | +#define GTK_PARAM_READWRITE G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB |
27 | + |
28 | + |
29 | +static void |
30 | +katze_cell_renderer_2pixbufs_finalize (GObject* object); |
31 | +static void |
32 | +katze_cell_renderer_2pixbufs_get_property (GObject* object, |
33 | + guint param_id, |
34 | + GValue* value, |
35 | + GParamSpec* pspec); |
36 | +static void |
37 | +katze_cell_renderer_2pixbufs_set_property (GObject* object, |
38 | + guint param_id, |
39 | + const GValue* value, |
40 | + GParamSpec* pspec); |
41 | +static void |
42 | +katze_cell_renderer_2pixbufs_get_size (GtkCellRenderer* cell, |
43 | + GtkWidget* widget, |
44 | + GdkRectangle* cell_area, |
45 | + gint* x_offset, |
46 | + gint* y_offset, |
47 | + gint* width, |
48 | + gint* height); |
49 | +static void |
50 | +#if GTK_CHECK_VERSION(3,0,0) |
51 | +katze_cell_renderer_2pixbufs_render (GtkCellRenderer *cell, |
52 | + cairo_t* cr, |
53 | + GtkWidget *widget, |
54 | + GdkRectangle *background_area, |
55 | + GdkRectangle *cell_area, |
56 | + GtkCellRendererState flags); |
57 | +#else |
58 | +katze_cell_renderer_2pixbufs_render (GtkCellRenderer *cell, |
59 | + GdkDrawable *window, |
60 | + GtkWidget *widget, |
61 | + GdkRectangle *background_area, |
62 | + GdkRectangle *cell_area, |
63 | + GdkRectangle *expose_area, |
64 | + GtkCellRendererState flags); |
65 | +#endif |
66 | + |
67 | +enum { |
68 | + PROP_0, |
69 | + PROP_PIXBUF_EXPANDER_OPEN, |
70 | + PROP_PIXBUF_EXPANDER_CLOSED, |
71 | + PROP_FOLLOW_STATE, |
72 | +}; |
73 | + |
74 | +#define KATZE_CELL_RENDERER_2PIXBUFS_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), KATZE_TYPE_CELL_RENDERER_2PIXBUFS, KatzeCellRenderer2PixbufsPrivate)) |
75 | + |
76 | +typedef struct _KatzeCellRenderer2PixbufsPrivate KatzeCellRenderer2PixbufsPrivate; |
77 | +struct _KatzeCellRenderer2PixbufsPrivate |
78 | +{ |
79 | + GtkCellRendererPixbuf* cellpixbuf; |
80 | + |
81 | + guint markup_set : 1; |
82 | + guint alternate_markup_set : 1; |
83 | +}; |
84 | + |
85 | +G_DEFINE_TYPE (KatzeCellRenderer2Pixbufs, katze_cell_renderer_2pixbufs, GTK_TYPE_CELL_RENDERER) |
86 | + |
87 | +static void |
88 | +katze_cell_renderer_2pixbufs_notify (GObject *gobject, |
89 | + GParamSpec *pspec, |
90 | + KatzeCellRenderer2Pixbufs *cellpixbuf) |
91 | +{ |
92 | + if (!g_strcmp0(P_("text"), pspec->name) |
93 | + || !g_strcmp0(P_("attributes"), pspec->name)) |
94 | + return; |
95 | + |
96 | + g_object_notify (G_OBJECT (cellpixbuf), pspec->name); |
97 | +} |
98 | + |
99 | +static void |
100 | +katze_cell_renderer_2pixbufs_init (KatzeCellRenderer2Pixbufs *cellpixbuf) |
101 | +{ |
102 | + GValue true_value = {0}; |
103 | + KatzeCellRenderer2PixbufsPrivate *priv; |
104 | + |
105 | + priv = KATZE_CELL_RENDERER_2PIXBUFS_GET_PRIVATE (cellpixbuf); |
106 | + |
107 | + priv->cellpixbuf = GTK_CELL_RENDERER_PIXBUF (gtk_cell_renderer_pixbuf_new()); |
108 | + g_object_ref (priv->cellpixbuf); |
109 | + |
110 | + g_value_init (&true_value, G_TYPE_BOOLEAN); |
111 | + g_value_set_boolean (&true_value, TRUE); |
112 | + g_object_set_property (G_OBJECT (priv->cellpixbuf), "is-expander", &true_value); |
113 | + g_value_reset (&true_value); |
114 | + |
115 | + g_signal_connect (priv->cellpixbuf, "notify", |
116 | + G_CALLBACK (katze_cell_renderer_2pixbufs_notify), |
117 | + cellpixbuf); |
118 | +} |
119 | + |
120 | +static void |
121 | +katze_cell_renderer_2pixbufs_class_init (KatzeCellRenderer2PixbufsClass *class) |
122 | +{ |
123 | + GObjectClass *object_class = G_OBJECT_CLASS (class); |
124 | + GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (class); |
125 | + |
126 | + object_class->finalize = katze_cell_renderer_2pixbufs_finalize; |
127 | + |
128 | + object_class->get_property = katze_cell_renderer_2pixbufs_get_property; |
129 | + object_class->set_property = katze_cell_renderer_2pixbufs_set_property; |
130 | + |
131 | + cell_class->get_size = katze_cell_renderer_2pixbufs_get_size; |
132 | + cell_class->render = katze_cell_renderer_2pixbufs_render; |
133 | + |
134 | + g_object_class_install_property (object_class, |
135 | + PROP_PIXBUF_EXPANDER_OPEN, |
136 | + g_param_spec_object ("pixbuf-expander-open", |
137 | + P_("Pixbuf Expander Open"), |
138 | + P_("Pixbuf for open expander"), |
139 | + GDK_TYPE_PIXBUF, |
140 | + GTK_PARAM_READWRITE)); |
141 | + |
142 | + g_object_class_install_property (object_class, |
143 | + PROP_PIXBUF_EXPANDER_CLOSED, |
144 | + g_param_spec_object ("pixbuf-expander-closed", |
145 | + P_("Pixbuf Expander Closed"), |
146 | + P_("Pixbuf for closed expander"), |
147 | + GDK_TYPE_PIXBUF, |
148 | + GTK_PARAM_READWRITE)); |
149 | + |
150 | + /** |
151 | + * GtkCellRendererPixbuf:follow-state: |
152 | + * |
153 | + * Specifies whether the rendered pixbuf should be colorized |
154 | + * according to the #GtkCellRendererState. |
155 | + * |
156 | + * Since: 2.8 |
157 | + */ |
158 | + g_object_class_install_property (object_class, |
159 | + PROP_FOLLOW_STATE, |
160 | + g_param_spec_boolean ("follow-state", |
161 | + P_("Follow State"), |
162 | + P_("Whether the rendered pixbuf should be " |
163 | + "colorized according to the state"), |
164 | + FALSE, |
165 | + GTK_PARAM_READWRITE)); |
166 | + |
167 | + g_type_class_add_private (object_class, sizeof (KatzeCellRenderer2PixbufsPrivate)); |
168 | +} |
169 | + |
170 | +static void |
171 | +katze_cell_renderer_2pixbufs_finalize (GObject *object) |
172 | +{ |
173 | + KatzeCellRenderer2Pixbufs *cellpixbuf = KATZE_CELL_RENDERER_2PIXBUFS (object); |
174 | + KatzeCellRenderer2PixbufsPrivate *priv; |
175 | + |
176 | + priv = KATZE_CELL_RENDERER_2PIXBUFS_GET_PRIVATE (object); |
177 | + |
178 | + g_object_unref (priv->cellpixbuf); |
179 | + |
180 | + G_OBJECT_CLASS (katze_cell_renderer_2pixbufs_parent_class)->finalize (object); |
181 | +} |
182 | + |
183 | +static const gchar* const cell_pixbuf_renderer_property_names[] = |
184 | +{ |
185 | + /* GtkCellRendererPixbuf args */ |
186 | + "pixbuf-expander-open", |
187 | + "pixbuf-expander-closed", |
188 | + "follow-state" |
189 | +}; |
190 | + |
191 | +static void |
192 | +katze_cell_renderer_2pixbufs_get_property (GObject* object, |
193 | + guint param_id, |
194 | + GValue* value, |
195 | + GParamSpec* pspec) |
196 | +{ |
197 | + KatzeCellRenderer2Pixbufs *cellpixbuf = KATZE_CELL_RENDERER_2PIXBUFS (object); |
198 | + KatzeCellRenderer2PixbufsPrivate *priv; |
199 | + |
200 | + priv = KATZE_CELL_RENDERER_2PIXBUFS_GET_PRIVATE (object); |
201 | + |
202 | + switch (param_id) |
203 | + { |
204 | + case PROP_PIXBUF_EXPANDER_OPEN: |
205 | + case PROP_PIXBUF_EXPANDER_CLOSED: |
206 | + case PROP_FOLLOW_STATE: |
207 | + g_object_get_property (G_OBJECT (priv->cellpixbuf), cell_pixbuf_renderer_property_names[param_id-PROP_PIXBUF_EXPANDER_OPEN], value); |
208 | + break; |
209 | + default: |
210 | + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); |
211 | + break; |
212 | + } |
213 | +} |
214 | + |
215 | + |
216 | +static void |
217 | +katze_cell_renderer_2pixbufs_set_property (GObject* object, |
218 | + guint param_id, |
219 | + const GValue* value, |
220 | + GParamSpec* pspec) |
221 | +{ |
222 | + KatzeCellRenderer2Pixbufs *cellpixbuf = KATZE_CELL_RENDERER_2PIXBUFS (object); |
223 | + KatzeCellRenderer2PixbufsPrivate *priv; |
224 | + |
225 | + priv = KATZE_CELL_RENDERER_2PIXBUFS_GET_PRIVATE (object); |
226 | + |
227 | + switch (param_id) |
228 | + { |
229 | + case PROP_PIXBUF_EXPANDER_OPEN: |
230 | + case PROP_PIXBUF_EXPANDER_CLOSED: |
231 | + case PROP_FOLLOW_STATE: |
232 | + g_object_set_property (G_OBJECT (priv->cellpixbuf), cell_pixbuf_renderer_property_names[param_id-PROP_PIXBUF_EXPANDER_OPEN], value); |
233 | + break; |
234 | + |
235 | + default: |
236 | + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); |
237 | + break; |
238 | + } |
239 | +} |
240 | + |
241 | +/** |
242 | + * katze_cell_renderer_2pixbufs_new: |
243 | + * |
244 | + * Creates a new #KatzeCellRenderer2Pixbufs. Adjust how text is drawn using |
245 | + * object properties. Object properties can be |
246 | + * set globally (with g_object_set()). Also, with #GtkTreeViewColumn, |
247 | + * you can bind a property to a value in a #GtkTreeModel. For example, |
248 | + * you can bind the "text" property on the cell renderer to a string |
249 | + * value in the model, thus rendering a different string in each row |
250 | + * of the #GtkTreeView |
251 | + * |
252 | + * Return value: the new cell renderer |
253 | + **/ |
254 | +GtkCellRenderer * |
255 | +katze_cell_renderer_2pixbufs_new (void) |
256 | +{ |
257 | + return g_object_new (KATZE_TYPE_CELL_RENDERER_2PIXBUFS, NULL); |
258 | +} |
259 | + |
260 | +static GtkCellRendererState |
261 | +set_pixbuf(KatzeCellRenderer2Pixbufs* cellpixbuf, |
262 | + GtkWidget* widget, |
263 | + KatzeCellRenderer2PixbufsPrivate* priv, |
264 | + GtkCellRendererState flags) |
265 | +{ |
266 | + GtkWidget* pwidget = gtk_widget_get_parent (widget); |
267 | + gboolean alternate = FALSE; |
268 | + GValue false_value = {0}; |
269 | + GValue true_value = {0}; |
270 | + g_value_init (&false_value, G_TYPE_BOOLEAN); |
271 | + g_value_init (&true_value, G_TYPE_BOOLEAN); |
272 | + g_value_set_boolean (&false_value, FALSE); |
273 | + g_value_set_boolean (&true_value, TRUE); |
274 | + |
275 | + if (GTK_IS_MENU_ITEM (pwidget)) |
276 | + { |
277 | + GtkWidget* menu = gtk_widget_get_parent (pwidget); |
278 | + GList* items; |
279 | + |
280 | + if (menu |
281 | + && (GTK_IS_MENU (menu)) |
282 | + && (items = gtk_container_get_children (GTK_CONTAINER (menu))) |
283 | + && (GTK_WIDGET (items->data) == pwidget) |
284 | + && (g_list_length (items) > 1) |
285 | + && (GTK_IS_SEPARATOR_MENU_ITEM (g_list_next (items)->data))) |
286 | + { |
287 | + alternate = TRUE; |
288 | + } |
289 | + } |
290 | + |
291 | + g_object_set_property (G_OBJECT (priv->cellpixbuf), "is-expander", &true_value); |
292 | + if (alternate) |
293 | + { |
294 | + flags |= (1<<6) /* GTK_CELL_RENDERER_EXPANDED */ ; |
295 | + g_object_set_property (G_OBJECT (priv->cellpixbuf), "is-expanded", &true_value); |
296 | + } |
297 | + else |
298 | + { |
299 | + flags |= (1<<5) /* GTK_CELL_RENDERER_EXPANDABLE*/ ; |
300 | + g_object_set_property (G_OBJECT (priv->cellpixbuf), "is-expanded", &false_value); |
301 | + } |
302 | + return flags; |
303 | +} |
304 | + |
305 | +static void |
306 | +katze_cell_renderer_2pixbufs_get_size (GtkCellRenderer *cell, |
307 | + GtkWidget *widget, |
308 | + GdkRectangle *cell_area, |
309 | + gint *x_offset, |
310 | + gint *y_offset, |
311 | + gint *width, |
312 | + gint *height) |
313 | +{ |
314 | + KatzeCellRenderer2Pixbufs *cellpixbuf = (KatzeCellRenderer2Pixbufs *) cell; |
315 | + KatzeCellRenderer2PixbufsPrivate *priv; |
316 | + priv = KATZE_CELL_RENDERER_2PIXBUFS_GET_PRIVATE (cell); |
317 | + |
318 | + gtk_cell_renderer_get_size (GTK_CELL_RENDERER (priv->cellpixbuf), |
319 | + widget, cell_area, |
320 | + x_offset, y_offset, width, height); |
321 | +} |
322 | + |
323 | +static void |
324 | +#if GTK_CHECK_VERSION(3,0,0) |
325 | +katze_cell_renderer_2pixbufs_render (GtkCellRenderer *cell, |
326 | + cairo_t* cr, |
327 | + GtkWidget *widget, |
328 | + GdkRectangle *background_area, |
329 | + GdkRectangle *cell_area, |
330 | + GtkCellRendererState flags) |
331 | +#else |
332 | +katze_cell_renderer_2pixbufs_render (GtkCellRenderer *cell, |
333 | + GdkDrawable *window, |
334 | + GtkWidget *widget, |
335 | + GdkRectangle *background_area, |
336 | + GdkRectangle *cell_area, |
337 | + GdkRectangle *expose_area, |
338 | + GtkCellRendererState flags) |
339 | +#endif |
340 | +{ |
341 | + KatzeCellRenderer2Pixbufs *cellpixbuf = (KatzeCellRenderer2Pixbufs *) cell; |
342 | + KatzeCellRenderer2PixbufsPrivate *priv; |
343 | + |
344 | + priv = KATZE_CELL_RENDERER_2PIXBUFS_GET_PRIVATE (cell); |
345 | + |
346 | + |
347 | +#if GTK_CHECK_VERSION(3,0,0) |
348 | + gtk_cell_renderer_render (GTK_CELL_RENDERER (priv->cellpixbuf), |
349 | + cr, |
350 | + widget, |
351 | + background_area, |
352 | + cell_area, |
353 | + set_pixbuf (cellpixbuf, widget, priv, flags)); |
354 | +#else |
355 | + gtk_cell_renderer_render (GTK_CELL_RENDERER (priv->cellpixbuf), |
356 | + window, |
357 | + widget, |
358 | + background_area, |
359 | + cell_area, |
360 | + expose_area, |
361 | + set_pixbuf (cellpixbuf, widget, priv, flags)); |
362 | +#endif |
363 | +} |
364 | |
365 | === added file 'katze/katze-cellrenderer2pixbufs.h' |
366 | --- katze/katze-cellrenderer2pixbufs.h 1970-01-01 00:00:00 +0000 |
367 | +++ katze/katze-cellrenderer2pixbufs.h 2013-07-18 19:43:28 +0000 |
368 | @@ -0,0 +1,59 @@ |
369 | +/* |
370 | + Copyright (C) 2008-2013 Christian Dywan <christian@twotoasts.de> |
371 | + |
372 | + This library is free software; you can redistribute it and/or |
373 | + modify it under the terms of the GNU Lesser General Public |
374 | + License as published by the Free Software Foundation; either |
375 | + version 2.1 of the License, or (at your option) any later version. |
376 | + |
377 | + See the file COPYING for the full license text. |
378 | +*/ |
379 | + |
380 | +#ifndef __KATZE_CELL_RENDERER_2PIXBUFS_H__ |
381 | +#define __KATZE_CELL_RENDERER_2PIXBUFS_H__ |
382 | + |
383 | + |
384 | +#include <gtk/gtk.h> |
385 | + |
386 | +#ifndef GSEAL |
387 | +#define GSEAL(String) String |
388 | +#endif |
389 | + |
390 | + |
391 | +G_BEGIN_DECLS |
392 | + |
393 | + |
394 | +#define KATZE_TYPE_CELL_RENDERER_2PIXBUFS (katze_cell_renderer_2pixbufs_get_type ()) |
395 | +#define KATZE_CELL_RENDERER_2PIXBUFS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), KATZE_TYPE_CELL_RENDERER_2PIXBUFS, KatzeCellRenderer2Pixbufs)) |
396 | +#define KATZE_CELL_RENDERER_2PIXBUFS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), KATZE_TYPE_CELL_RENDERER_2PIXBUFS, KatzeCellRenderer2PixbufsClass)) |
397 | +#define KATZE_IS_CELL_RENDERER_2PIXBUFS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), KATZE_TYPE_CELL_RENDERER_2PIXBUFS)) |
398 | +#define KATZE_IS_CELL_RENDERER_2PIXBUFS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), KATZE_TYPE_CELL_RENDERER_2PIXBUFS)) |
399 | +#define KATZE_CELL_RENDERER_2PIXBUFS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), KATZE_TYPE_CELL_RENDERER_2PIXBUFS, GtkCellRenderer2PixbufsClass)) |
400 | + |
401 | +typedef struct _KatzeCellRenderer2Pixbufs KatzeCellRenderer2Pixbufs; |
402 | +typedef struct _KatzeCellRenderer2PixbufsClass KatzeCellRenderer2PixbufsClass; |
403 | + |
404 | +struct _KatzeCellRenderer2Pixbufs |
405 | +{ |
406 | + GtkCellRenderer parent; |
407 | +}; |
408 | + |
409 | +struct _KatzeCellRenderer2PixbufsClass |
410 | +{ |
411 | + GtkCellRendererClass parent_class; |
412 | + |
413 | + /* Padding for future expansion */ |
414 | + void (*_gtk_reserved1) (void); |
415 | + void (*_gtk_reserved2) (void); |
416 | + void (*_gtk_reserved3) (void); |
417 | + void (*_gtk_reserved4) (void); |
418 | +}; |
419 | + |
420 | +GType katze_cell_renderer_2pixbufs_get_type (void) G_GNUC_CONST; |
421 | +GtkCellRenderer *katze_cell_renderer_2pixbufs_new (void); |
422 | + |
423 | + |
424 | +G_END_DECLS |
425 | + |
426 | + |
427 | +#endif /* __KATZE_CELL_RENDERER_2PIXBUFS_H__ */ |
428 | |
429 | === added file 'katze/katze-cellrenderer2texts.c' |
430 | --- katze/katze-cellrenderer2texts.c 1970-01-01 00:00:00 +0000 |
431 | +++ katze/katze-cellrenderer2texts.c 2013-07-18 19:43:28 +0000 |
432 | @@ -0,0 +1,1136 @@ |
433 | +/* |
434 | + Copyright (C) 2008-2013 Christian Dywan <christian@twotoasts.de> |
435 | + |
436 | + This library is free software; you can redistribute it and/or |
437 | + modify it under the terms of the GNU Lesser General Public |
438 | + License as published by the Free Software Foundation; either |
439 | + version 2.1 of the License, or (at your option) any later version. |
440 | + |
441 | + See the file COPYING for the full license text. |
442 | +*/ |
443 | + |
444 | +#include "katze-cellrenderer2texts.h" |
445 | + |
446 | +#include "marshal.h" |
447 | + |
448 | +#include <gdk/gdk.h> |
449 | + |
450 | +#define P_(String) (String) |
451 | +#define I_(String) (String) |
452 | +#define GTK_PARAM_READABLE G_PARAM_READABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB |
453 | +#define GTK_PARAM_WRITABLE G_PARAM_WRITABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB |
454 | +#define GTK_PARAM_READWRITE G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB |
455 | + |
456 | + |
457 | +static void |
458 | +katze_cell_renderer_2texts_finalize (GObject* object); |
459 | + |
460 | +static void |
461 | +katze_cell_renderer_2texts_get_property (GObject* object, |
462 | + guint param_id, |
463 | + GValue* value, |
464 | + GParamSpec* pspec); |
465 | +static void |
466 | +katze_cell_renderer_2texts_set_property (GObject* object, |
467 | + guint param_id, |
468 | + const GValue* value, |
469 | + GParamSpec* pspec); |
470 | +static void |
471 | +katze_cell_renderer_2texts_get_size (GtkCellRenderer* cell, |
472 | + GtkWidget* widget, |
473 | + GdkRectangle* cell_area, |
474 | + gint* x_offset, |
475 | + gint* y_offset, |
476 | + gint* width, |
477 | + gint* height); |
478 | +static void |
479 | +#if GTK_CHECK_VERSION(3,0,0) |
480 | +katze_cell_renderer_2texts_render (GtkCellRenderer *cell, |
481 | + cairo_t* cr, |
482 | + GtkWidget *widget, |
483 | + GdkRectangle *background_area, |
484 | + GdkRectangle *cell_area, |
485 | + GtkCellRendererState flags); |
486 | +#else |
487 | +katze_cell_renderer_2texts_render (GtkCellRenderer *cell, |
488 | + GdkDrawable *window, |
489 | + GtkWidget *widget, |
490 | + GdkRectangle *background_area, |
491 | + GdkRectangle *cell_area, |
492 | + GdkRectangle *expose_area, |
493 | + GtkCellRendererState flags); |
494 | +#endif |
495 | + |
496 | +static GtkCellEditable * |
497 | +katze_cell_renderer_2texts_start_editing (GtkCellRenderer *cell, |
498 | + GdkEvent *event, |
499 | + GtkWidget *widget, |
500 | + const gchar *path, |
501 | + GdkRectangle *background_area, |
502 | + GdkRectangle *cell_area, |
503 | + GtkCellRendererState flags); |
504 | + |
505 | +enum { |
506 | + EDITED, |
507 | + LAST_SIGNAL |
508 | +}; |
509 | + |
510 | +enum { |
511 | + PROP_0, |
512 | + |
513 | + PROP_TEXT, |
514 | + PROP_MARKUP, |
515 | + PROP_ATTRIBUTES, |
516 | + PROP_ALTERNATE_TEXT, |
517 | + PROP_ALTERNATE_MARKUP, |
518 | + PROP_ALTERNATE_ATTRIBUTES, |
519 | + |
520 | + /* GtkCellRendererText args */ |
521 | + PROP_SINGLE_PARAGRAPH_MODE, |
522 | + PROP_WIDTH_CHARS, |
523 | + PROP_WRAP_WIDTH, |
524 | + PROP_ALIGN, |
525 | + |
526 | + /* Style args */ |
527 | + PROP_BACKGROUND, |
528 | + PROP_FOREGROUND, |
529 | + PROP_BACKGROUND_GDK, |
530 | + PROP_FOREGROUND_GDK, |
531 | + PROP_FONT, |
532 | + PROP_FONT_DESC, |
533 | + PROP_FAMILY, |
534 | + PROP_STYLE, |
535 | + PROP_VARIANT, |
536 | + PROP_WEIGHT, |
537 | + PROP_STRETCH, |
538 | + PROP_SIZE, |
539 | + PROP_SIZE_POINTS, |
540 | + PROP_SCALE, |
541 | + PROP_EDITABLE, |
542 | + PROP_STRIKETHROUGH, |
543 | + PROP_UNDERLINE, |
544 | + PROP_RISE, |
545 | + PROP_LANGUAGE, |
546 | + PROP_ELLIPSIZE, |
547 | + PROP_WRAP_MODE, |
548 | + |
549 | + /* Whether-a-style-arg-is-set args */ |
550 | + PROP_BACKGROUND_SET, |
551 | + PROP_FOREGROUND_SET, |
552 | + PROP_FAMILY_SET, |
553 | + PROP_STYLE_SET, |
554 | + PROP_VARIANT_SET, |
555 | + PROP_WEIGHT_SET, |
556 | + PROP_STRETCH_SET, |
557 | + PROP_SIZE_SET, |
558 | + PROP_SCALE_SET, |
559 | + PROP_EDITABLE_SET, |
560 | + PROP_STRIKETHROUGH_SET, |
561 | + PROP_UNDERLINE_SET, |
562 | + PROP_RISE_SET, |
563 | + PROP_LANGUAGE_SET, |
564 | + PROP_ELLIPSIZE_SET, |
565 | + PROP_ALIGN_SET |
566 | +}; |
567 | + |
568 | +static guint _2texts_cell_renderer_signals [LAST_SIGNAL]; |
569 | + |
570 | +#define KATZE_CELL_RENDERER_2TEXTS_PATH "gtk-cell-renderer-text-path" |
571 | + |
572 | +#define KATZE_CELL_RENDERER_2TEXTS_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), KATZE_TYPE_CELL_RENDERER_2TEXTS, KatzeCellRenderer2textsPrivate)) |
573 | + |
574 | +typedef struct _KatzeCellRenderer2textsPrivate KatzeCellRenderer2textsPrivate; |
575 | +struct _KatzeCellRenderer2textsPrivate |
576 | +{ |
577 | + GtkCellRendererText* celltext; |
578 | + |
579 | + guint markup_set : 1; |
580 | + guint alternate_markup_set : 1; |
581 | +}; |
582 | + |
583 | +G_DEFINE_TYPE (KatzeCellRenderer2texts, katze_cell_renderer_2texts, GTK_TYPE_CELL_RENDERER) |
584 | + |
585 | +static void |
586 | +katze_cell_renderer_2texts_notify (GObject *gobject, |
587 | + GParamSpec *pspec, |
588 | + KatzeCellRenderer2texts *celltext) |
589 | +{ |
590 | + if (!g_strcmp0(P_("text"), pspec->name) |
591 | + || !g_strcmp0(P_("attributes"), pspec->name)) |
592 | + return; |
593 | + |
594 | + g_object_notify (G_OBJECT (celltext), pspec->name); |
595 | +} |
596 | + |
597 | +static void |
598 | +katze_cell_renderer_2texts_init (KatzeCellRenderer2texts *celltext) |
599 | +{ |
600 | + KatzeCellRenderer2textsPrivate *priv; |
601 | + |
602 | + priv = KATZE_CELL_RENDERER_2TEXTS_GET_PRIVATE (celltext); |
603 | + |
604 | + priv->celltext = GTK_CELL_RENDERER_TEXT (gtk_cell_renderer_text_new()); |
605 | + g_object_ref (priv->celltext); |
606 | + |
607 | + priv->markup_set = FALSE; |
608 | + priv->alternate_markup_set = FALSE; |
609 | + |
610 | + g_signal_connect (priv->celltext, "notify", |
611 | + G_CALLBACK (katze_cell_renderer_2texts_notify), |
612 | + celltext); |
613 | +} |
614 | + |
615 | +static void |
616 | +katze_cell_renderer_2texts_class_init (KatzeCellRenderer2textsClass *class) |
617 | +{ |
618 | + GObjectClass *object_class = G_OBJECT_CLASS (class); |
619 | + GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (class); |
620 | + |
621 | + object_class->finalize = katze_cell_renderer_2texts_finalize; |
622 | + |
623 | + object_class->get_property = katze_cell_renderer_2texts_get_property; |
624 | + object_class->set_property = katze_cell_renderer_2texts_set_property; |
625 | + |
626 | + cell_class->get_size = katze_cell_renderer_2texts_get_size; |
627 | + cell_class->render = katze_cell_renderer_2texts_render; |
628 | + cell_class->start_editing = katze_cell_renderer_2texts_start_editing; |
629 | + |
630 | + g_object_class_install_property (object_class, |
631 | + PROP_TEXT, |
632 | + g_param_spec_string ("text", |
633 | + P_("Text"), |
634 | + P_("Text to render"), |
635 | + NULL, |
636 | + GTK_PARAM_READWRITE)); |
637 | + |
638 | + g_object_class_install_property (object_class, |
639 | + PROP_ALTERNATE_TEXT, |
640 | + g_param_spec_string ("alternate-text", |
641 | + P_("Alternate text"), |
642 | + P_("Text to render if 2texts is opened"), |
643 | + NULL, |
644 | + GTK_PARAM_READWRITE)); |
645 | + |
646 | + g_object_class_install_property (object_class, |
647 | + PROP_MARKUP, |
648 | + g_param_spec_string ("markup", |
649 | + P_("Markup"), |
650 | + P_("Marked up text to render"), |
651 | + NULL, |
652 | + GTK_PARAM_WRITABLE)); |
653 | + |
654 | + g_object_class_install_property (object_class, |
655 | + PROP_ALTERNATE_MARKUP, |
656 | + g_param_spec_string ("alternate-markup", |
657 | + P_("Markup"), |
658 | + P_("Marked up text to render if 2texts is opened"), |
659 | + NULL, |
660 | + GTK_PARAM_WRITABLE)); |
661 | + |
662 | + g_object_class_install_property (object_class, |
663 | + PROP_ATTRIBUTES, |
664 | + g_param_spec_boxed ("attributes", |
665 | + P_("Attributes"), |
666 | + P_("A list of style attributes to apply to the text of the renderer"), |
667 | + PANGO_TYPE_ATTR_LIST, |
668 | + GTK_PARAM_READWRITE)); |
669 | + |
670 | + g_object_class_install_property (object_class, |
671 | + PROP_ALTERNATE_ATTRIBUTES, |
672 | + g_param_spec_boxed ("alternate-attributes", |
673 | + P_("Attributes"), |
674 | + P_("A list of style attributes to apply to the text of the renderer"), |
675 | + PANGO_TYPE_ATTR_LIST, |
676 | + GTK_PARAM_READWRITE)); |
677 | + |
678 | + g_object_class_install_property (object_class, |
679 | + PROP_SINGLE_PARAGRAPH_MODE, |
680 | + g_param_spec_boolean ("single-paragraph-mode", |
681 | + P_("Single Paragraph Mode"), |
682 | + P_("Whether or not to keep all text in a single paragraph"), |
683 | + FALSE, |
684 | + GTK_PARAM_READWRITE)); |
685 | + |
686 | + |
687 | + g_object_class_install_property (object_class, |
688 | + PROP_BACKGROUND, |
689 | + g_param_spec_string ("background", |
690 | + P_("Background color name"), |
691 | + P_("Background color as a string"), |
692 | + NULL, |
693 | + GTK_PARAM_WRITABLE)); |
694 | + |
695 | + g_object_class_install_property (object_class, |
696 | + PROP_BACKGROUND_GDK, |
697 | + g_param_spec_boxed ("background-gdk", |
698 | + P_("Background color"), |
699 | + P_("Background color as a GdkColor"), |
700 | + GDK_TYPE_COLOR, |
701 | + GTK_PARAM_READWRITE)); |
702 | + |
703 | + g_object_class_install_property (object_class, |
704 | + PROP_FOREGROUND, |
705 | + g_param_spec_string ("foreground", |
706 | + P_("Foreground color name"), |
707 | + P_("Foreground color as a string"), |
708 | + NULL, |
709 | + GTK_PARAM_WRITABLE)); |
710 | + |
711 | + g_object_class_install_property (object_class, |
712 | + PROP_FOREGROUND_GDK, |
713 | + g_param_spec_boxed ("foreground-gdk", |
714 | + P_("Foreground color"), |
715 | + P_("Foreground color as a GdkColor"), |
716 | + GDK_TYPE_COLOR, |
717 | + GTK_PARAM_READWRITE)); |
718 | + |
719 | + |
720 | + g_object_class_install_property (object_class, |
721 | + PROP_EDITABLE, |
722 | + g_param_spec_boolean ("editable", |
723 | + P_("Editable"), |
724 | + P_("Whether the text can be modified by the user"), |
725 | + FALSE, |
726 | + GTK_PARAM_READWRITE)); |
727 | + |
728 | + g_object_class_install_property (object_class, |
729 | + PROP_FONT, |
730 | + g_param_spec_string ("font", |
731 | + P_("Font"), |
732 | + P_("Font description as a string, e.g. \"Sans Italic 12\""), |
733 | + NULL, |
734 | + GTK_PARAM_READWRITE)); |
735 | + |
736 | + g_object_class_install_property (object_class, |
737 | + PROP_FONT_DESC, |
738 | + g_param_spec_boxed ("font-desc", |
739 | + P_("Font"), |
740 | + P_("Font description as a PangoFontDescription struct"), |
741 | + PANGO_TYPE_FONT_DESCRIPTION, |
742 | + GTK_PARAM_READWRITE)); |
743 | + |
744 | + |
745 | + g_object_class_install_property (object_class, |
746 | + PROP_FAMILY, |
747 | + g_param_spec_string ("family", |
748 | + P_("Font family"), |
749 | + P_("Name of the font family, e.g. Sans, Helvetica, Times, Monospace"), |
750 | + NULL, |
751 | + GTK_PARAM_READWRITE)); |
752 | + |
753 | + g_object_class_install_property (object_class, |
754 | + PROP_STYLE, |
755 | + g_param_spec_enum ("style", |
756 | + P_("Font style"), |
757 | + P_("Font style"), |
758 | + PANGO_TYPE_STYLE, |
759 | + PANGO_STYLE_NORMAL, |
760 | + GTK_PARAM_READWRITE)); |
761 | + |
762 | + g_object_class_install_property (object_class, |
763 | + PROP_VARIANT, |
764 | + g_param_spec_enum ("variant", |
765 | + P_("Font variant"), |
766 | + P_("Font variant"), |
767 | + PANGO_TYPE_VARIANT, |
768 | + PANGO_VARIANT_NORMAL, |
769 | + GTK_PARAM_READWRITE)); |
770 | + |
771 | + g_object_class_install_property (object_class, |
772 | + PROP_WEIGHT, |
773 | + g_param_spec_int ("weight", |
774 | + P_("Font weight"), |
775 | + P_("Font weight"), |
776 | + 0, |
777 | + G_MAXINT, |
778 | + PANGO_WEIGHT_NORMAL, |
779 | + GTK_PARAM_READWRITE)); |
780 | + |
781 | + g_object_class_install_property (object_class, |
782 | + PROP_STRETCH, |
783 | + g_param_spec_enum ("stretch", |
784 | + P_("Font stretch"), |
785 | + P_("Font stretch"), |
786 | + PANGO_TYPE_STRETCH, |
787 | + PANGO_STRETCH_NORMAL, |
788 | + GTK_PARAM_READWRITE)); |
789 | + |
790 | + g_object_class_install_property (object_class, |
791 | + PROP_SIZE, |
792 | + g_param_spec_int ("size", |
793 | + P_("Font size"), |
794 | + P_("Font size"), |
795 | + 0, |
796 | + G_MAXINT, |
797 | + 0, |
798 | + GTK_PARAM_READWRITE)); |
799 | + |
800 | + g_object_class_install_property (object_class, |
801 | + PROP_SIZE_POINTS, |
802 | + g_param_spec_double ("size-points", |
803 | + P_("Font points"), |
804 | + P_("Font size in points"), |
805 | + 0.0, |
806 | + G_MAXDOUBLE, |
807 | + 0.0, |
808 | + GTK_PARAM_READWRITE)); |
809 | + |
810 | + g_object_class_install_property (object_class, |
811 | + PROP_SCALE, |
812 | + g_param_spec_double ("scale", |
813 | + P_("Font scale"), |
814 | + P_("Font scaling factor"), |
815 | + 0.0, |
816 | + G_MAXDOUBLE, |
817 | + 1.0, |
818 | + GTK_PARAM_READWRITE)); |
819 | + |
820 | + g_object_class_install_property (object_class, |
821 | + PROP_RISE, |
822 | + g_param_spec_int ("rise", |
823 | + P_("Rise"), |
824 | + P_("Offset of text above the baseline " |
825 | + "(below the baseline if rise is negative)"), |
826 | + -G_MAXINT, |
827 | + G_MAXINT, |
828 | + 0, |
829 | + GTK_PARAM_READWRITE)); |
830 | + |
831 | + |
832 | + g_object_class_install_property (object_class, |
833 | + PROP_STRIKETHROUGH, |
834 | + g_param_spec_boolean ("strikethrough", |
835 | + P_("Strikethrough"), |
836 | + P_("Whether to strike through the text"), |
837 | + FALSE, |
838 | + GTK_PARAM_READWRITE)); |
839 | + |
840 | + g_object_class_install_property (object_class, |
841 | + PROP_UNDERLINE, |
842 | + g_param_spec_enum ("underline", |
843 | + P_("Underline"), |
844 | + P_("Style of underline for this text"), |
845 | + PANGO_TYPE_UNDERLINE, |
846 | + PANGO_UNDERLINE_NONE, |
847 | + GTK_PARAM_READWRITE)); |
848 | + |
849 | + g_object_class_install_property (object_class, |
850 | + PROP_LANGUAGE, |
851 | + g_param_spec_string ("language", |
852 | + P_("Language"), |
853 | + P_("The language this text is in, as an ISO code. " |
854 | + "Pango can use this as a hint when rendering the text. " |
855 | + "If you don't understand this parameter, you probably don't need it"), |
856 | + NULL, |
857 | + GTK_PARAM_READWRITE)); |
858 | + |
859 | + |
860 | + /** |
861 | + * KatzeCellRenderer2texts:ellipsize: |
862 | + * |
863 | + * Specifies the preferred place to ellipsize the string, if the cell renderer |
864 | + * does not have enough room to display the entire string. Setting it to |
865 | + * %PANGO_ELLIPSIZE_NONE turns off ellipsizing. See the wrap-width property |
866 | + * for another way of making the text fit into a given width. |
867 | + * |
868 | + * Since: 2.6 |
869 | + */ |
870 | + g_object_class_install_property (object_class, |
871 | + PROP_ELLIPSIZE, |
872 | + g_param_spec_enum ("ellipsize", |
873 | + P_("Ellipsize"), |
874 | + P_("The preferred place to ellipsize the string, " |
875 | + "if the cell renderer does not have enough room " |
876 | + "to display the entire string"), |
877 | + PANGO_TYPE_ELLIPSIZE_MODE, |
878 | + PANGO_ELLIPSIZE_NONE, |
879 | + GTK_PARAM_READWRITE)); |
880 | + |
881 | + /** |
882 | + * KatzeCellRenderer2texts:width-chars: |
883 | + * |
884 | + * The desired width of the cell, in characters. If this property is set to |
885 | + * -1, the width will be calculated automatically, otherwise the cell will |
886 | + * request either 3 characters or the property value, whichever is greater. |
887 | + * |
888 | + * Since: 2.6 |
889 | + **/ |
890 | + g_object_class_install_property (object_class, |
891 | + PROP_WIDTH_CHARS, |
892 | + g_param_spec_int ("width-chars", |
893 | + P_("Width In Characters"), |
894 | + P_("The desired width of the label, in characters"), |
895 | + -1, |
896 | + G_MAXINT, |
897 | + -1, |
898 | + GTK_PARAM_READWRITE)); |
899 | + |
900 | + /** |
901 | + * KatzeCellRenderer2texts:wrap-mode: |
902 | + * |
903 | + * Specifies how to break the string into multiple lines, if the cell |
904 | + * renderer does not have enough room to display the entire string. |
905 | + * This property has no effect unless the wrap-width property is set. |
906 | + * |
907 | + * Since: 2.8 |
908 | + */ |
909 | + g_object_class_install_property (object_class, |
910 | + PROP_WRAP_MODE, |
911 | + g_param_spec_enum ("wrap-mode", |
912 | + P_("Wrap mode"), |
913 | + P_("How to break the string into multiple lines, " |
914 | + "if the cell renderer does not have enough room " |
915 | + "to display the entire string"), |
916 | + PANGO_TYPE_WRAP_MODE, |
917 | + PANGO_WRAP_CHAR, |
918 | + GTK_PARAM_READWRITE)); |
919 | + |
920 | + /** |
921 | + * KatzeCellRenderer2texts:wrap-width: |
922 | + * |
923 | + * Specifies the width at which the text is wrapped. The wrap-mode property can |
924 | + * be used to influence at what character positions the line breaks can be placed. |
925 | + * Setting wrap-width to -1 turns wrapping off. |
926 | + * |
927 | + * Since: 2.8 |
928 | + */ |
929 | + g_object_class_install_property (object_class, |
930 | + PROP_WRAP_WIDTH, |
931 | + g_param_spec_int ("wrap-width", |
932 | + P_("Wrap width"), |
933 | + P_("The width at which the text is wrapped"), |
934 | + -1, |
935 | + G_MAXINT, |
936 | + -1, |
937 | + GTK_PARAM_READWRITE)); |
938 | + |
939 | + /** |
940 | + * KatzeCellRenderer2texts:alignment: |
941 | + * |
942 | + * Specifies how to align the lines of text with respect to each other. |
943 | + * |
944 | + * Note that this property describes how to align the lines of text in |
945 | + * case there are several of them. The "xalign" property of #GtkCellRenderer, |
946 | + * on the other hand, sets the horizontal alignment of the whole text. |
947 | + * |
948 | + * Since: 2.10 |
949 | + */ |
950 | + g_object_class_install_property (object_class, |
951 | + PROP_ALIGN, |
952 | + g_param_spec_enum ("alignment", |
953 | + P_("Alignment"), |
954 | + P_("How to align the lines"), |
955 | + PANGO_TYPE_ALIGNMENT, |
956 | + PANGO_ALIGN_LEFT, |
957 | + GTK_PARAM_READWRITE)); |
958 | + |
959 | + /* Style props are set or not */ |
960 | + |
961 | +#define ADD_SET_PROP(propname, propval, nick, blurb) g_object_class_install_property (object_class, propval, g_param_spec_boolean (propname, nick, blurb, FALSE, GTK_PARAM_READWRITE)) |
962 | + |
963 | + ADD_SET_PROP ("background-set", PROP_BACKGROUND_SET, |
964 | + P_("Background set"), |
965 | + P_("Whether this tag affects the background color")); |
966 | + |
967 | + ADD_SET_PROP ("foreground-set", PROP_FOREGROUND_SET, |
968 | + P_("Foreground set"), |
969 | + P_("Whether this tag affects the foreground color")); |
970 | + |
971 | + ADD_SET_PROP ("editable-set", PROP_EDITABLE_SET, |
972 | + P_("Editability set"), |
973 | + P_("Whether this tag affects text editability")); |
974 | + |
975 | + ADD_SET_PROP ("family-set", PROP_FAMILY_SET, |
976 | + P_("Font family set"), |
977 | + P_("Whether this tag affects the font family")); |
978 | + |
979 | + ADD_SET_PROP ("style-set", PROP_STYLE_SET, |
980 | + P_("Font style set"), |
981 | + P_("Whether this tag affects the font style")); |
982 | + |
983 | + ADD_SET_PROP ("variant-set", PROP_VARIANT_SET, |
984 | + P_("Font variant set"), |
985 | + P_("Whether this tag affects the font variant")); |
986 | + |
987 | + ADD_SET_PROP ("weight-set", PROP_WEIGHT_SET, |
988 | + P_("Font weight set"), |
989 | + P_("Whether this tag affects the font weight")); |
990 | + |
991 | + ADD_SET_PROP ("stretch-set", PROP_STRETCH_SET, |
992 | + P_("Font stretch set"), |
993 | + P_("Whether this tag affects the font stretch")); |
994 | + |
995 | + ADD_SET_PROP ("size-set", PROP_SIZE_SET, |
996 | + P_("Font size set"), |
997 | + P_("Whether this tag affects the font size")); |
998 | + |
999 | + ADD_SET_PROP ("scale-set", PROP_SCALE_SET, |
1000 | + P_("Font scale set"), |
1001 | + P_("Whether this tag scales the font size by a factor")); |
1002 | + |
1003 | + ADD_SET_PROP ("rise-set", PROP_RISE_SET, |
1004 | + P_("Rise set"), |
1005 | + P_("Whether this tag affects the rise")); |
1006 | + |
1007 | + ADD_SET_PROP ("strikethrough-set", PROP_STRIKETHROUGH_SET, |
1008 | + P_("Strikethrough set"), |
1009 | + P_("Whether this tag affects strikethrough")); |
1010 | + |
1011 | + ADD_SET_PROP ("underline-set", PROP_UNDERLINE_SET, |
1012 | + P_("Underline set"), |
1013 | + P_("Whether this tag affects underlining")); |
1014 | + |
1015 | + ADD_SET_PROP ("language-set", PROP_LANGUAGE_SET, |
1016 | + P_("Language set"), |
1017 | + P_("Whether this tag affects the language the text is rendered as")); |
1018 | + |
1019 | + ADD_SET_PROP ("ellipsize-set", PROP_ELLIPSIZE_SET, |
1020 | + P_("Ellipsize set"), |
1021 | + P_("Whether this tag affects the ellipsize mode")); |
1022 | + |
1023 | + ADD_SET_PROP ("align-set", PROP_ALIGN_SET, |
1024 | + P_("Align set"), |
1025 | + P_("Whether this tag affects the alignment mode")); |
1026 | + |
1027 | + /** |
1028 | + * KatzeCellRenderer2texts::edited |
1029 | + * @renderer: the object which received the signal |
1030 | + * @path: the path identifying the edited cell |
1031 | + * @new_text: the new text |
1032 | + * |
1033 | + * This signal is emitted after @renderer has been edited. |
1034 | + * |
1035 | + * It is the responsibility of the application to update the model |
1036 | + * and store @new_text at the position indicated by @path. |
1037 | + */ |
1038 | + _2texts_cell_renderer_signals [EDITED] = |
1039 | + g_signal_new (I_("edited"), |
1040 | + G_OBJECT_CLASS_TYPE (object_class), |
1041 | + G_SIGNAL_RUN_LAST, |
1042 | + G_STRUCT_OFFSET (KatzeCellRenderer2textsClass, edited), |
1043 | + NULL, NULL, |
1044 | + midori_cclosure_marshal_VOID__STRING_STRING, |
1045 | + G_TYPE_NONE, 2, |
1046 | + G_TYPE_STRING, |
1047 | + G_TYPE_STRING); |
1048 | + |
1049 | + g_type_class_add_private (object_class, sizeof (KatzeCellRenderer2textsPrivate)); |
1050 | +} |
1051 | + |
1052 | +static void |
1053 | +katze_cell_renderer_2texts_finalize (GObject *object) |
1054 | +{ |
1055 | + KatzeCellRenderer2texts *celltext = KATZE_CELL_RENDERER_2TEXTS (object); |
1056 | + KatzeCellRenderer2textsPrivate *priv; |
1057 | + |
1058 | + priv = KATZE_CELL_RENDERER_2TEXTS_GET_PRIVATE (object); |
1059 | + |
1060 | + g_free (celltext->text); |
1061 | + if (celltext->extra_attrs) |
1062 | + pango_attr_list_unref (celltext->extra_attrs); |
1063 | + |
1064 | + g_free (celltext->alternate_text); |
1065 | + if (celltext->alternate_extra_attrs) |
1066 | + pango_attr_list_unref (celltext->alternate_extra_attrs); |
1067 | + |
1068 | + g_object_unref (priv->celltext); |
1069 | + |
1070 | + G_OBJECT_CLASS (katze_cell_renderer_2texts_parent_class)->finalize (object); |
1071 | +} |
1072 | + |
1073 | +static const gchar* const cell_text_renderer_property_names[] = |
1074 | +{ |
1075 | + /* GtkCellRendererText args */ |
1076 | + "single-paragraph-mode", |
1077 | + "width-chars", |
1078 | + "wrap-width", |
1079 | + "align", |
1080 | + |
1081 | + /* Style args */ |
1082 | + "background", |
1083 | + "foreground", |
1084 | + "background-gdk", |
1085 | + "foreground-gdk", |
1086 | + "font", |
1087 | + "font-desc", |
1088 | + "family", |
1089 | + "style", |
1090 | + "variant", |
1091 | + "weight", |
1092 | + "stretch", |
1093 | + "size", |
1094 | + "size-points", |
1095 | + "scale", |
1096 | + "editable", |
1097 | + "strikethrough", |
1098 | + "underline", |
1099 | + "rise", |
1100 | + "language", |
1101 | + "ellipsize", |
1102 | + "wrap-mode", |
1103 | + |
1104 | + /* Whether-a-style-arg-is-set args */ |
1105 | + "background-set", |
1106 | + "foreground-set", |
1107 | + "family-set", |
1108 | + "style-set", |
1109 | + "variant-set", |
1110 | + "weight-set", |
1111 | + "stretch-set", |
1112 | + "size-set", |
1113 | + "scale-set", |
1114 | + "editable-set", |
1115 | + "strikethrough-set", |
1116 | + "underline-set", |
1117 | + "rise-set", |
1118 | + "language-set", |
1119 | + "ellipsize-set", |
1120 | + "align-set" |
1121 | +}; |
1122 | + |
1123 | +static void |
1124 | +katze_cell_renderer_2texts_get_property (GObject* object, |
1125 | + guint param_id, |
1126 | + GValue* value, |
1127 | + GParamSpec* pspec) |
1128 | +{ |
1129 | + KatzeCellRenderer2texts *celltext = KATZE_CELL_RENDERER_2TEXTS (object); |
1130 | + KatzeCellRenderer2textsPrivate *priv; |
1131 | + |
1132 | + priv = KATZE_CELL_RENDERER_2TEXTS_GET_PRIVATE (object); |
1133 | + |
1134 | + switch (param_id) |
1135 | + { |
1136 | + case PROP_TEXT: |
1137 | + g_value_set_string (value, celltext->text); |
1138 | + break; |
1139 | + |
1140 | + case PROP_ATTRIBUTES: |
1141 | + g_value_set_boxed (value, celltext->extra_attrs); |
1142 | + break; |
1143 | + |
1144 | + case PROP_ALTERNATE_TEXT: |
1145 | + g_value_set_string (value, celltext->alternate_text); |
1146 | + break; |
1147 | + |
1148 | + case PROP_ALTERNATE_ATTRIBUTES: |
1149 | + g_value_set_boxed (value, celltext->alternate_extra_attrs); |
1150 | + break; |
1151 | + |
1152 | + case PROP_SINGLE_PARAGRAPH_MODE: |
1153 | + case PROP_BACKGROUND_GDK: |
1154 | + case PROP_FOREGROUND_GDK: |
1155 | + case PROP_FONT: |
1156 | + case PROP_FONT_DESC: |
1157 | + case PROP_FAMILY: |
1158 | + case PROP_STYLE: |
1159 | + case PROP_VARIANT: |
1160 | + case PROP_WEIGHT: |
1161 | + case PROP_STRETCH: |
1162 | + case PROP_SIZE: |
1163 | + case PROP_SIZE_POINTS: |
1164 | + case PROP_SCALE: |
1165 | + case PROP_EDITABLE: |
1166 | + case PROP_STRIKETHROUGH: |
1167 | + case PROP_UNDERLINE: |
1168 | + case PROP_RISE: |
1169 | + case PROP_LANGUAGE: |
1170 | + case PROP_ELLIPSIZE: |
1171 | + case PROP_WRAP_MODE: |
1172 | + case PROP_WRAP_WIDTH: |
1173 | + case PROP_ALIGN: |
1174 | + case PROP_BACKGROUND_SET: |
1175 | + case PROP_FOREGROUND_SET: |
1176 | + case PROP_FAMILY_SET: |
1177 | + case PROP_STYLE_SET: |
1178 | + case PROP_VARIANT_SET: |
1179 | + case PROP_WEIGHT_SET: |
1180 | + case PROP_STRETCH_SET: |
1181 | + case PROP_SIZE_SET: |
1182 | + case PROP_SCALE_SET: |
1183 | + case PROP_EDITABLE_SET: |
1184 | + case PROP_STRIKETHROUGH_SET: |
1185 | + case PROP_UNDERLINE_SET: |
1186 | + case PROP_RISE_SET: |
1187 | + case PROP_LANGUAGE_SET: |
1188 | + case PROP_ELLIPSIZE_SET: |
1189 | + case PROP_ALIGN_SET: |
1190 | + case PROP_WIDTH_CHARS: |
1191 | + case PROP_BACKGROUND: |
1192 | + case PROP_FOREGROUND: |
1193 | + g_object_get_property (G_OBJECT (priv->celltext), cell_text_renderer_property_names[param_id-PROP_SINGLE_PARAGRAPH_MODE], value); |
1194 | + break; |
1195 | + case PROP_MARKUP: |
1196 | + case PROP_ALTERNATE_MARKUP: |
1197 | + default: |
1198 | + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); |
1199 | + break; |
1200 | + } |
1201 | +} |
1202 | + |
1203 | + |
1204 | +static void |
1205 | +katze_cell_renderer_2texts_set_property (GObject* object, |
1206 | + guint param_id, |
1207 | + const GValue* value, |
1208 | + GParamSpec* pspec) |
1209 | +{ |
1210 | + KatzeCellRenderer2texts *celltext = KATZE_CELL_RENDERER_2TEXTS (object); |
1211 | + KatzeCellRenderer2textsPrivate *priv; |
1212 | + |
1213 | + priv = KATZE_CELL_RENDERER_2TEXTS_GET_PRIVATE (object); |
1214 | + |
1215 | + switch (param_id) |
1216 | + { |
1217 | + case PROP_TEXT: |
1218 | + g_free (celltext->text); |
1219 | + |
1220 | + if (priv->markup_set) |
1221 | + { |
1222 | + if (celltext->extra_attrs) |
1223 | + pango_attr_list_unref (celltext->extra_attrs); |
1224 | + celltext->extra_attrs = NULL; |
1225 | + priv->markup_set = FALSE; |
1226 | + } |
1227 | + |
1228 | + celltext->text = g_value_dup_string (value); |
1229 | + g_object_notify (object, "text"); |
1230 | + break; |
1231 | + case PROP_ATTRIBUTES: |
1232 | + if (celltext->extra_attrs) |
1233 | + pango_attr_list_unref (celltext->extra_attrs); |
1234 | + |
1235 | + celltext->extra_attrs = g_value_get_boxed (value); |
1236 | + if (celltext->extra_attrs) |
1237 | + pango_attr_list_ref (celltext->extra_attrs); |
1238 | + break; |
1239 | + case PROP_MARKUP: |
1240 | + { |
1241 | + const gchar *str; |
1242 | + gchar *text = NULL; |
1243 | + GError *error = NULL; |
1244 | + PangoAttrList *attrs = NULL; |
1245 | + |
1246 | + str = g_value_get_string (value); |
1247 | + if (str && !pango_parse_markup (str, |
1248 | + -1, |
1249 | + 0, |
1250 | + &attrs, |
1251 | + &text, |
1252 | + NULL, |
1253 | + &error)) |
1254 | + { |
1255 | + g_warning ("Failed to set text from markup due to error parsing markup: %s", |
1256 | + error->message); |
1257 | + g_error_free (error); |
1258 | + return; |
1259 | + } |
1260 | + |
1261 | + g_free (celltext->text); |
1262 | + |
1263 | + if (celltext->extra_attrs) |
1264 | + pango_attr_list_unref (celltext->extra_attrs); |
1265 | + |
1266 | + celltext->text = text; |
1267 | + celltext->extra_attrs = attrs; |
1268 | + priv->markup_set = TRUE; |
1269 | + } |
1270 | + break; |
1271 | + |
1272 | + case PROP_ALTERNATE_TEXT: |
1273 | + g_free (celltext->alternate_text); |
1274 | + |
1275 | + if (priv->alternate_markup_set) |
1276 | + { |
1277 | + if (celltext->alternate_extra_attrs) |
1278 | + pango_attr_list_unref (celltext->alternate_extra_attrs); |
1279 | + celltext->alternate_extra_attrs = NULL; |
1280 | + priv->alternate_markup_set = FALSE; |
1281 | + } |
1282 | + |
1283 | + celltext->alternate_text = g_value_dup_string (value); |
1284 | + g_object_notify (object, "alternate-text"); |
1285 | + break; |
1286 | + case PROP_ALTERNATE_ATTRIBUTES: |
1287 | + if (celltext->alternate_extra_attrs) |
1288 | + pango_attr_list_unref (celltext->alternate_extra_attrs); |
1289 | + |
1290 | + celltext->alternate_extra_attrs = g_value_get_boxed (value); |
1291 | + if (celltext->alternate_extra_attrs) |
1292 | + pango_attr_list_ref (celltext->alternate_extra_attrs); |
1293 | + break; |
1294 | + case PROP_ALTERNATE_MARKUP: |
1295 | + { |
1296 | + const gchar *str; |
1297 | + gchar *text = NULL; |
1298 | + GError *error = NULL; |
1299 | + PangoAttrList *attrs = NULL; |
1300 | + |
1301 | + str = g_value_get_string (value); |
1302 | + if (str && !pango_parse_markup (str, |
1303 | + -1, |
1304 | + 0, |
1305 | + &attrs, |
1306 | + &text, |
1307 | + NULL, |
1308 | + &error)) |
1309 | + { |
1310 | + g_warning ("Failed to set text from markup due to error parsing markup: %s", |
1311 | + error->message); |
1312 | + g_error_free (error); |
1313 | + return; |
1314 | + } |
1315 | + |
1316 | + g_free (celltext->alternate_text); |
1317 | + |
1318 | + if (celltext->alternate_extra_attrs) |
1319 | + pango_attr_list_unref (celltext->alternate_extra_attrs); |
1320 | + |
1321 | + celltext->alternate_text = text; |
1322 | + celltext->alternate_extra_attrs = attrs; |
1323 | + priv->alternate_markup_set = TRUE; |
1324 | + } |
1325 | + break; |
1326 | + |
1327 | + case PROP_SINGLE_PARAGRAPH_MODE: |
1328 | + case PROP_BACKGROUND: |
1329 | + case PROP_FOREGROUND: |
1330 | + case PROP_BACKGROUND_GDK: |
1331 | + case PROP_FOREGROUND_GDK: |
1332 | + case PROP_FONT: |
1333 | + case PROP_FONT_DESC: |
1334 | + case PROP_FAMILY: |
1335 | + case PROP_STYLE: |
1336 | + case PROP_VARIANT: |
1337 | + case PROP_WEIGHT: |
1338 | + case PROP_STRETCH: |
1339 | + case PROP_SIZE: |
1340 | + case PROP_SIZE_POINTS: |
1341 | + case PROP_SCALE: |
1342 | + case PROP_EDITABLE: |
1343 | + case PROP_STRIKETHROUGH: |
1344 | + case PROP_UNDERLINE: |
1345 | + case PROP_RISE: |
1346 | + case PROP_LANGUAGE: |
1347 | + case PROP_ELLIPSIZE: |
1348 | + case PROP_WRAP_MODE: |
1349 | + case PROP_WRAP_WIDTH: |
1350 | + case PROP_WIDTH_CHARS: |
1351 | + case PROP_ALIGN: |
1352 | + case PROP_BACKGROUND_SET: |
1353 | + case PROP_FOREGROUND_SET: |
1354 | + case PROP_FAMILY_SET: |
1355 | + case PROP_STYLE_SET: |
1356 | + case PROP_VARIANT_SET: |
1357 | + case PROP_WEIGHT_SET: |
1358 | + case PROP_STRETCH_SET: |
1359 | + case PROP_SIZE_SET: |
1360 | + case PROP_SCALE_SET: |
1361 | + case PROP_EDITABLE_SET: |
1362 | + case PROP_STRIKETHROUGH_SET: |
1363 | + case PROP_UNDERLINE_SET: |
1364 | + case PROP_RISE_SET: |
1365 | + case PROP_LANGUAGE_SET: |
1366 | + case PROP_ELLIPSIZE_SET: |
1367 | + case PROP_ALIGN_SET: |
1368 | + g_object_set_property (G_OBJECT (priv->celltext), cell_text_renderer_property_names[param_id-PROP_SINGLE_PARAGRAPH_MODE], value); |
1369 | + break; |
1370 | + |
1371 | + default: |
1372 | + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); |
1373 | + break; |
1374 | + } |
1375 | +} |
1376 | + |
1377 | +/** |
1378 | + * katze_cell_renderer_2texts_new: |
1379 | + * |
1380 | + * Creates a new #KatzeCellRenderer2texts. Adjust how text is drawn using |
1381 | + * object properties. Object properties can be |
1382 | + * set globally (with g_object_set()). Also, with #GtkTreeViewColumn, |
1383 | + * you can bind a property to a value in a #GtkTreeModel. For example, |
1384 | + * you can bind the "text" property on the cell renderer to a string |
1385 | + * value in the model, thus rendering a different string in each row |
1386 | + * of the #GtkTreeView |
1387 | + * |
1388 | + * Return value: the new cell renderer |
1389 | + **/ |
1390 | +GtkCellRenderer * |
1391 | +katze_cell_renderer_2texts_new (void) |
1392 | +{ |
1393 | + return g_object_new (KATZE_TYPE_CELL_RENDERER_2TEXTS, NULL); |
1394 | +} |
1395 | + |
1396 | +static void |
1397 | +set_text(KatzeCellRenderer2texts* celltext, |
1398 | + GtkWidget* widget, |
1399 | + KatzeCellRenderer2textsPrivate* priv) |
1400 | +{ |
1401 | + GValue text_value = {0}; |
1402 | + GValue attrs_value = {0}; |
1403 | + GtkWidget* pwidget = gtk_widget_get_parent (widget); |
1404 | + gboolean alternate = FALSE; |
1405 | + |
1406 | + if (GTK_IS_MENU_ITEM (pwidget)) |
1407 | + { |
1408 | + GtkWidget* menu = gtk_widget_get_parent (pwidget); |
1409 | + GList* items; |
1410 | + |
1411 | + if (menu |
1412 | + && (GTK_IS_MENU (menu)) |
1413 | + && (items = gtk_container_get_children (GTK_CONTAINER (menu))) |
1414 | + && (GTK_WIDGET (items->data) == pwidget) |
1415 | + && (g_list_length (items) > 1) |
1416 | + && (GTK_IS_SEPARATOR_MENU_ITEM (g_list_next (items)->data))) |
1417 | + { |
1418 | + alternate = TRUE; |
1419 | + } |
1420 | + } |
1421 | + |
1422 | + g_value_init (&text_value, G_TYPE_STRING); |
1423 | + g_value_init (&attrs_value, PANGO_TYPE_ATTR_LIST); |
1424 | + |
1425 | + if (alternate) |
1426 | + { |
1427 | + g_value_set_static_string (&text_value, celltext->alternate_text); |
1428 | + g_value_set_boxed (&attrs_value, celltext->alternate_extra_attrs); |
1429 | + } |
1430 | + else |
1431 | + { |
1432 | + g_value_set_static_string (&text_value, celltext->text); |
1433 | + g_value_set_boxed (&attrs_value, celltext->extra_attrs); |
1434 | + } |
1435 | + |
1436 | + g_object_set_property (G_OBJECT (priv->celltext), |
1437 | + "text", &text_value); |
1438 | + g_object_set_property (G_OBJECT (priv->celltext), |
1439 | + "attributes", &attrs_value); |
1440 | + |
1441 | +} |
1442 | + |
1443 | +static void |
1444 | +katze_cell_renderer_2texts_get_size (GtkCellRenderer *cell, |
1445 | + GtkWidget *widget, |
1446 | + GdkRectangle *cell_area, |
1447 | + gint *x_offset, |
1448 | + gint *y_offset, |
1449 | + gint *width, |
1450 | + gint *height) |
1451 | +{ |
1452 | + KatzeCellRenderer2texts *celltext = (KatzeCellRenderer2texts *) cell; |
1453 | + KatzeCellRenderer2textsPrivate *priv; |
1454 | + priv = KATZE_CELL_RENDERER_2TEXTS_GET_PRIVATE (cell); |
1455 | + |
1456 | + set_text (celltext, widget, priv); |
1457 | + |
1458 | + gtk_cell_renderer_get_size (GTK_CELL_RENDERER (priv->celltext), |
1459 | + widget, cell_area, |
1460 | + x_offset, y_offset, width, height); |
1461 | +} |
1462 | + |
1463 | +static void |
1464 | +#if GTK_CHECK_VERSION(3,0,0) |
1465 | +katze_cell_renderer_2texts_render (GtkCellRenderer *cell, |
1466 | + cairo_t* cr, |
1467 | + GtkWidget *widget, |
1468 | + GdkRectangle *background_area, |
1469 | + GdkRectangle *cell_area, |
1470 | + GtkCellRendererState flags) |
1471 | +#else |
1472 | +katze_cell_renderer_2texts_render (GtkCellRenderer *cell, |
1473 | + GdkDrawable *window, |
1474 | + GtkWidget *widget, |
1475 | + GdkRectangle *background_area, |
1476 | + GdkRectangle *cell_area, |
1477 | + GdkRectangle *expose_area, |
1478 | + GtkCellRendererState flags) |
1479 | +#endif |
1480 | +{ |
1481 | + KatzeCellRenderer2texts *celltext = (KatzeCellRenderer2texts *) cell; |
1482 | + KatzeCellRenderer2textsPrivate *priv; |
1483 | + |
1484 | + priv = KATZE_CELL_RENDERER_2TEXTS_GET_PRIVATE (cell); |
1485 | + |
1486 | + set_text (celltext, widget, priv); |
1487 | + |
1488 | +#if GTK_CHECK_VERSION(3,0,0) |
1489 | + gtk_cell_renderer_render (GTK_CELL_RENDERER (priv->celltext), |
1490 | + cr, |
1491 | + widget, |
1492 | + background_area, |
1493 | + cell_area, |
1494 | + flags); |
1495 | +#else |
1496 | + gtk_cell_renderer_render (GTK_CELL_RENDERER (priv->celltext), |
1497 | + window, |
1498 | + widget, |
1499 | + background_area, |
1500 | + cell_area, |
1501 | + expose_area, |
1502 | + flags); |
1503 | +#endif |
1504 | +} |
1505 | + |
1506 | +static void |
1507 | +katze_cell_renderer_2texts_edited (GtkCellRendererText *celltext, |
1508 | + const gchar* path, |
1509 | + const gchar* new_text, |
1510 | + gpointer data) |
1511 | +{ |
1512 | + g_signal_emit (data, _2texts_cell_renderer_signals[EDITED], 0, path, new_text); |
1513 | +} |
1514 | + |
1515 | +static GtkCellEditable * |
1516 | +katze_cell_renderer_2texts_start_editing (GtkCellRenderer *cell, |
1517 | + GdkEvent *event, |
1518 | + GtkWidget *widget, |
1519 | + const gchar *path, |
1520 | + GdkRectangle *background_area, |
1521 | + GdkRectangle *cell_area, |
1522 | + GtkCellRendererState flags) |
1523 | +{ |
1524 | + GtkCellEditable *celledit; |
1525 | + GtkRequisition requisition; |
1526 | + KatzeCellRenderer2texts *celltext; |
1527 | + KatzeCellRenderer2textsPrivate *priv; |
1528 | + |
1529 | + celltext = KATZE_CELL_RENDERER_2TEXTS (cell); |
1530 | + priv = KATZE_CELL_RENDERER_2TEXTS_GET_PRIVATE (cell); |
1531 | + |
1532 | + celledit = gtk_cell_renderer_start_editing (GTK_CELL_RENDERER (priv->celltext), event, widget, path, background_area, cell_area, flags); |
1533 | + |
1534 | + if (celledit) |
1535 | + g_signal_connect (priv->celltext, |
1536 | + "edited", |
1537 | + G_CALLBACK (katze_cell_renderer_2texts_edited), |
1538 | + celltext); |
1539 | + |
1540 | + return celledit; |
1541 | +} |
1542 | + |
1543 | +/** |
1544 | + * katze_cell_renderer_2texts_set_fixed_height_from_font: |
1545 | + * @renderer: A #KatzeCellRenderer2texts |
1546 | + * @number_of_rows: Number of rows of text each cell renderer is allocated, or -1 |
1547 | + * |
1548 | + * Sets the height of a renderer to explicitly be determined by the "font" and |
1549 | + * "y_pad" property set on it. Further changes in these properties do not |
1550 | + * affect the height, so they must be accompanied by a subsequent call to this |
1551 | + * function. Using this function is unflexible, and should really only be used |
1552 | + * if calculating the size of a cell is too slow (ie, a massive number of cells |
1553 | + * displayed). If @number_of_rows is -1, then the fixed height is unset, and |
1554 | + * the height is determined by the properties again. |
1555 | + **/ |
1556 | +void |
1557 | +katze_cell_renderer_2texts_set_fixed_height_from_font (KatzeCellRenderer2texts *renderer, |
1558 | + gint number_of_rows) |
1559 | +{ |
1560 | + g_return_if_fail (KATZE_IS_CELL_RENDERER_2TEXTS (renderer)); |
1561 | + g_return_if_fail (number_of_rows == -1 || number_of_rows > 0); |
1562 | + |
1563 | + KatzeCellRenderer2textsPrivate *priv; |
1564 | + |
1565 | + priv = KATZE_CELL_RENDERER_2TEXTS_GET_PRIVATE (renderer); |
1566 | + |
1567 | + gtk_cell_renderer_text_set_fixed_height_from_font (priv->celltext, number_of_rows); |
1568 | +} |
1569 | |
1570 | === added file 'katze/katze-cellrenderer2texts.h' |
1571 | --- katze/katze-cellrenderer2texts.h 1970-01-01 00:00:00 +0000 |
1572 | +++ katze/katze-cellrenderer2texts.h 2013-07-18 19:43:28 +0000 |
1573 | @@ -0,0 +1,71 @@ |
1574 | +/* |
1575 | + Copyright (C) 2008-2013 Christian Dywan <christian@twotoasts.de> |
1576 | + |
1577 | + This library is free software; you can redistribute it and/or |
1578 | + modify it under the terms of the GNU Lesser General Public |
1579 | + License as published by the Free Software Foundation; either |
1580 | + version 2.1 of the License, or (at your option) any later version. |
1581 | + |
1582 | + See the file COPYING for the full license text. |
1583 | +*/ |
1584 | + |
1585 | +#ifndef __KATZE_CELL_RENDERER_2TEXTS_H__ |
1586 | +#define __KATZE_CELL_RENDERER_2TEXTS_H__ |
1587 | + |
1588 | + |
1589 | +#include <gtk/gtk.h> |
1590 | + |
1591 | +#ifndef GSEAL |
1592 | +#define GSEAL(String) String |
1593 | +#endif |
1594 | + |
1595 | +G_BEGIN_DECLS |
1596 | + |
1597 | + |
1598 | +#define KATZE_TYPE_CELL_RENDERER_2TEXTS (katze_cell_renderer_2texts_get_type ()) |
1599 | +#define KATZE_CELL_RENDERER_2TEXTS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), KATZE_TYPE_CELL_RENDERER_2TEXTS, KatzeCellRenderer2texts)) |
1600 | +#define KATZE_CELL_RENDERER_2TEXTS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), KATZE_TYPE_CELL_RENDERER_2TEXTS, KatzeCellRenderer2textsClass)) |
1601 | +#define KATZE_IS_CELL_RENDERER_2TEXTS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), KATZE_TYPE_CELL_RENDERER_2TEXTS)) |
1602 | +#define KATZE_IS_CELL_RENDERER_2TEXTS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), KATZE_TYPE_CELL_RENDERER_2TEXTS)) |
1603 | +#define KATZE_CELL_RENDERER_2TEXTS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), KATZE_TYPE_CELL_RENDERER_2TEXTS, KatzeCellRenderer2textsClass)) |
1604 | + |
1605 | +typedef struct _KatzeCellRenderer2texts KatzeCellRenderer2texts; |
1606 | +typedef struct _KatzeCellRenderer2textsClass KatzeCellRenderer2textsClass; |
1607 | + |
1608 | +struct _KatzeCellRenderer2texts |
1609 | +{ |
1610 | + GtkCellRenderer parent; |
1611 | + |
1612 | + /*< private >*/ |
1613 | + gchar *GSEAL (text); |
1614 | + PangoAttrList *GSEAL (extra_attrs); |
1615 | + |
1616 | + gchar *GSEAL (alternate_text); |
1617 | + PangoAttrList *GSEAL (alternate_extra_attrs); |
1618 | +}; |
1619 | + |
1620 | +struct _KatzeCellRenderer2textsClass |
1621 | +{ |
1622 | + GtkCellRendererClass parent_class; |
1623 | + |
1624 | + void (* edited) (KatzeCellRenderer2texts *cell_renderer_2texts, |
1625 | + const gchar *path, |
1626 | + const gchar *new_text); |
1627 | + |
1628 | + /* Padding for future expansion */ |
1629 | + void (*_gtk_reserved1) (void); |
1630 | + void (*_gtk_reserved2) (void); |
1631 | + void (*_gtk_reserved3) (void); |
1632 | + void (*_gtk_reserved4) (void); |
1633 | +}; |
1634 | + |
1635 | +GType katze_cell_renderer_2texts_get_type (void) G_GNUC_CONST; |
1636 | +GtkCellRenderer *katze_cell_renderer_2texts_new (void); |
1637 | + |
1638 | +void katze_cell_renderer_2texts_set_fixed_height_from_font (KatzeCellRenderer2texts *renderer, |
1639 | + gint number_of_rows); |
1640 | + |
1641 | + |
1642 | +G_END_DECLS |
1643 | + |
1644 | +#endif /* __KATZE_CELL_RENDERER_2TEXTS_H__ */ |
1645 | |
1646 | === modified file 'midori/midori-browser.c' |
1647 | --- midori/midori-browser.c 2013-07-15 23:01:23 +0000 |
1648 | +++ midori/midori-browser.c 2013-07-18 19:43:28 +0000 |
1649 | @@ -26,6 +26,8 @@ |
1650 | #include "midori-privatedata.h" |
1651 | #include "midori-core.h" |
1652 | #include "midori-privatedata.h" |
1653 | +#include "katze-cellrenderer2texts.h" |
1654 | +#include "katze-cellrenderer2pixbufs.h" |
1655 | |
1656 | #include "marshal.h" |
1657 | |
1658 | @@ -828,52 +830,221 @@ |
1659 | } |
1660 | } |
1661 | |
1662 | +static gboolean |
1663 | +midori_bookmark_folder_button_reach_parent (GtkTreeModel* model, GtkTreeIter *iter, gint64 parentid) |
1664 | +{ |
1665 | + do |
1666 | + { |
1667 | + gint64 id; |
1668 | + |
1669 | + gtk_tree_model_get (model, iter, 1, &id, -1); |
1670 | + |
1671 | + if (parentid == id) |
1672 | + return TRUE; |
1673 | + |
1674 | + if (gtk_tree_model_iter_has_child (model, iter)) |
1675 | + { |
1676 | + GtkTreeIter child; |
1677 | + gtk_tree_model_iter_children (model, &child, iter); |
1678 | + if (midori_bookmark_folder_button_reach_parent (model, &child, parentid)) |
1679 | + { |
1680 | + *iter = child; |
1681 | + return TRUE; |
1682 | + } |
1683 | + } |
1684 | + } |
1685 | + while (gtk_tree_model_iter_next (model, iter)); |
1686 | + |
1687 | + return FALSE; |
1688 | +} |
1689 | + |
1690 | +typedef struct _FolderEntry |
1691 | +{ |
1692 | + const gchar *title; |
1693 | + gint64 id; |
1694 | + gint64 parentid; |
1695 | +} FolderEntry; |
1696 | + |
1697 | +static void |
1698 | +midori_bookmark_folder_free_folder_entry (FolderEntry* folder) |
1699 | +{ |
1700 | + g_free ((gpointer)folder->title); |
1701 | +} |
1702 | + |
1703 | static GtkWidget* |
1704 | midori_bookmark_folder_button_new (KatzeArray* array, |
1705 | - gint64 selected, |
1706 | - gint64 parentid) |
1707 | + gint64 selected_parentid) |
1708 | { |
1709 | - GtkListStore* model; |
1710 | + GtkTreeStore* model; |
1711 | GtkWidget* combo; |
1712 | GtkCellRenderer* renderer; |
1713 | guint n; |
1714 | sqlite3* db; |
1715 | sqlite3_stmt* statement; |
1716 | gint result; |
1717 | - const gchar* sqlcmd = "SELECT title, id FROM bookmarks WHERE uri='' ORDER BY title ASC"; |
1718 | - |
1719 | - model = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT64); |
1720 | - combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (model)); |
1721 | - renderer = gtk_cell_renderer_text_new (); |
1722 | - gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE); |
1723 | - gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (combo), renderer, "text", 0); |
1724 | - gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (combo), renderer, "ellipsize", 1); |
1725 | - gtk_list_store_insert_with_values (model, NULL, G_MAXINT, |
1726 | - 0, _("Bookmarks"), 1, PANGO_ELLIPSIZE_END, 2, (gint64)0, -1); |
1727 | - gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0); |
1728 | + const gchar* sqlcmd = "SELECT title, id, parentid FROM bookmarks WHERE uri='' ORDER BY parentid, title ASC"; |
1729 | + gint64 current_parentid; |
1730 | + GtkTreeIter tree_iter; |
1731 | + GtkTreeIter stock_parent_iter; |
1732 | + GtkTreeIter* parent_iter; |
1733 | + GList *folders = NULL; |
1734 | |
1735 | db = g_object_get_data (G_OBJECT (array), "db"); |
1736 | g_return_val_if_fail (db != NULL, NULL); |
1737 | + |
1738 | + /* folder combo box model content: |
1739 | + ** 0: title |
1740 | + ** 1: id |
1741 | + */ |
1742 | + model = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_INT64); |
1743 | + combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (model)); |
1744 | + |
1745 | + /* setup combo layout |
1746 | + ** 0: a folder icon |
1747 | + ** 1: the folder name |
1748 | + */ |
1749 | + |
1750 | + gtk_cell_layout_clear (GTK_CELL_LAYOUT (combo)); |
1751 | + |
1752 | + renderer = katze_cell_renderer_2pixbufs_new (); |
1753 | + g_object_set (G_OBJECT (renderer), |
1754 | + "pixbuf-expander-open", |
1755 | + gtk_widget_render_icon (GTK_WIDGET (combo), |
1756 | + GTK_STOCK_OPEN, GTK_ICON_SIZE_MENU, NULL), |
1757 | + "pixbuf-expander-closed", |
1758 | + gtk_widget_render_icon (GTK_WIDGET (combo), |
1759 | + GTK_STOCK_DIRECTORY, GTK_ICON_SIZE_MENU, NULL), |
1760 | + NULL); |
1761 | + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, FALSE); |
1762 | + |
1763 | + renderer = katze_cell_renderer_2texts_new (); |
1764 | + g_object_set (G_OBJECT (renderer), |
1765 | + "width-chars", 40, /* FIXME: figure out a way to define an acceptable string length */ |
1766 | + "ellipsize", PANGO_ELLIPSIZE_END, |
1767 | + "alternate-text", _("Select this folder"), |
1768 | + NULL); |
1769 | + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE); |
1770 | + gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (combo), renderer, "text", 0); |
1771 | + |
1772 | + /* read the folders list from the database */ |
1773 | + /* FIXME: this should be a service of midori/midori-bookmarks-db */ |
1774 | + |
1775 | + if ((result = sqlite3_prepare_v2 (db, sqlcmd, -1, &statement, NULL)) == SQLITE_OK) |
1776 | + { |
1777 | + while ((result = sqlite3_step (statement)) == SQLITE_ROW) |
1778 | + { |
1779 | + FolderEntry* folder = g_new (FolderEntry, 1); |
1780 | + |
1781 | + folder->title = g_strdup ((const gchar*)sqlite3_column_text (statement, 0)); |
1782 | + folder->id = sqlite3_column_int64 (statement, 1); |
1783 | + folder->parentid = sqlite3_column_int64 (statement, 2); |
1784 | + |
1785 | + folders = g_list_append (folders, folder); |
1786 | + } |
1787 | + |
1788 | + sqlite3_clear_bindings (statement); |
1789 | + sqlite3_reset (statement); |
1790 | + } |
1791 | + |
1792 | + /* populate the combo box */ |
1793 | + /* FIXME: here we should have the root bookmark array's name and id, not hard encoded values */ |
1794 | + |
1795 | + gtk_tree_store_insert_with_values (model, &tree_iter, NULL, G_MAXINT, |
1796 | + 0, _("Bookmarks"), 1, (gint64)0, -1); |
1797 | + gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combo), &tree_iter); |
1798 | + |
1799 | + current_parentid = 0; |
1800 | + parent_iter = NULL; |
1801 | n = 1; |
1802 | - if ((result = sqlite3_prepare_v2 (db, sqlcmd, -1, &statement, NULL)) == SQLITE_OK) |
1803 | - while ((result = sqlite3_step (statement)) == SQLITE_ROW) |
1804 | + while (g_list_first (folders)) |
1805 | { |
1806 | - const unsigned char* name = sqlite3_column_text (statement, 0); |
1807 | - gint64 id = sqlite3_column_int64 (statement, 1); |
1808 | + gboolean something_done = FALSE; |
1809 | + GList* list_iter = g_list_first (folders); |
1810 | |
1811 | - /* do not show the folder itself */ |
1812 | - if (id != selected) |
1813 | + do |
1814 | { |
1815 | - gtk_list_store_insert_with_values (model, NULL, G_MAXINT, |
1816 | - 0, name, 1, PANGO_ELLIPSIZE_END, 2, id, -1); |
1817 | - |
1818 | - if (id == parentid) |
1819 | - gtk_combo_box_set_active (GTK_COMBO_BOX (combo), n); |
1820 | + FolderEntry* folder = list_iter->data; |
1821 | + const gchar* title = folder->title; |
1822 | + gint64 id = folder->id; |
1823 | + gint64 parentid = folder->parentid; |
1824 | + |
1825 | + if (parentid != current_parentid) /* optimize case of sub-folders of the same parent */ |
1826 | + { |
1827 | + if (!parentid) |
1828 | + { |
1829 | + /* folder's parent is the stree store root */ |
1830 | + |
1831 | + current_parentid = 0; |
1832 | + parent_iter = NULL; |
1833 | + } |
1834 | + else if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), &tree_iter)) |
1835 | + { |
1836 | + if (midori_bookmark_folder_button_reach_parent ( |
1837 | + GTK_TREE_MODEL (model), &tree_iter, parentid)) |
1838 | + { |
1839 | + /* folder's parent found in the tree store */ |
1840 | + |
1841 | + current_parentid = parentid; |
1842 | + stock_parent_iter = tree_iter; |
1843 | + parent_iter = &stock_parent_iter; |
1844 | + } |
1845 | + else |
1846 | + { |
1847 | + /* folder's parent not found, skip it */ |
1848 | + |
1849 | + list_iter = g_list_next (list_iter); |
1850 | + continue; |
1851 | + } |
1852 | + } |
1853 | + else |
1854 | + g_assert_not_reached (); |
1855 | + } |
1856 | + |
1857 | + /* insert folder in the tree store and remove it from the folders list */ |
1858 | + |
1859 | + gtk_tree_store_insert_with_values (model, &tree_iter, parent_iter, G_MAXINT, |
1860 | + 0, title, 1, id, -1); |
1861 | + |
1862 | + if (id == selected_parentid) |
1863 | + gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combo), &tree_iter); |
1864 | + |
1865 | n++; |
1866 | - } |
1867 | - } |
1868 | + |
1869 | + something_done = TRUE; |
1870 | + |
1871 | + g_free ((gpointer)title); |
1872 | + folders = g_list_delete_link (folders, list_iter); |
1873 | + |
1874 | + list_iter = g_list_first (folders); |
1875 | + } |
1876 | + while (list_iter); |
1877 | + |
1878 | + if (!something_done) /* avoid infinite loop in case of orphan folders */ |
1879 | + break; |
1880 | + } |
1881 | + |
1882 | + if (g_list_first (folders)) |
1883 | + { |
1884 | + GList* iter; |
1885 | + g_printerr ("midori_bookmark_folder_button_new: orphan folder(s) detected in bookmarks db\n"); |
1886 | + |
1887 | + for (iter = g_list_first (folders) ; iter ; iter = g_list_next (iter)) |
1888 | + { |
1889 | + FolderEntry* folder = iter->data; |
1890 | + const gchar* title = folder->title; |
1891 | + gint64 id = folder->id; |
1892 | + gint64 parentid = folder->parentid; |
1893 | + |
1894 | + g_printerr (" id=%" G_GINT64_FORMAT ", parentid=%" G_GINT64_FORMAT ", title=%s\n", |
1895 | + id, parentid, title); |
1896 | + } |
1897 | + |
1898 | + g_list_free_full (folders, (GDestroyNotify)midori_bookmark_folder_free_folder_entry); |
1899 | + } |
1900 | + |
1901 | if (n < 2) |
1902 | gtk_widget_set_sensitive (combo, FALSE); |
1903 | + |
1904 | return combo; |
1905 | } |
1906 | |
1907 | @@ -887,14 +1058,8 @@ |
1908 | |
1909 | if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter)) |
1910 | { |
1911 | - gchar* selected = NULL; |
1912 | GtkTreeModel* model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo)); |
1913 | - gtk_tree_model_get (GTK_TREE_MODEL (model), &iter, 0, &selected, 2, &id, -1); |
1914 | - |
1915 | - if (g_str_equal (selected, _("Bookmarks"))) |
1916 | - id = 0; |
1917 | - |
1918 | - g_free (selected); |
1919 | + gtk_tree_model_get (GTK_TREE_MODEL (model), &iter, 1, &id, -1); |
1920 | } |
1921 | |
1922 | return id; |
1923 | @@ -1021,7 +1186,6 @@ |
1924 | } |
1925 | |
1926 | combo_folder = midori_bookmark_folder_button_new (browser->bookmarks, |
1927 | - katze_item_get_meta_integer (bookmark, "id"), |
1928 | katze_item_get_meta_integer (bookmark, "parentid")); |
1929 | gtk_box_pack_start (GTK_BOX (vbox), combo_folder, FALSE, FALSE, 0); |
1930 | |
1931 | @@ -4460,8 +4624,7 @@ |
1932 | gtk_container_add (GTK_CONTAINER (content_area), hbox); |
1933 | gtk_widget_show_all (hbox); |
1934 | |
1935 | - combobox_folder = midori_bookmark_folder_button_new (browser->bookmarks, |
1936 | - 0, 0); |
1937 | + combobox_folder = midori_bookmark_folder_button_new (browser->bookmarks, 0); |
1938 | gtk_container_add (GTK_CONTAINER (content_area), combobox_folder); |
1939 | |
1940 | gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT); |
I could live with the "duplicate" folder if need be. If it's feasible I'd consider renaming the "second" menu item to "Choose this folder", a style I've seen in a few places.
For the sizing, sokoke.c has a function, alternatively something screen width based. Hard to say which works best in this case honestly.