Statistics
| Revision:

root / src / gtkutils.c @ 1637

History | View | Annotate | Download (25 kB)

1 1 hiro
/*
2 1 hiro
 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 1514 hiro
 * Copyright (C) 1999-2007 Hiroyuki Yamamoto
4 1 hiro
 *
5 1 hiro
 * This program is free software; you can redistribute it and/or modify
6 1 hiro
 * it under the terms of the GNU General Public License as published by
7 1 hiro
 * the Free Software Foundation; either version 2 of the License, or
8 1 hiro
 * (at your option) any later version.
9 1 hiro
 *
10 1 hiro
 * This program is distributed in the hope that it will be useful,
11 1 hiro
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 1 hiro
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 1 hiro
 * GNU General Public License for more details.
14 1 hiro
 *
15 1 hiro
 * You should have received a copy of the GNU General Public License
16 1 hiro
 * along with this program; if not, write to the Free Software
17 1 hiro
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 1 hiro
 */
19 1 hiro
20 1 hiro
#ifdef HAVE_CONFIG_H
21 1 hiro
#  include "config.h"
22 1 hiro
#endif
23 1 hiro
24 1 hiro
#include <glib.h>
25 92 hiro
#include <glib/gi18n.h>
26 1 hiro
#include <gdk/gdkkeysyms.h>
27 1 hiro
#include <gdk/gdk.h>
28 1 hiro
#include <gtk/gtkwidget.h>
29 405 hiro
#include <gtk/gtkbox.h>
30 1 hiro
#include <gtk/gtkhbbox.h>
31 1 hiro
#include <gtk/gtkbutton.h>
32 276 hiro
#include <gtk/gtkarrow.h>
33 1 hiro
#include <gtk/gtkctree.h>
34 1 hiro
#include <gtk/gtkcombo.h>
35 1 hiro
#include <gtk/gtkbindings.h>
36 1 hiro
#include <gtk/gtkitemfactory.h>
37 239 hiro
#include <gtk/gtktreemodel.h>
38 239 hiro
#include <gtk/gtktreesortable.h>
39 239 hiro
#include <gtk/gtktreeview.h>
40 281 hiro
#include <gtk/gtktreestore.h>
41 239 hiro
#include <gtk/gtkversion.h>
42 1 hiro
#include <stdlib.h>
43 1 hiro
#include <stdarg.h>
44 1 hiro
45 1637 hiro
#ifdef G_OS_WIN32
46 1637 hiro
#  include <pango/pangowin32.h>
47 1637 hiro
#endif
48 1637 hiro
49 1 hiro
#include "gtkutils.h"
50 1 hiro
#include "utils.h"
51 1 hiro
#include "codeconv.h"
52 1 hiro
#include "menu.h"
53 1 hiro
54 1514 hiro
gboolean gtkut_get_str_size(GtkWidget *widget, const gchar *str,
55 1514 hiro
                            gint *width, gint *height)
56 1 hiro
{
57 1 hiro
        PangoLayout *layout;
58 1 hiro
59 1 hiro
        g_return_val_if_fail(GTK_IS_WIDGET(widget), FALSE);
60 1 hiro
61 1 hiro
        layout = gtk_widget_create_pango_layout(widget, str);
62 1 hiro
        g_return_val_if_fail(layout, FALSE);
63 1 hiro
        pango_layout_get_pixel_size(layout, width, height);
64 1 hiro
        g_object_unref(layout);
65 1 hiro
66 1 hiro
        return TRUE;
67 1 hiro
}
68 1 hiro
69 1514 hiro
gboolean gtkut_get_font_size(GtkWidget *widget, gint *width, gint *height)
70 1514 hiro
{
71 1514 hiro
        const gchar *str = "Abcdef";
72 1514 hiro
        gboolean ret;
73 1514 hiro
74 1514 hiro
        ret = gtkut_get_str_size(widget, str, width, height);
75 1514 hiro
        if (ret && width)
76 1514 hiro
                *width = *width / g_utf8_strlen(str, -1);
77 1514 hiro
78 1514 hiro
        return ret;
79 1514 hiro
}
80 1514 hiro
81 39 hiro
PangoFontDescription *gtkut_get_default_font_desc(void)
82 39 hiro
{
83 39 hiro
        static PangoFontDescription *font_desc = NULL;
84 39 hiro
85 39 hiro
        if (!font_desc) {
86 39 hiro
                GtkWidget *window;
87 39 hiro
88 39 hiro
                window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
89 39 hiro
                gtk_widget_ensure_style(window);
90 39 hiro
                font_desc = pango_font_description_copy
91 39 hiro
                        (window->style->font_desc);
92 39 hiro
                gtk_object_sink(GTK_OBJECT(window));
93 39 hiro
        }
94 39 hiro
95 39 hiro
        return pango_font_description_copy(font_desc);
96 39 hiro
}
97 39 hiro
98 89 hiro
void gtkut_widget_set_small_font_size(GtkWidget *widget)
99 89 hiro
{
100 89 hiro
        PangoFontDescription *font_desc;
101 89 hiro
        gint size;
102 89 hiro
103 89 hiro
        g_return_if_fail(widget != NULL);
104 89 hiro
        g_return_if_fail(widget->style != NULL);
105 89 hiro
106 89 hiro
        font_desc = gtkut_get_default_font_desc();
107 89 hiro
        size = pango_font_description_get_size(font_desc);
108 89 hiro
        pango_font_description_set_size(font_desc, size * PANGO_SCALE_SMALL);
109 89 hiro
        gtk_widget_modify_font(widget, font_desc);
110 89 hiro
        pango_font_description_free(font_desc);
111 89 hiro
}
112 89 hiro
113 1637 hiro
gboolean gtkut_font_can_load(const gchar *str)
114 1637 hiro
{
115 1637 hiro
#ifdef G_OS_WIN32
116 1637 hiro
        PangoFontDescription *desc;
117 1637 hiro
        PangoContext *context;
118 1637 hiro
        PangoFont *font;
119 1637 hiro
        gboolean can_load = FALSE;
120 1637 hiro
121 1637 hiro
        desc = pango_font_description_from_string(str);
122 1637 hiro
        if (desc) {
123 1637 hiro
                context = pango_win32_get_context();
124 1637 hiro
                font = pango_context_load_font(context, desc);
125 1637 hiro
                if (font) {
126 1637 hiro
                        can_load = TRUE;
127 1637 hiro
                        g_object_unref(font);
128 1637 hiro
                }
129 1637 hiro
                g_object_unref(context);
130 1637 hiro
                pango_font_description_free(desc);
131 1637 hiro
        }
132 1637 hiro
133 1637 hiro
        return can_load;
134 1637 hiro
#else
135 1637 hiro
        return FALSE;
136 1637 hiro
#endif
137 1637 hiro
}
138 1637 hiro
139 1 hiro
void gtkut_convert_int_to_gdk_color(gint rgbvalue, GdkColor *color)
140 1 hiro
{
141 1 hiro
        g_return_if_fail(color != NULL);
142 1 hiro
143 1 hiro
        color->pixel = 0L;
144 1 hiro
        color->red   = (int) (((gdouble)((rgbvalue & 0xff0000) >> 16) / 255.0) * 65535.0);
145 1 hiro
        color->green = (int) (((gdouble)((rgbvalue & 0x00ff00) >>  8) / 255.0) * 65535.0);
146 1 hiro
        color->blue  = (int) (((gdouble) (rgbvalue & 0x0000ff)        / 255.0) * 65535.0);
147 1 hiro
}
148 1 hiro
149 405 hiro
static gboolean reverse_order = FALSE;
150 405 hiro
151 405 hiro
void gtkut_stock_button_set_set_reverse(gboolean reverse)
152 405 hiro
{
153 405 hiro
        reverse_order = reverse;
154 405 hiro
}
155 405 hiro
156 30 hiro
void gtkut_stock_button_set_create(GtkWidget **bbox,
157 30 hiro
                                   GtkWidget **button1, const gchar *label1,
158 30 hiro
                                   GtkWidget **button2, const gchar *label2,
159 30 hiro
                                   GtkWidget **button3, const gchar *label3)
160 30 hiro
{
161 30 hiro
        g_return_if_fail(bbox != NULL);
162 30 hiro
        g_return_if_fail(button1 != NULL);
163 30 hiro
164 30 hiro
        *bbox = gtk_hbutton_box_new();
165 30 hiro
        gtk_button_box_set_layout(GTK_BUTTON_BOX(*bbox), GTK_BUTTONBOX_END);
166 405 hiro
        gtk_box_set_spacing(GTK_BOX(*bbox), 6);
167 30 hiro
168 405 hiro
        if (button3) {
169 405 hiro
                *button3 = gtk_button_new_from_stock(label3);
170 405 hiro
                GTK_WIDGET_SET_FLAGS(*button3, GTK_CAN_DEFAULT);
171 405 hiro
                gtk_box_pack_start(GTK_BOX(*bbox), *button3, FALSE, FALSE, 0);
172 405 hiro
                gtk_widget_show(*button3);
173 405 hiro
        }
174 30 hiro
175 30 hiro
        if (button2) {
176 30 hiro
                *button2 = gtk_button_new_from_stock(label2);
177 30 hiro
                GTK_WIDGET_SET_FLAGS(*button2, GTK_CAN_DEFAULT);
178 405 hiro
                gtk_box_pack_start(GTK_BOX(*bbox), *button2, FALSE, FALSE, 0);
179 30 hiro
                gtk_widget_show(*button2);
180 30 hiro
        }
181 30 hiro
182 405 hiro
        *button1 = gtk_button_new_from_stock(label1);
183 405 hiro
        GTK_WIDGET_SET_FLAGS(*button1, GTK_CAN_DEFAULT);
184 405 hiro
        gtk_box_pack_start(GTK_BOX(*bbox), *button1, FALSE, FALSE, 0);
185 405 hiro
        gtk_widget_show(*button1);
186 405 hiro
187 405 hiro
        if (reverse_order)
188 405 hiro
                gtkut_box_set_reverse_order(GTK_BOX(*bbox), TRUE);
189 405 hiro
}
190 405 hiro
191 405 hiro
void gtkut_box_set_reverse_order(GtkBox *box, gboolean reverse)
192 405 hiro
{
193 405 hiro
        GList *cur;
194 405 hiro
        GList *new_order = NULL;
195 405 hiro
        gint pos = 0;
196 405 hiro
        gboolean is_reversed;
197 405 hiro
198 405 hiro
        g_return_if_fail(box != NULL);
199 405 hiro
200 405 hiro
        is_reversed = GPOINTER_TO_INT
201 405 hiro
                (g_object_get_data(G_OBJECT(box), "reverse-order"));
202 405 hiro
        if (is_reversed == reverse)
203 405 hiro
                return;
204 405 hiro
        g_object_set_data(G_OBJECT(box), "reverse-order",
205 405 hiro
                          GINT_TO_POINTER(reverse));
206 405 hiro
207 405 hiro
        for (cur = box->children; cur != NULL; cur = cur->next) {
208 405 hiro
                GtkBoxChild *cinfo = cur->data;
209 405 hiro
                new_order = g_list_prepend(new_order, cinfo->widget);
210 30 hiro
        }
211 405 hiro
212 405 hiro
        for (cur = new_order; cur != NULL; cur = cur->next) {
213 405 hiro
                GtkWidget *child = cur->data;
214 405 hiro
                gtk_box_reorder_child(box, child, pos++);
215 405 hiro
        }
216 405 hiro
217 405 hiro
        g_list_free(new_order);
218 30 hiro
}
219 30 hiro
220 1 hiro
static void combo_button_size_request(GtkWidget *widget,
221 1 hiro
                                      GtkRequisition *requisition,
222 1 hiro
                                      gpointer data)
223 1 hiro
{
224 1 hiro
        ComboButton *combo = (ComboButton *)data;
225 1 hiro
226 1 hiro
        if (combo->arrow->allocation.height != requisition->height)
227 1 hiro
                gtk_widget_set_size_request(combo->arrow,
228 1 hiro
                                            -1, requisition->height);
229 1 hiro
}
230 1 hiro
231 1 hiro
static void combo_button_enter(GtkWidget *widget, gpointer data)
232 1 hiro
{
233 1 hiro
        ComboButton *combo = (ComboButton *)data;
234 1 hiro
235 1 hiro
        if (GTK_WIDGET_STATE(combo->arrow) != GTK_STATE_PRELIGHT) {
236 1 hiro
                gtk_widget_set_state(combo->arrow, GTK_STATE_PRELIGHT);
237 1 hiro
                gtk_widget_queue_draw(combo->arrow);
238 1 hiro
        }
239 1 hiro
        if (GTK_WIDGET_STATE(combo->button) != GTK_STATE_PRELIGHT) {
240 1 hiro
                gtk_widget_set_state(combo->button, GTK_STATE_PRELIGHT);
241 1 hiro
                gtk_widget_queue_draw(combo->button);
242 1 hiro
        }
243 1 hiro
}
244 1 hiro
245 1 hiro
static void combo_button_leave(GtkWidget *widget, gpointer data)
246 1 hiro
{
247 1 hiro
        ComboButton *combo = (ComboButton *)data;
248 1 hiro
249 1 hiro
        if (GTK_WIDGET_STATE(combo->arrow) != GTK_STATE_NORMAL) {
250 1 hiro
                gtk_widget_set_state(combo->arrow, GTK_STATE_NORMAL);
251 1 hiro
                gtk_widget_queue_draw(combo->arrow);
252 1 hiro
        }
253 1 hiro
        if (GTK_WIDGET_STATE(combo->button) != GTK_STATE_NORMAL) {
254 1 hiro
                gtk_widget_set_state(combo->button, GTK_STATE_NORMAL);
255 1 hiro
                gtk_widget_queue_draw(combo->button);
256 1 hiro
        }
257 1 hiro
}
258 1 hiro
259 1 hiro
static gint combo_button_arrow_pressed(GtkWidget *widget, GdkEventButton *event,
260 1 hiro
                                       gpointer data)
261 1 hiro
{
262 1 hiro
        ComboButton *combo = (ComboButton *)data;
263 1 hiro
264 1 hiro
        if (!event) return FALSE;
265 1 hiro
266 1 hiro
        gtk_menu_popup(GTK_MENU(combo->menu), NULL, NULL,
267 1 hiro
                       menu_button_position, combo->button,
268 1 hiro
                       event->button, event->time);
269 1 hiro
270 1 hiro
        return TRUE;
271 1 hiro
}
272 1 hiro
273 1 hiro
static void combo_button_destroy(GtkWidget *widget, gpointer data)
274 1 hiro
{
275 1 hiro
        ComboButton *combo = (ComboButton *)data;
276 1 hiro
277 1 hiro
        gtk_object_destroy(GTK_OBJECT(combo->factory));
278 1 hiro
        g_free(combo);
279 1 hiro
}
280 1 hiro
281 1 hiro
ComboButton *gtkut_combo_button_create(GtkWidget *button,
282 1 hiro
                                       GtkItemFactoryEntry *entries,
283 1 hiro
                                       gint n_entries, const gchar *path,
284 1 hiro
                                       gpointer data)
285 1 hiro
{
286 1 hiro
        ComboButton *combo;
287 1 hiro
        GtkWidget *arrow;
288 1 hiro
289 1 hiro
        combo = g_new0(ComboButton, 1);
290 1 hiro
291 1 hiro
        combo->arrow = gtk_button_new();
292 1 hiro
        arrow = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_OUT);
293 5 hiro
        gtk_widget_set_size_request(arrow, 7, -1);
294 1 hiro
        gtk_container_add(GTK_CONTAINER(combo->arrow), arrow);
295 1 hiro
        GTK_WIDGET_UNSET_FLAGS(combo->arrow, GTK_CAN_FOCUS);
296 1 hiro
        gtk_widget_show_all(combo->arrow);
297 1 hiro
298 1 hiro
        combo->button = button;
299 1 hiro
        combo->menu = menu_create_items(entries, n_entries, path,
300 1 hiro
                                        &combo->factory, data);
301 1 hiro
        combo->data = data;
302 1 hiro
303 1 hiro
        g_signal_connect(G_OBJECT(combo->button), "size_request",
304 1 hiro
                         G_CALLBACK(combo_button_size_request), combo);
305 1514 hiro
#if 0
306 1 hiro
        g_signal_connect(G_OBJECT(combo->button), "enter",
307 1 hiro
                         G_CALLBACK(combo_button_enter), combo);
308 1 hiro
        g_signal_connect(G_OBJECT(combo->button), "leave",
309 1 hiro
                         G_CALLBACK(combo_button_leave), combo);
310 1514 hiro
#endif
311 1 hiro
        g_signal_connect(G_OBJECT(combo->arrow), "enter",
312 1 hiro
                         G_CALLBACK(combo_button_enter), combo);
313 1 hiro
        g_signal_connect(G_OBJECT(combo->arrow), "leave",
314 1 hiro
                         G_CALLBACK(combo_button_leave), combo);
315 1 hiro
        g_signal_connect(G_OBJECT(combo->arrow), "button_press_event",
316 1 hiro
                         G_CALLBACK(combo_button_arrow_pressed), combo);
317 1 hiro
        g_signal_connect(G_OBJECT(combo->arrow), "destroy",
318 1 hiro
                         G_CALLBACK(combo_button_destroy), combo);
319 1 hiro
320 1 hiro
        return combo;
321 1 hiro
}
322 1 hiro
323 1 hiro
gint gtkut_ctree_get_nth_from_node(GtkCTree *ctree, GtkCTreeNode *node)
324 1 hiro
{
325 1 hiro
        g_return_val_if_fail(ctree != NULL, -1);
326 1 hiro
        g_return_val_if_fail(node != NULL, -1);
327 1 hiro
328 1 hiro
        return g_list_position(GTK_CLIST(ctree)->row_list, (GList *)node);
329 1 hiro
}
330 1 hiro
331 1 hiro
void gtkut_ctree_set_focus_row(GtkCTree *ctree, GtkCTreeNode *node)
332 1 hiro
{
333 1 hiro
        gtkut_clist_set_focus_row(GTK_CLIST(ctree),
334 1 hiro
                                  gtkut_ctree_get_nth_from_node(ctree, node));
335 1 hiro
}
336 1 hiro
337 1 hiro
void gtkut_clist_set_focus_row(GtkCList *clist, gint row)
338 1 hiro
{
339 1 hiro
        clist->focus_row = row;
340 1 hiro
        GTKUT_CTREE_REFRESH(clist);
341 1 hiro
}
342 1 hiro
343 1577 hiro
#ifdef G_OS_WIN32
344 1577 hiro
static void vadjustment_changed(GtkAdjustment *adj, gpointer data)
345 1577 hiro
{
346 1577 hiro
        GtkWidget *widget = GTK_WIDGET(data);
347 1577 hiro
348 1577 hiro
        gtk_widget_queue_draw(widget);
349 1577 hiro
}
350 1577 hiro
#endif
351 1577 hiro
352 1577 hiro
void gtkut_clist_set_redraw(GtkCList *clist)
353 1577 hiro
{
354 1577 hiro
#ifdef G_OS_WIN32
355 1577 hiro
        if (clist->vadjustment) {
356 1577 hiro
                g_signal_connect(G_OBJECT(clist->vadjustment), "changed",
357 1577 hiro
                                 G_CALLBACK(vadjustment_changed), clist);
358 1577 hiro
        }
359 1577 hiro
#endif
360 1577 hiro
}
361 1577 hiro
362 202 hiro
gboolean gtkut_tree_model_next(GtkTreeModel *model, GtkTreeIter *iter)
363 202 hiro
{
364 202 hiro
        GtkTreeIter iter_, parent;
365 202 hiro
        gboolean valid;
366 202 hiro
367 202 hiro
        if (gtk_tree_model_iter_children(model, &iter_, iter)) {
368 202 hiro
                *iter = iter_;
369 202 hiro
                return TRUE;
370 202 hiro
        }
371 202 hiro
372 202 hiro
        iter_ = *iter;
373 202 hiro
        if (gtk_tree_model_iter_next(model, &iter_)) {
374 202 hiro
                *iter = iter_;
375 202 hiro
                return TRUE;
376 202 hiro
        }
377 202 hiro
378 202 hiro
        iter_ = *iter;
379 202 hiro
        valid = gtk_tree_model_iter_parent(model, &parent, &iter_);
380 202 hiro
        while (valid) {
381 202 hiro
                iter_ = parent;
382 202 hiro
                if (gtk_tree_model_iter_next(model, &iter_)) {
383 202 hiro
                        *iter = iter_;
384 202 hiro
                        return TRUE;
385 202 hiro
                }
386 202 hiro
387 202 hiro
                iter_ = parent;
388 202 hiro
                valid = gtk_tree_model_iter_parent(model, &parent, &iter_);
389 202 hiro
        }
390 202 hiro
391 202 hiro
        return FALSE;
392 202 hiro
}
393 202 hiro
394 237 hiro
gboolean gtkut_tree_model_prev(GtkTreeModel *model, GtkTreeIter *iter)
395 237 hiro
{
396 237 hiro
        GtkTreeIter iter_, child, next, parent;
397 237 hiro
        GtkTreePath *path;
398 237 hiro
        gboolean found = FALSE;
399 237 hiro
400 237 hiro
        iter_ = *iter;
401 237 hiro
402 237 hiro
        path = gtk_tree_model_get_path(model, &iter_);
403 237 hiro
404 237 hiro
        if (gtk_tree_path_prev(path)) {
405 237 hiro
                gtk_tree_model_get_iter(model, &child, path);
406 237 hiro
407 237 hiro
                while (gtk_tree_model_iter_has_child(model, &child)) {
408 237 hiro
                        iter_ = child;
409 237 hiro
                        gtk_tree_model_iter_children(model, &child, &iter_);
410 237 hiro
                        next = child;
411 237 hiro
                        while (gtk_tree_model_iter_next(model, &next))
412 237 hiro
                                child = next;
413 237 hiro
                }
414 237 hiro
415 237 hiro
                *iter = child;
416 237 hiro
                found = TRUE;
417 237 hiro
        } else if (gtk_tree_model_iter_parent(model, &parent, &iter_)) {
418 237 hiro
                *iter = parent;
419 237 hiro
                found = TRUE;
420 237 hiro
        }
421 237 hiro
422 237 hiro
        gtk_tree_path_free(path);
423 237 hiro
424 237 hiro
        return found;
425 237 hiro
}
426 237 hiro
427 237 hiro
gboolean gtkut_tree_model_get_iter_last(GtkTreeModel *model, GtkTreeIter *iter)
428 237 hiro
{
429 237 hiro
        GtkTreeIter iter_, child, next;
430 237 hiro
431 237 hiro
        if (!gtk_tree_model_get_iter_first(model, &iter_))
432 237 hiro
                return FALSE;
433 237 hiro
434 237 hiro
        for (;;) {
435 237 hiro
                next = iter_;
436 237 hiro
                while (gtk_tree_model_iter_next(model, &next))
437 237 hiro
                        iter_ = next;
438 237 hiro
                if (gtk_tree_model_iter_children(model, &child, &iter_))
439 237 hiro
                        iter_ = child;
440 237 hiro
                else
441 237 hiro
                        break;
442 237 hiro
        }
443 237 hiro
444 237 hiro
        *iter = iter_;
445 237 hiro
        return TRUE;
446 237 hiro
}
447 237 hiro
448 202 hiro
gboolean gtkut_tree_model_find_by_column_data(GtkTreeModel *model,
449 202 hiro
                                              GtkTreeIter *iter,
450 202 hiro
                                              GtkTreeIter *start,
451 202 hiro
                                              gint col, gpointer data)
452 202 hiro
{
453 202 hiro
        gboolean valid;
454 202 hiro
        GtkTreeIter iter_;
455 202 hiro
        gpointer store_data;
456 202 hiro
457 258 hiro
        if (start) {
458 258 hiro
                gtk_tree_model_get(model, start, col, &store_data, -1);
459 258 hiro
                if (store_data == data) {
460 258 hiro
                        *iter = *start;
461 258 hiro
                        return TRUE;
462 258 hiro
                }
463 202 hiro
                valid = gtk_tree_model_iter_children(model, &iter_, start);
464 258 hiro
        } else
465 202 hiro
                valid = gtk_tree_model_get_iter_first(model, &iter_);
466 202 hiro
467 202 hiro
        while (valid) {
468 258 hiro
                if (gtkut_tree_model_find_by_column_data
469 258 hiro
                        (model, iter, &iter_, col, data)) {
470 202 hiro
                        return TRUE;
471 202 hiro
                }
472 202 hiro
473 202 hiro
                valid = gtk_tree_model_iter_next(model, &iter_);
474 202 hiro
        }
475 202 hiro
476 202 hiro
        return FALSE;
477 202 hiro
}
478 202 hiro
479 935 hiro
void gtkut_tree_model_foreach(GtkTreeModel *model, GtkTreeIter *start,
480 935 hiro
                              GtkTreeModelForeachFunc func, gpointer user_data)
481 935 hiro
{
482 935 hiro
        gboolean valid = TRUE;
483 935 hiro
        GtkTreeIter iter;
484 935 hiro
        GtkTreePath *path;
485 935 hiro
486 935 hiro
        g_return_if_fail(func != NULL);
487 935 hiro
488 935 hiro
        if (!start) {
489 935 hiro
                gtk_tree_model_foreach(model, func, user_data);
490 935 hiro
                return;
491 935 hiro
        }
492 935 hiro
493 935 hiro
        path = gtk_tree_model_get_path(model, start);
494 935 hiro
        func(model, path, start, user_data);
495 935 hiro
        gtk_tree_path_free(path);
496 935 hiro
497 935 hiro
        valid = gtk_tree_model_iter_children(model, &iter, start);
498 935 hiro
        while (valid) {
499 935 hiro
                gtkut_tree_model_foreach(model, &iter, func, user_data);
500 935 hiro
                valid = gtk_tree_model_iter_next(model, &iter);
501 935 hiro
        }
502 935 hiro
}
503 935 hiro
504 237 hiro
gboolean gtkut_tree_row_reference_get_iter(GtkTreeModel *model,
505 237 hiro
                                           GtkTreeRowReference *ref,
506 237 hiro
                                           GtkTreeIter *iter)
507 237 hiro
{
508 237 hiro
        GtkTreePath *path;
509 237 hiro
        gboolean valid = FALSE;
510 237 hiro
511 237 hiro
        if (ref) {
512 237 hiro
                path = gtk_tree_row_reference_get_path(ref);
513 237 hiro
                if (path) {
514 237 hiro
                        valid = gtk_tree_model_get_iter(model, iter, path);
515 237 hiro
                        gtk_tree_path_free(path);
516 237 hiro
                }
517 237 hiro
        }
518 237 hiro
519 237 hiro
        return valid;
520 237 hiro
}
521 237 hiro
522 212 hiro
gboolean gtkut_tree_row_reference_equal(GtkTreeRowReference *ref1,
523 212 hiro
                                        GtkTreeRowReference *ref2)
524 212 hiro
{
525 212 hiro
        GtkTreePath *path1, *path2;
526 212 hiro
        gint result;
527 212 hiro
528 237 hiro
        if (ref1 == NULL || ref2 == NULL)
529 237 hiro
                return FALSE;
530 212 hiro
531 212 hiro
        path1 = gtk_tree_row_reference_get_path(ref1);
532 253 hiro
        if (!path1)
533 253 hiro
                return FALSE;
534 212 hiro
        path2 = gtk_tree_row_reference_get_path(ref2);
535 253 hiro
        if (!path2) {
536 253 hiro
                gtk_tree_path_free(path1);
537 253 hiro
                return FALSE;
538 253 hiro
        }
539 212 hiro
540 212 hiro
        result = gtk_tree_path_compare(path1, path2);
541 212 hiro
542 212 hiro
        gtk_tree_path_free(path2);
543 212 hiro
        gtk_tree_path_free(path1);
544 212 hiro
545 212 hiro
        return (result == 0);
546 212 hiro
}
547 212 hiro
548 239 hiro
void gtkut_tree_sortable_unset_sort_column_id(GtkTreeSortable *sortable)
549 239 hiro
{
550 239 hiro
#if GTK_CHECK_VERSION(2, 6, 0)
551 239 hiro
        gtk_tree_sortable_set_sort_column_id
552 239 hiro
                (sortable, GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID,
553 239 hiro
                 GTK_SORT_ASCENDING);
554 239 hiro
#else
555 239 hiro
        GtkTreeStore *store = GTK_TREE_STORE(sortable);
556 239 hiro
557 239 hiro
        g_return_if_fail(GTK_IS_TREE_STORE(sortable));
558 239 hiro
559 239 hiro
        if (store->sort_column_id == -2 && store->order == GTK_SORT_ASCENDING)
560 239 hiro
                return;
561 239 hiro
562 239 hiro
        store->sort_column_id = -2;
563 239 hiro
        store->order = GTK_SORT_ASCENDING;
564 239 hiro
565 239 hiro
        gtk_tree_sortable_sort_column_changed(sortable);
566 239 hiro
#endif
567 239 hiro
}
568 239 hiro
569 202 hiro
gboolean gtkut_tree_view_find_collapsed_parent(GtkTreeView *treeview,
570 202 hiro
                                               GtkTreeIter *parent,
571 202 hiro
                                               GtkTreeIter *iter)
572 202 hiro
{
573 202 hiro
        GtkTreeModel *model;
574 202 hiro
        GtkTreeIter iter_, parent_;
575 202 hiro
        GtkTreePath *path;
576 202 hiro
        gboolean valid;
577 202 hiro
578 202 hiro
        if (!iter) return FALSE;
579 202 hiro
580 202 hiro
        model = gtk_tree_view_get_model(treeview);
581 202 hiro
        valid = gtk_tree_model_iter_parent(model, &parent_, iter);
582 202 hiro
583 202 hiro
        while (valid) {
584 202 hiro
                path = gtk_tree_model_get_path(model, &parent_);
585 202 hiro
                if (!gtk_tree_view_row_expanded(treeview, path)) {
586 202 hiro
                        *parent = parent_;
587 202 hiro
                        gtk_tree_path_free(path);
588 202 hiro
                        return TRUE;
589 202 hiro
                }
590 202 hiro
                gtk_tree_path_free(path);
591 202 hiro
                iter_ = parent_;
592 202 hiro
                valid = gtk_tree_model_iter_parent(model, &parent_, &iter_);
593 202 hiro
        }
594 202 hiro
595 202 hiro
        return FALSE;
596 202 hiro
}
597 202 hiro
598 237 hiro
void gtkut_tree_view_expand_parent_all(GtkTreeView *treeview, GtkTreeIter *iter)
599 237 hiro
{
600 237 hiro
        GtkTreeModel *model;
601 237 hiro
        GtkTreeIter parent;
602 237 hiro
        GtkTreePath *path;
603 237 hiro
604 237 hiro
        model = gtk_tree_view_get_model(treeview);
605 237 hiro
606 237 hiro
        if (gtk_tree_model_iter_parent(model, &parent, iter)) {
607 237 hiro
                path = gtk_tree_model_get_path(model, &parent);
608 237 hiro
                gtk_tree_view_expand_to_path(treeview, path);
609 237 hiro
                gtk_tree_path_free(path);
610 237 hiro
        }
611 237 hiro
}
612 237 hiro
613 207 hiro
#define SCROLL_EDGE_SIZE 15
614 207 hiro
615 207 hiro
/* borrowed from gtktreeview.c */
616 207 hiro
void gtkut_tree_view_vertical_autoscroll(GtkTreeView *treeview)
617 207 hiro
{
618 207 hiro
        GdkRectangle visible_rect;
619 207 hiro
        gint y, wy;
620 207 hiro
        gint offset;
621 207 hiro
        GtkAdjustment *vadj;
622 207 hiro
        gfloat value;
623 207 hiro
624 207 hiro
        gdk_window_get_pointer(gtk_tree_view_get_bin_window(treeview),
625 207 hiro
                               NULL, &wy, NULL);
626 207 hiro
        gtk_tree_view_widget_to_tree_coords(treeview, 0, wy, NULL, &y);
627 207 hiro
628 207 hiro
        gtk_tree_view_get_visible_rect(treeview, &visible_rect);
629 207 hiro
630 207 hiro
        /* see if we are near the edge. */
631 207 hiro
        offset = y - (visible_rect.y + 2 * SCROLL_EDGE_SIZE);
632 207 hiro
        if (offset > 0) {
633 207 hiro
                offset = y - (visible_rect.y + visible_rect.height - 2 * SCROLL_EDGE_SIZE);
634 207 hiro
                if (offset < 0)
635 207 hiro
                        return;
636 207 hiro
        }
637 207 hiro
638 207 hiro
        vadj = gtk_tree_view_get_vadjustment(treeview);
639 207 hiro
        value = CLAMP(vadj->value + offset, 0.0, vadj->upper - vadj->page_size);
640 207 hiro
        gtk_adjustment_set_value(vadj, value);
641 207 hiro
}
642 207 hiro
643 322 hiro
/* modified version of gtk_tree_view_scroll_to_cell */
644 600 hiro
void gtkut_tree_view_scroll_to_cell(GtkTreeView *treeview, GtkTreePath *path,
645 600 hiro
                                    gboolean align_center)
646 322 hiro
{
647 322 hiro
        GdkRectangle cell_rect;
648 322 hiro
        GdkRectangle vis_rect;
649 322 hiro
        gint dest_x, dest_y;
650 420 hiro
        gint margin = 0;
651 322 hiro
652 322 hiro
        if (!path)
653 322 hiro
                return;
654 322 hiro
655 322 hiro
        gtk_tree_view_get_cell_area(treeview, path, NULL, &cell_rect);
656 322 hiro
        gtk_tree_view_widget_to_tree_coords(treeview, cell_rect.x, cell_rect.y,
657 322 hiro
                                            NULL, &(cell_rect.y));
658 322 hiro
        gtk_tree_view_get_visible_rect(treeview, &vis_rect);
659 322 hiro
660 322 hiro
        dest_x = vis_rect.x;
661 322 hiro
        dest_y = vis_rect.y;
662 322 hiro
663 420 hiro
        /* add margin */
664 420 hiro
        if (cell_rect.height * 2 < vis_rect.height)
665 600 hiro
                margin = cell_rect.height + (align_center ? 0 : 2);
666 322 hiro
667 600 hiro
        if (cell_rect.y < vis_rect.y + margin) {
668 600 hiro
                if (align_center)
669 600 hiro
                        dest_y = cell_rect.y -
670 600 hiro
                                (vis_rect.height - cell_rect.height) / 2;
671 600 hiro
                else
672 600 hiro
                        dest_y = cell_rect.y - margin;
673 600 hiro
        }
674 420 hiro
        if (cell_rect.y + cell_rect.height >
675 600 hiro
                vis_rect.y + vis_rect.height - margin) {
676 600 hiro
                if (align_center)
677 600 hiro
                        dest_y = cell_rect.y -
678 600 hiro
                                (vis_rect.height - cell_rect.height) / 2;
679 600 hiro
                else
680 600 hiro
                        dest_y = cell_rect.y + cell_rect.height -
681 600 hiro
                                vis_rect.height + margin;
682 600 hiro
        }
683 420 hiro
684 322 hiro
        gtk_tree_view_scroll_to_point(treeview, dest_x, dest_y);
685 322 hiro
}
686 322 hiro
687 1089 hiro
void gtkut_tree_view_fast_clear(GtkTreeView *treeview, GtkTreeStore *store)
688 1089 hiro
{
689 1223 hiro
#if GTK_CHECK_VERSION(2, 8, 0) && !GTK_CHECK_VERSION(2, 10, 0)
690 1089 hiro
        gtk_tree_store_clear(store);
691 1089 hiro
#else
692 1089 hiro
        /* this is faster than above, but it seems to trigger crashes in
693 1089 hiro
           GTK+ 2.8.x */
694 1089 hiro
        gtk_tree_view_set_model(treeview, NULL);
695 1089 hiro
        gtk_tree_store_clear(store);
696 1089 hiro
        gtk_tree_view_set_model(treeview, GTK_TREE_MODEL(store));
697 1089 hiro
#endif
698 1089 hiro
}
699 1089 hiro
700 1 hiro
void gtkut_combo_set_items(GtkCombo *combo, const gchar *str1, ...)
701 1 hiro
{
702 1 hiro
        va_list args;
703 1 hiro
        gchar *s;
704 1 hiro
        GList *combo_items = NULL;
705 1 hiro
706 1 hiro
        g_return_if_fail(str1 != NULL);
707 1 hiro
708 1 hiro
        combo_items = g_list_append(combo_items, (gpointer)str1);
709 1 hiro
        va_start(args, str1);
710 1 hiro
        s = va_arg(args, gchar*);
711 1 hiro
        while (s) {
712 1 hiro
                combo_items = g_list_append(combo_items, (gpointer)s);
713 1 hiro
                s = va_arg(args, gchar*);
714 1 hiro
        }
715 1 hiro
        va_end(args);
716 1 hiro
717 1 hiro
        gtk_combo_set_popdown_strings(combo, combo_items);
718 1 hiro
719 1 hiro
        g_list_free(combo_items);
720 1 hiro
}
721 1 hiro
722 1 hiro
gchar *gtkut_editable_get_selection(GtkEditable *editable)
723 1 hiro
{
724 583 hiro
        gint start_pos, end_pos;
725 1 hiro
        gboolean found;
726 1 hiro
727 1 hiro
        g_return_val_if_fail(GTK_IS_EDITABLE(editable), NULL);
728 1 hiro
729 1 hiro
        found = gtk_editable_get_selection_bounds(editable,
730 1 hiro
                                                  &start_pos, &end_pos);
731 1 hiro
        if (found)
732 1 hiro
                return gtk_editable_get_chars(editable, start_pos, end_pos);
733 1 hiro
        else
734 1 hiro
                return NULL;
735 1 hiro
}
736 1 hiro
737 1 hiro
void gtkut_editable_disable_im(GtkEditable *editable)
738 1 hiro
{
739 1 hiro
        g_return_if_fail(editable != NULL);
740 1 hiro
741 1 hiro
#if USE_XIM
742 1 hiro
        if (editable->ic) {
743 1 hiro
                gdk_ic_destroy(editable->ic);
744 1 hiro
                editable->ic = NULL;
745 1 hiro
        }
746 1 hiro
        if (editable->ic_attr) {
747 1 hiro
                gdk_ic_attr_destroy(editable->ic_attr);
748 1 hiro
                editable->ic_attr = NULL;
749 1 hiro
        }
750 1 hiro
#endif
751 1 hiro
}
752 1 hiro
753 1 hiro
void gtkut_container_remove(GtkContainer *container, GtkWidget *widget)
754 1 hiro
{
755 1 hiro
        gtk_container_remove(container, widget);
756 1 hiro
}
757 1 hiro
758 198 hiro
void gtkut_scrolled_window_reset_position(GtkScrolledWindow *window)
759 198 hiro
{
760 198 hiro
        GtkAdjustment *adj;
761 198 hiro
762 198 hiro
        adj = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(window));
763 198 hiro
        gtk_adjustment_set_value(adj, adj->lower);
764 198 hiro
        adj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(window));
765 198 hiro
        gtk_adjustment_set_value(adj, adj->lower);
766 198 hiro
}
767 198 hiro
768 123 hiro
gboolean gtkut_text_buffer_match_string(GtkTextBuffer *textbuf,
769 123 hiro
                                        const GtkTextIter *iter,
770 1 hiro
                                        gunichar *wcs, gint len,
771 1 hiro
                                        gboolean case_sens)
772 1 hiro
{
773 1 hiro
        GtkTextIter start_iter, end_iter;
774 123 hiro
        gchar *utf8str, *p;
775 123 hiro
        gint match_count;
776 1 hiro
777 123 hiro
        start_iter = end_iter = *iter;
778 123 hiro
        gtk_text_iter_forward_chars(&end_iter, len);
779 1 hiro
780 123 hiro
        utf8str = gtk_text_buffer_get_text(textbuf, &start_iter, &end_iter,
781 123 hiro
                                           FALSE);
782 1 hiro
        if (!utf8str) return FALSE;
783 1 hiro
784 1 hiro
        if ((gint)g_utf8_strlen(utf8str, -1) != len) {
785 1 hiro
                g_free(utf8str);
786 1 hiro
                return FALSE;
787 1 hiro
        }
788 1 hiro
789 123 hiro
        for (p = utf8str, match_count = 0;
790 123 hiro
             *p != '\0' && match_count < len;
791 123 hiro
             p = g_utf8_next_char(p), match_count++) {
792 123 hiro
                gunichar wc;
793 1 hiro
794 123 hiro
                wc = g_utf8_get_char(p);
795 1 hiro
796 1 hiro
                if (case_sens) {
797 123 hiro
                        if (wc != wcs[match_count])
798 1 hiro
                                break;
799 1 hiro
                } else {
800 123 hiro
                        if (g_unichar_tolower(wc) !=
801 1 hiro
                            g_unichar_tolower(wcs[match_count]))
802 1 hiro
                                break;
803 1 hiro
                }
804 1 hiro
        }
805 1 hiro
806 1 hiro
        g_free(utf8str);
807 1 hiro
808 1 hiro
        if (match_count == len)
809 1 hiro
                return TRUE;
810 1 hiro
        else
811 1 hiro
                return FALSE;
812 1 hiro
}
813 1 hiro
814 123 hiro
gboolean gtkut_text_buffer_find(GtkTextBuffer *buffer, const GtkTextIter *iter,
815 123 hiro
                                const gchar *str, gboolean case_sens,
816 123 hiro
                                GtkTextIter *match_pos)
817 1 hiro
{
818 1 hiro
        gunichar *wcs;
819 123 hiro
        gint len;
820 1 hiro
        glong items_read = 0, items_written = 0;
821 1 hiro
        GError *error = NULL;
822 123 hiro
        GtkTextIter iter_;
823 123 hiro
        gboolean found = FALSE;
824 1 hiro
825 1 hiro
        wcs = g_utf8_to_ucs4(str, -1, &items_read, &items_written, &error);
826 1 hiro
        if (error != NULL) {
827 1 hiro
                g_warning("An error occured while converting a string from UTF-8 to UCS-4: %s\n", error->message);
828 1 hiro
                g_error_free(error);
829 1 hiro
        }
830 123 hiro
        if (!wcs || items_written <= 0) return FALSE;
831 123 hiro
        len = (gint)items_written;
832 1 hiro
833 123 hiro
        iter_ = *iter;
834 123 hiro
        do {
835 123 hiro
                found = gtkut_text_buffer_match_string
836 123 hiro
                        (buffer, &iter_, wcs, len, case_sens);
837 123 hiro
                if (found) {
838 123 hiro
                        *match_pos = iter_;
839 123 hiro
                        break;
840 123 hiro
                }
841 123 hiro
        } while (gtk_text_iter_forward_char(&iter_));
842 1 hiro
843 1 hiro
        g_free(wcs);
844 1 hiro
845 123 hiro
        return found;
846 1 hiro
}
847 1 hiro
848 123 hiro
gboolean gtkut_text_buffer_find_backward(GtkTextBuffer *buffer,
849 123 hiro
                                         const GtkTextIter *iter,
850 123 hiro
                                         const gchar *str, gboolean case_sens,
851 123 hiro
                                         GtkTextIter *match_pos)
852 90 hiro
{
853 90 hiro
        gunichar *wcs;
854 90 hiro
        gint len;
855 90 hiro
        glong items_read = 0, items_written = 0;
856 90 hiro
        GError *error = NULL;
857 123 hiro
        GtkTextIter iter_;
858 123 hiro
        gboolean found = FALSE;
859 90 hiro
860 90 hiro
        wcs = g_utf8_to_ucs4(str, -1, &items_read, &items_written, &error);
861 90 hiro
        if (error != NULL) {
862 90 hiro
                g_warning("An error occured while converting a string from UTF-8 to UCS-4: %s\n", error->message);
863 90 hiro
                g_error_free(error);
864 90 hiro
        }
865 123 hiro
        if (!wcs || items_written <= 0) return FALSE;
866 90 hiro
        len = (gint)items_written;
867 90 hiro
868 123 hiro
        iter_ = *iter;
869 123 hiro
        while (gtk_text_iter_backward_char(&iter_)) {
870 123 hiro
                found = gtkut_text_buffer_match_string
871 123 hiro
                        (buffer, &iter_, wcs, len, case_sens);
872 123 hiro
                if (found) {
873 123 hiro
                        *match_pos = iter_;
874 90 hiro
                        break;
875 90 hiro
                }
876 123 hiro
        }
877 90 hiro
878 90 hiro
        g_free(wcs);
879 90 hiro
880 123 hiro
        return found;
881 1 hiro
}
882 1 hiro
883 153 hiro
#define MAX_TEXT_LINE_LEN        8190
884 153 hiro
885 153 hiro
void gtkut_text_buffer_insert_with_tag_by_name(GtkTextBuffer *buffer,
886 153 hiro
                                               GtkTextIter *iter,
887 153 hiro
                                               const gchar *text,
888 153 hiro
                                               gint len,
889 153 hiro
                                               const gchar *tag)
890 153 hiro
{
891 153 hiro
        if (len < 0)
892 153 hiro
                len = strlen(text);
893 153 hiro
894 153 hiro
        gtk_text_buffer_insert_with_tags_by_name
895 153 hiro
                (buffer, iter, text, len, tag, NULL);
896 153 hiro
897 153 hiro
        if (text[len - 1] != '\n') {
898 153 hiro
                /* somehow returns invalid value first (bug?),
899 153 hiro
                   so call it twice */
900 153 hiro
                gtk_text_iter_get_chars_in_line(iter);
901 153 hiro
                if (gtk_text_iter_get_chars_in_line(iter) > MAX_TEXT_LINE_LEN) {
902 153 hiro
                        gtk_text_buffer_insert_with_tags_by_name
903 153 hiro
                                (buffer, iter, "\n", 1, tag, NULL);
904 153 hiro
                }
905 153 hiro
        }
906 153 hiro
}
907 153 hiro
908 1 hiro
gchar *gtkut_text_view_get_selection(GtkTextView *textview)
909 1 hiro
{
910 1 hiro
        GtkTextBuffer *buffer;
911 1 hiro
        GtkTextIter start_iter, end_iter;
912 1 hiro
        gboolean found;
913 1 hiro
914 1 hiro
        g_return_val_if_fail(GTK_IS_TEXT_VIEW(textview), NULL);
915 1 hiro
916 1 hiro
        buffer = gtk_text_view_get_buffer(textview);
917 1 hiro
        found = gtk_text_buffer_get_selection_bounds(buffer,
918 1 hiro
                                                     &start_iter, &end_iter);
919 1 hiro
        if (found)
920 1 hiro
                return gtk_text_buffer_get_text(buffer, &start_iter, &end_iter,
921 1 hiro
                                                FALSE);
922 1 hiro
        else
923 1 hiro
                return NULL;
924 1 hiro
}
925 1 hiro
926 1 hiro
void gtkut_window_popup(GtkWidget *window)
927 1 hiro
{
928 1 hiro
        gint x, y, sx, sy, new_x, new_y;
929 1 hiro
930 1 hiro
        g_return_if_fail(window != NULL);
931 1 hiro
        g_return_if_fail(window->window != NULL);
932 1 hiro
933 1 hiro
        sx = gdk_screen_width();
934 1 hiro
        sy = gdk_screen_height();
935 1 hiro
936 1 hiro
        gdk_window_get_origin(window->window, &x, &y);
937 1 hiro
        new_x = x % sx; if (new_x < 0) new_x = 0;
938 1 hiro
        new_y = y % sy; if (new_y < 0) new_y = 0;
939 1 hiro
        if (new_x != x || new_y != y)
940 1 hiro
                gdk_window_move(window->window, new_x, new_y);
941 1 hiro
942 1216 hiro
        gtk_window_set_skip_taskbar_hint(GTK_WINDOW(window), FALSE);
943 94 hiro
        gtk_window_present(GTK_WINDOW(window));
944 1339 hiro
#ifdef G_OS_WIN32
945 1339 hiro
        /* ensure that the window is displayed at the top */
946 1339 hiro
        gdk_window_show(window->window);
947 1339 hiro
#endif
948 1 hiro
}
949 1 hiro
950 962 hiro
gboolean gtkut_window_modal_exist(void)
951 962 hiro
{
952 962 hiro
        GList *window_list, *cur;
953 962 hiro
        gboolean exist = FALSE;
954 962 hiro
955 962 hiro
        window_list = gtk_window_list_toplevels();
956 962 hiro
        for (cur = window_list; cur != NULL; cur = cur->next) {
957 962 hiro
                GtkWidget *window = GTK_WIDGET(cur->data);
958 962 hiro
959 962 hiro
                if (GTK_WIDGET_VISIBLE(window) &&
960 962 hiro
                    gtk_window_get_modal(GTK_WINDOW(window))) {
961 962 hiro
                        exist = TRUE;
962 962 hiro
                        break;
963 962 hiro
                }
964 962 hiro
        }
965 962 hiro
        g_list_free(window_list);
966 962 hiro
967 962 hiro
        return exist;
968 962 hiro
}
969 962 hiro
970 1 hiro
void gtkut_widget_get_uposition(GtkWidget *widget, gint *px, gint *py)
971 1 hiro
{
972 1 hiro
        gint x, y;
973 1 hiro
        gint sx, sy;
974 1 hiro
975 1 hiro
        g_return_if_fail(widget != NULL);
976 1 hiro
        g_return_if_fail(widget->window != NULL);
977 1 hiro
978 1 hiro
        sx = gdk_screen_width();
979 1 hiro
        sy = gdk_screen_height();
980 1 hiro
981 1 hiro
        /* gdk_window_get_root_origin ever return *rootwindow*'s position */
982 1 hiro
        gdk_window_get_root_origin(widget->window, &x, &y);
983 1 hiro
984 1 hiro
        x %= sx; if (x < 0) x = 0;
985 1 hiro
        y %= sy; if (y < 0) y = 0;
986 1 hiro
        *px = x;
987 1 hiro
        *py = y;
988 1 hiro
}
989 1 hiro
990 227 hiro
void gtkut_widget_draw_now(GtkWidget *widget)
991 1 hiro
{
992 227 hiro
        if (GTK_WIDGET_VISIBLE(widget) && GTK_WIDGET_DRAWABLE(widget))
993 227 hiro
                gdk_window_process_updates(widget->window, FALSE);
994 1 hiro
}
995 1 hiro
996 1 hiro
static void gtkut_clist_bindings_add(GtkWidget *clist)
997 1 hiro
{
998 1 hiro
        GtkBindingSet *binding_set;
999 1 hiro
1000 1 hiro
        binding_set = gtk_binding_set_by_class(GTK_CLIST_GET_CLASS(clist));
1001 1 hiro
1002 1 hiro
        gtk_binding_entry_add_signal(binding_set, GDK_n, GDK_CONTROL_MASK,
1003 1 hiro
                                     "scroll_vertical", 2,
1004 1 hiro
                                     G_TYPE_ENUM, GTK_SCROLL_STEP_FORWARD,
1005 1 hiro
                                     G_TYPE_FLOAT, 0.0);
1006 1 hiro
        gtk_binding_entry_add_signal(binding_set, GDK_p, GDK_CONTROL_MASK,
1007 1 hiro
                                     "scroll_vertical", 2,
1008 1 hiro
                                     G_TYPE_ENUM, GTK_SCROLL_STEP_BACKWARD,
1009 1 hiro
                                     G_TYPE_FLOAT, 0.0);
1010 1 hiro
}
1011 1 hiro
1012 1 hiro
void gtkut_widget_init(void)
1013 1 hiro
{
1014 1 hiro
        GtkWidget *clist;
1015 1 hiro
1016 1 hiro
        clist = gtk_clist_new(1);
1017 1 hiro
        g_object_ref(G_OBJECT(clist));
1018 1 hiro
        gtk_object_sink(GTK_OBJECT(clist));
1019 1 hiro
        gtkut_clist_bindings_add(clist);
1020 1 hiro
        g_object_unref(G_OBJECT(clist));
1021 1 hiro
1022 1 hiro
        clist = gtk_ctree_new(1, 0);
1023 1 hiro
        g_object_ref(G_OBJECT(clist));
1024 1 hiro
        gtk_object_sink(GTK_OBJECT(clist));
1025 1 hiro
        gtkut_clist_bindings_add(clist);
1026 1 hiro
        g_object_unref(G_OBJECT(clist));
1027 1 hiro
}
1028 552 hiro
1029 552 hiro
void gtkut_events_flush(void)
1030 552 hiro
{
1031 552 hiro
        GTK_EVENTS_FLUSH();
1032 552 hiro
}