8 #define YUILogComponent "gtk"
9 #include <yui/Libyui_config.h>
15 static inline void skipSpace (
const char *instr,
int *i)
16 {
while (g_ascii_isspace (instr[*i])) (*i)++; }
21 unsigned int early_closer : 1;
25 tag_entry_new (GString *tag,
int tag_len)
27 static const char *early_closers[] = {
"p",
"li" };
30 entry->tag_len = tag_len;
31 entry->early_closer = FALSE;
34 for (i = 0; i < G_N_ELEMENTS (early_closers); i++)
35 if (!g_ascii_strncasecmp (tag->str, early_closers[i], tag_len))
36 entry->early_closer = TRUE;
43 if (entry && entry->tag)
44 g_string_free (entry->tag, TRUE);
49 emit_unclosed_tags_for (GString *outp, GQueue *tag_queue,
const char *tag_str,
int tag_len)
51 gboolean matched = FALSE;
54 if (g_queue_is_empty (tag_queue))
62 if (last_entry->tag_len != tag_len ||
63 g_ascii_strncasecmp (last_entry->tag->str, tag_str, tag_len)) {
65 g_string_append (outp,
"</");
66 g_string_append_len (outp, last_entry->tag->str, last_entry->tag_len);
67 g_string_append_c (outp,
'>');
71 tag_entry_free (last_entry);
76 check_early_close (GString *outp, GQueue *tag_queue,
TagEntry *entry)
81 if (!entry->early_closer)
84 last_tag = (
TagEntry *) g_queue_peek_tail (tag_queue);
85 if (!last_tag || !last_tag->early_closer)
88 if (entry->tag_len != last_tag->tag_len ||
89 g_ascii_strncasecmp (last_tag->tag->str, entry->tag->str, entry->tag_len))
94 g_string_append (outp,
"</");
95 g_string_append_len (outp, entry->tag->str, entry->tag_len);
96 g_string_append_c (outp,
'>');
103 const gchar *html, *text;
111 static const EntityMap *lookup_entity (
const char *html)
114 for (i = 0; i <
sizeof (entities) /
sizeof (
EntityMap); i++)
115 if (!g_ascii_strncasecmp (html+1, entities[i].html, strlen (entities[i].html)))
123 gchar *ygutils_convert_to_xhtml (
const char *instr)
125 GString *outp = g_string_new (
"");
126 GQueue *tag_queue = g_queue_new();
129 gboolean allow_space = FALSE, pre_mode = FALSE;
130 skipSpace (instr, &i);
133 g_string_append (outp,
"<body>");
135 for (; instr[i] !=
'\0'; i++)
138 if (instr[i] ==
'<') {
140 if (strncmp (&instr[i],
"<!--", 4) == 0) {
141 for (i += 3; instr[i] !=
'\0'; i++)
142 if (strncmp (&instr[i],
"-->", 3) == 0) {
150 gboolean is_close = FALSE;
153 GString *tag = g_string_sized_new (20);
156 skipSpace (instr, &i);
158 if (instr[i] ==
'/') {
163 skipSpace (instr, &i);
168 for (; instr[i] !=
'>' && instr[i]; i++) {
170 if (!g_ascii_isalnum(instr[i]))
175 g_string_append_c (tag, instr[i]);
179 if (!is_close && tag_len == 2 &&
180 (!g_ascii_strncasecmp (tag->str,
"hr", 2) ||
181 !g_ascii_strncasecmp (tag->str,
"br", 2)) &&
182 tag->str[tag->len - 1] !=
'/')
183 g_string_append_c (tag,
'/');
185 if (!g_ascii_strncasecmp (tag->str,
"pre", 3))
186 pre_mode = !is_close;
190 for (k = 0; k < tag->len; k++) {
191 if (tag->str[k] ==
'=') {
192 gboolean unquote = tag->str[k+1] !=
'"';
194 g_string_insert_c (tag, k+1,
'"');
197 for (k++; tag->str[k]; k++) {
198 if (unquote && g_ascii_isspace (tag->str[k]))
200 else if (!unquote && tag->str[k] ==
'"')
204 g_string_insert_c (tag, k,
'"');
207 tag->str[k] = g_ascii_tolower (tag->str[k]);
213 while (j > 0 && g_ascii_isspace (tag->str[j])) j--;
215 gboolean is_open_close = (tag->str[j] ==
'/');
219 emit_unclosed_tags_for (outp, tag_queue, tag->str, tag_len);
221 TagEntry *entry = tag_entry_new (tag, tag_len);
224 entry->tag_len = tag_len;
226 if (!check_early_close (outp, tag_queue, entry))
227 g_queue_push_tail (tag_queue, entry);
230 tag_entry_free (entry);
234 g_string_append_c (outp,
'<');
236 g_string_append_c (outp,
'/');
237 g_string_append_len (outp, tag->str, tag->len);
238 g_string_append_c (outp,
'>');
240 if (is_close || is_open_close)
241 g_string_free (tag, TRUE);
243 allow_space = is_close;
246 else if (instr[i] ==
'&') {
247 const EntityMap *entity = lookup_entity (instr+i);
249 if (!strcmp (entity->html,
"product"))
250 g_string_append (outp, YUI::app()->productName().c_str());
252 g_string_append (outp, entity->text);
253 i += strlen (entity->html);
254 if (instr[i+1] ==
';') i++;
259 for (j = i + 1; instr[j] !=
'\0'; j++) {
260 if (!g_ascii_isalnum (instr[j]) && instr[j] !=
'#')
264 g_string_append (outp,
"&");
266 g_string_append_c (outp, instr[i]);
272 if (!pre_mode && g_ascii_isspace (instr[i])) {
274 g_string_append_c (outp,
' ');
279 g_string_append_c (outp, instr[i]);
284 emit_unclosed_tags_for (outp, tag_queue,
"", 0);
285 g_queue_free (tag_queue);
286 g_string_append (outp,
"</body>");
288 gchar *ret = g_string_free (outp, FALSE);
292 std::string YGUtils::mapKBAccel (
const std::string &src)
295 std::string::size_type length = src.length(), i;
297 str.reserve (length);
298 for (i = 0; i < length; i++) {
301 else if (src[i] ==
'&') {
302 if (i+1 < length && src[i+1] ==
'&') {
315 char *ygutils_mapKBAccel (
const char *src)
317 std::string ret (YGUtils::mapKBAccel (src));
318 return strdup (ret.c_str());
321 void YGUtils::setFilter (GtkEntry *entry,
const std::string &validChars)
324 static void insert_text_cb (GtkEditable *editable,
const gchar *new_text,
325 gint new_text_length, gint *pos)
327 const gchar *valid_chars = (gchar *) g_object_get_data (G_OBJECT (editable),
331 for (i = new_text; *i; i++) {
332 for (j = valid_chars; *j; j++) {
338 g_signal_stop_emission_by_name (editable,
"insert_text");
339 gtk_widget_error_bell (GTK_WIDGET (editable));
347 if (g_object_get_data (G_OBJECT (entry),
"insert-text-set"))
348 g_object_disconnect (G_OBJECT (entry),
"insert-text",
349 G_CALLBACK (inner::insert_text_cb), NULL);
351 if (!validChars.empty()) {
352 gchar *chars = g_strdup (validChars.c_str());
353 g_object_set_data_full (G_OBJECT (entry),
"valid-chars", chars, g_free);
354 g_signal_connect (G_OBJECT (entry),
"insert-text",
355 G_CALLBACK (inner::insert_text_cb), NULL);
356 g_object_set_data (G_OBJECT (entry),
"insert-text-set", GINT_TO_POINTER (1));
359 g_object_set_data (G_OBJECT (entry),
"insert-text-set", GINT_TO_POINTER (0));
362 void ygutils_setFilter (GtkEntry *entry,
const char *validChars)
363 { YGUtils::setFilter (entry, validChars); }
365 void YGUtils::replace (std::string &str,
const char *mouth,
int mouth_len,
const char *food)
368 mouth_len = strlen (mouth);
369 std::string::size_type i = 0;
370 while ((i = str.find (mouth, i)) != std::string::npos) {
371 str.erase (i, mouth_len);
372 str.insert (i, food);
376 std::string YGUtils::truncate (
const std::string &str,
int length,
int pos)
378 std::string ret (str);
379 const char *pstr = ret.c_str();
char *pi;
380 int size = g_utf8_strlen (pstr, -1);
383 pi = g_utf8_offset_to_pointer (pstr, length-3);
388 pi = g_utf8_offset_to_pointer (pstr, size-(length-3));
389 ret.erase (0, pi-pstr);
390 ret.insert (0,
"...");
393 pi = g_utf8_offset_to_pointer (pstr, size/2);
394 int delta = size - (length-3);
395 gchar *pn = pi, *pp = pi;
397 if (i++ == delta)
break;
398 pn = g_utf8_next_char (pn);
399 if (i++ == delta)
break;
400 pp = g_utf8_prev_char (pp);
402 g_assert (pp != NULL && pn != NULL);
404 ret.erase (pp-pstr, pn-pp);
405 ret.insert (pp-pstr,
"...");
411 static gboolean scroll_down_cb (
void *pData)
413 GtkAdjustment *vadj = (GtkAdjustment *) pData;
414 gtk_adjustment_set_value (vadj, gtk_adjustment_get_upper(vadj) - gtk_adjustment_get_page_size(vadj));
418 void YGUtils::scrollWidget (GtkAdjustment *vadj,
bool top)
421 gtk_adjustment_set_value (vadj, gtk_adjustment_get_lower(vadj));
425 g_idle_add_full (G_PRIORITY_LOW, scroll_down_cb, vadj, NULL);
428 void ygutils_scrollAdj (GtkAdjustment *vadj, gboolean top)
429 { YGUtils::scrollWidget (vadj, top); }
431 std::string YGUtils::escapeMarkup (
const std::string &ori)
433 std::string::size_type length = ori.length(), i;
435 ret.reserve (length * 1.5);
436 for (i = 0; i < length; i++)
454 bool YGUtils::endsWith (
const std::string &str,
const std::string &key)
456 if (str.size() < key.size())
458 return str.compare (str.size()-key.size(), key.size(), key) == 0;
461 int YGUtils::getCharsWidth (GtkWidget *widget,
int chars_nb)
463 GtkStyleContext *style_ctx = gtk_widget_get_style_context(widget);
464 PangoContext *context = gtk_widget_get_pango_context (widget);
465 PangoFontDescription *font_desc;
466 gtk_style_context_get (style_ctx, GTK_STATE_FLAG_NORMAL,
"font", &font_desc, NULL);
467 PangoFontMetrics *metrics = pango_context_get_metrics (context, font_desc, NULL);
469 int width = pango_font_metrics_get_approximate_char_width (metrics);
470 pango_font_metrics_unref (metrics);
472 return PANGO_PIXELS (width) * chars_nb;
475 int YGUtils::getCharsHeight (GtkWidget *widget,
int chars_nb)
477 GtkStyleContext *style_ctx = gtk_widget_get_style_context(widget);
478 PangoContext *context = gtk_widget_get_pango_context (widget);
479 PangoFontDescription *font_desc;
480 gtk_style_context_get (style_ctx, GTK_STATE_FLAG_NORMAL,
"font", &font_desc, NULL);
481 PangoFontMetrics *metrics = pango_context_get_metrics (context, font_desc, NULL);
483 int height = pango_font_metrics_get_ascent (metrics) +
484 pango_font_metrics_get_descent (metrics);
485 pango_font_metrics_unref (metrics);
487 return PANGO_PIXELS (height) * chars_nb;
490 void YGUtils::setWidgetFont (GtkWidget *widget, PangoStyle style, PangoWeight weight,
493 GtkStyleContext *style_ctx = gtk_widget_get_style_context(widget);
494 PangoFontDescription *font_desc;
495 gtk_style_context_get (style_ctx, GTK_STATE_FLAG_NORMAL,
"font", &font_desc, NULL);
497 int size = pango_font_description_get_size (font_desc);
498 PangoFontDescription* font = pango_font_description_new();
499 pango_font_description_set_weight (font, weight);
500 pango_font_description_set_size (font, (
int)(size * scale));
501 pango_font_description_set_style (font, style);
502 gtk_widget_override_font (widget, font);
505 void ygutils_setWidgetFont (GtkWidget *widget, PangoStyle style, PangoWeight weight,
double scale)
506 { YGUtils::setWidgetFont (widget, style, weight, scale); }
508 static void paned_allocate_cb (GtkWidget *paned, GtkAllocation *alloc, gpointer _rel)
510 if (!g_object_get_data (G_OBJECT (paned),
"init")) {
511 gdouble rel = GPOINTER_TO_INT (_rel) / 100.;
514 gtk_widget_get_allocation(paned, &alloc);
516 if (gtk_orientable_get_orientation (GTK_ORIENTABLE (paned)) == GTK_ORIENTATION_HORIZONTAL)
517 parent_size = alloc.width;
519 parent_size = alloc.height;
520 int pos = parent_size * rel;
521 gtk_paned_set_position (GTK_PANED (paned), pos);
522 g_object_set_data (G_OBJECT (paned),
"init", GINT_TO_POINTER (1));
526 void YGUtils::setPaneRelPosition (GtkWidget *paned, gdouble rel)
528 gint _rel = rel * 100;
529 g_signal_connect_after (G_OBJECT (paned),
"size-allocate",
530 G_CALLBACK (paned_allocate_cb), GINT_TO_POINTER (_rel));
533 void ygutils_setPaneRelPosition (GtkWidget *paned, gdouble rel)
534 { YGUtils::setPaneRelPosition (paned, rel); }
536 GdkPixbuf *YGUtils::loadPixbuf (
const std::string &filename)
538 GdkPixbuf *pixbuf = NULL;
539 if (!filename.empty()) {
541 pixbuf = gdk_pixbuf_new_from_file (filename.c_str(), &error);
543 yuiWarning() <<
"Could not load icon: " << filename <<
"\n"
544 "Reason: " << error->message <<
"\n";
550 static inline guchar pixel_clamp (
int val)
551 {
return MAX (0, MIN (255, val)); }
552 GdkPixbuf *YGUtils::setOpacity (
const GdkPixbuf *src,
int opacity,
bool touchAlpha)
554 if (!src)
return NULL;
555 int shift = 255 - ((opacity * 255) / 100);
556 int rgb_shift = 0, alpha_shift = 0;
562 int width = gdk_pixbuf_get_width (src), height = gdk_pixbuf_get_height (src);
563 gboolean has_alpha = gdk_pixbuf_get_has_alpha (src);
565 GdkPixbuf *dest = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (src),
566 has_alpha, gdk_pixbuf_get_bits_per_sample (src), width, height);
568 guchar *src_pixels_orig = gdk_pixbuf_get_pixels (src);
569 guchar *dest_pixels_orig = gdk_pixbuf_get_pixels (dest);
571 int src_rowstride = gdk_pixbuf_get_rowstride (src);
572 int dest_rowstride = gdk_pixbuf_get_rowstride (dest);
574 for (i = 0; i < height; i++) {
575 guchar *src_pixels = src_pixels_orig + (i * src_rowstride);
576 guchar *dest_pixels = dest_pixels_orig + (i * dest_rowstride);
577 for (j = 0; j < width; j++) {
578 *(dest_pixels++) = pixel_clamp (*(src_pixels++) + rgb_shift);
579 *(dest_pixels++) = pixel_clamp (*(src_pixels++) + rgb_shift);
580 *(dest_pixels++) = pixel_clamp (*(src_pixels++) + rgb_shift);
582 *(dest_pixels++) = pixel_clamp (*(src_pixels++) - alpha_shift);
588 GdkPixbuf *YGUtils::setGray (
const GdkPixbuf *src)
590 int width = gdk_pixbuf_get_width (src), height = gdk_pixbuf_get_height (src);
591 gboolean has_alpha = gdk_pixbuf_get_has_alpha (src);
593 GdkPixbuf *dest = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (src),
594 has_alpha, gdk_pixbuf_get_bits_per_sample (src), width, height);
596 guchar *src_pixels_orig = gdk_pixbuf_get_pixels (src);
597 guchar *dest_pixels_orig = gdk_pixbuf_get_pixels (dest);
599 int src_rowstride = gdk_pixbuf_get_rowstride (src);
600 int dest_rowstride = gdk_pixbuf_get_rowstride (dest);
602 for (i = 0; i < height; i++) {
603 guchar *src_pixels = src_pixels_orig + (i * src_rowstride);
604 guchar *dest_pixels = dest_pixels_orig + (i * dest_rowstride);
605 for (j = 0; j < width; j++) {
606 int clr = (src_pixels[0] + src_pixels[1] + src_pixels[2]) / 3;
607 *(dest_pixels++) = clr;
608 *(dest_pixels++) = clr;
609 *(dest_pixels++) = clr;
612 *(dest_pixels++) = *(src_pixels++);
618 GdkPixbuf *ygutils_setOpacity (
const GdkPixbuf *src,
int opacity, gboolean useAlpha)
619 {
return YGUtils::setOpacity (src, opacity, useAlpha); }
621 static std::string cutUnderline (
const std::string &str)
623 std::string ret (str);
624 std::string::size_type i = 0;
625 if ((i = ret.find (
'_', i)) != std::string::npos)
630 static void stripStart (std::string &str,
char ch)
632 while (!str.empty() && str[0] == ch)
635 static void stripEnd (std::string &str,
char ch)
637 while (!str.empty() && str[str.size()-1] == ch)
638 str.erase (str.size()-1, 1);
642 const char *english, *locale, *stock;
644 static const StockMap stock_map[] = {
645 {
"Apply", _(
"Apply"), GTK_STOCK_APPLY },
646 {
"Accept", _(
"Accept"), GTK_STOCK_APPLY },
647 {
"Install", _(
"Install"), GTK_STOCK_APPLY },
648 {
"OK", _(
"OK"), GTK_STOCK_OK },
649 {
"Cancel", _(
"Cancel"), GTK_STOCK_CANCEL },
650 {
"Abort", _(
"Abort"), GTK_STOCK_CANCEL },
651 {
"Close", _(
"Close"), GTK_STOCK_CLOSE },
652 {
"Yes", _(
"Yes"), GTK_STOCK_YES },
653 {
"No", _(
"No"), GTK_STOCK_NO },
654 {
"Add", _(
"Add"), GTK_STOCK_ADD },
655 {
"Edit", _(
"Edit"), GTK_STOCK_EDIT },
656 {
"Delete", _(
"Delete"), GTK_STOCK_DELETE },
657 {
"Up", _(
"Up"), GTK_STOCK_GO_UP },
658 {
"Down", _(
"Down"), GTK_STOCK_GO_DOWN },
659 {
"Enable", _(
"Enable"), GTK_STOCK_YES },
660 {
"Disable", _(
"Disable"), GTK_STOCK_NO },
661 {
"Exit", _(
"Exit"), GTK_STOCK_QUIT },
663 #define stock_map_length (sizeof (stock_map) / sizeof (StockMap))
665 const char *YGUtils::mapStockIcon (
const std::string &label)
667 static bool firstTime =
true;
static std::map <std::string, std::string> stockMap;
672 GSList *list = gtk_stock_list_ids();
673 for (GSList *i = list; i; i = i->next) {
674 gchar *
id = (gchar *) i->data;
676 if (gtk_stock_lookup (
id, &item)) {
677 const gchar *_id = id;
678 if (!strcmp (
id, GTK_STOCK_MEDIA_NEXT) || !strcmp (
id, GTK_STOCK_MEDIA_FORWARD))
679 _id = GTK_STOCK_GO_FORWARD;
680 else if (!strcmp (
id, GTK_STOCK_MEDIA_PREVIOUS) || !strcmp (
id, GTK_STOCK_MEDIA_REWIND))
681 _id = GTK_STOCK_GO_BACK;
682 else if (!strcmp (
id, GTK_STOCK_MEDIA_RECORD))
683 _id = GTK_STOCK_SAVE;
684 else if (!strcmp (
id, GTK_STOCK_CLEAR))
685 _id = GTK_STOCK_DELETE;
686 else if (!strcmp (
id, GTK_STOCK_QUIT))
687 _id = GTK_STOCK_APPLY;
688 else if (!strcmp (
id, GTK_STOCK_JUMP_TO))
690 else if (!strncmp (
id,
"gtk-dialog-", 11))
694 stockMap[cutUnderline (item.label)] = _id;
702 for (
unsigned int j = 0; j < 2; j++)
703 for (
unsigned int i = 0; i < stock_map_length; i++)
704 stockMap [stock_map[i].english+j] = stock_map[i].stock;
707 std::string
id = cutUnderline (label);
708 stripStart (
id,
' ');
712 std::map <std::string, std::string>::const_iterator it;
713 it = stockMap.find (
id);
714 if (it != stockMap.end())
715 return it->second.c_str();
719 const char *YGUtils::setStockIcon (GtkWidget *button,
const std::string &label,
720 const char *fallbackIcon)
722 const char *icon = mapStockIcon (label);
723 GtkStyleContext *ctx = gtk_widget_get_style_context(button);
725 if (!icon && label.size() < 22)
728 if (gtk_style_context_lookup_icon_set (ctx, icon)) {
730 GtkWidget *image = gtk_image_new_from_stock (icon, GTK_ICON_SIZE_BUTTON);
731 gtk_button_set_image (GTK_BUTTON (button), image);
735 GtkWidget *image = gtk_button_get_image (GTK_BUTTON (button));
737 gtk_widget_hide (image);
742 void YGUtils::shrinkWidget (GtkWidget *widget)
744 static bool first_time =
true;
745 GtkCssProvider *provider;
748 provider = gtk_css_provider_new ();
749 gtk_css_provider_load_from_data (provider,
750 "style \"small-widget-style\"\n"
752 " GtkWidget::focus-padding = 0\n"
753 " GtkWidget::focus-line-width = 0\n"
757 "widget \"*.small-widget\" style \"small-widget-style\"", -1, NULL);
758 gtk_style_context_add_provider (gtk_widget_get_style_context (widget),
759 GTK_STYLE_PROVIDER (provider),
760 GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
761 g_object_unref (provider);
762 gtk_widget_set_name (widget,
"small-widget");
772 ygutils_headerize_help (
const char *help_text, gboolean *cut)
774 char *text = ygutils_convert_to_xhtml (help_text);
776 GString *str = g_string_new (
"");
778 gboolean copy_word = FALSE;
779 for (i = 0; text[i]; i++) {
780 if (text[i] ==
'<') {
786 if (!strncasecmp (text+a,
"<h", 2) || !strncasecmp (text+a,
"<big>", 5) ||
787 (!str->len && !strncasecmp (text+a,
"<b>", 3))) {
788 for (i++; text[i]; i++) {
791 if (text[i] ==
'>') {
792 if (!strncasecmp (text+a,
"</h", 3) || !strncasecmp (text+a,
"</big>", 6) ||
793 !strncasecmp (text+a,
"</b>", 4))
799 else if (g_ascii_isspace (text[i])) {
801 g_string_append_c (str,
' ');
806 g_string_append_c (str, text[i]);
807 if (text[i] ==
'.') {
808 if (g_ascii_isspace (text[i+1]) || text[i+1] ==
'<') {
816 gboolean markup = FALSE;
817 for (; text[i]; i++) {
825 else if (!g_ascii_isspace (text[i])) {
832 return g_string_free (str, FALSE);
835 const char *ygutils_mapStockIcon (
const char *label)
836 {
return YGUtils::mapStockIcon (label); }
838 const char *ygutils_setStockIcon (GtkWidget *button,
const char *label,
const char *fallback)
839 {
return YGUtils::setStockIcon (button, label, fallback); }
845 __LEFT_PTR_WATCH = None
846 def set_busy_cursor (window):
847 global __LEFT_PTR_WATCH
848 if __LEFT_PTR_WATCH is None:
849 os.environ[
'XCURSOR_DISCOVER'] =
'1' #Turn on logging in Xlib
850 # Busy cursor code from Padraig Brady <P@draigBrady.com>
851 # cursor_data hash is 08e8e1c95fe2fc01f976f1e063a24ccd
853 \x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\
854 \x0c\x00\x00\x00\x1c\x00\x00\x00\x3c\x00\x00\x00\
855 \x7c\x00\x00\x00\xfc\x00\x00\x00\xfc\x01\x00\x00\
856 \xfc\x3b\x00\x00\x7c\x38\x00\x00\x6c\x54\x00\x00\
857 \xc4\xdc\x00\x00\xc0\x44\x00\x00\x80\x39\x00\x00\
858 \x80\x39\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
859 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
860 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
861 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
862 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
863 \x00\x00\x00\x00\x00\x00\x00\x00"
866 pix = gtk.gdk.bitmap_create_from_data(None, cursor_data, 32, 32)
867 color = gtk.gdk.Color()
868 __LEFT_PTR_WATCH = gtk.gdk.Cursor(pix, pix, color, color, 2, 2)
871 # default
"WATCH" cursor
872 __LEFT_PTR_WATCH = gtk.gdk.Cursor(gtk.gdk.WATCH)
873 window.set_cursor (__LEFT_PTR_WATCH)
877 gboolean YGUtils::empty_row_is_separator_cb (
878 GtkTreeModel *model, GtkTreeIter *iter, gpointer _text_col)
880 int text_col = GPOINTER_TO_INT (_text_col);
882 gtk_tree_model_get (model, iter, text_col, &str, -1);
883 bool ret = !str || !(*str);