Merge lp:~aauzi/midori/fix-1177553-3 into lp:midori

Proposed by André Auzi
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
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.

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.

To post a comment you must log in.
Revision history for this message
Cris Dywan (kalikiana) wrote :

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.

review: Needs Fixing
lp:~aauzi/midori/fix-1177553-3 updated
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

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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);

Subscribers

People subscribed via source and target branches

to all changes: