Statistics
| Revision:

root / src / gtkutils.c @ 2811

History | View | Annotate | Download (25.1 kB)

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