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 PangoFontMetrics *metrics = pango_context_get_metrics (context,
466 gtk_style_context_get_font(style_ctx, GTK_STATE_FLAG_NORMAL), NULL);
468 int width = pango_font_metrics_get_approximate_char_width (metrics);
469 pango_font_metrics_unref (metrics);
471 return PANGO_PIXELS (width) * chars_nb;
474 int YGUtils::getCharsHeight (GtkWidget *widget,
int chars_nb)
476 GtkStyleContext *style_ctx = gtk_widget_get_style_context(widget);
477 PangoContext *context = gtk_widget_get_pango_context (widget);
478 PangoFontMetrics *metrics = pango_context_get_metrics (context,
479 gtk_style_context_get_font(style_ctx, GTK_STATE_FLAG_NORMAL), NULL);
481 int height = pango_font_metrics_get_ascent (metrics) +
482 pango_font_metrics_get_descent (metrics);
483 pango_font_metrics_unref (metrics);
485 return PANGO_PIXELS (height) * chars_nb;
488 void YGUtils::setWidgetFont (GtkWidget *widget, PangoStyle style, PangoWeight weight,
491 GtkStyleContext *style_ctx = gtk_widget_get_style_context(widget);
492 const PangoFontDescription *font_desc = gtk_style_context_get_font(style_ctx, GTK_STATE_FLAG_NORMAL);
494 int size = pango_font_description_get_size (font_desc);
495 PangoFontDescription* font = pango_font_description_new();
496 pango_font_description_set_weight (font, weight);
497 pango_font_description_set_size (font, (
int)(size * scale));
498 pango_font_description_set_style (font, style);
499 gtk_widget_override_font (widget, font);
500 pango_font_description_free (font);
503 void ygutils_setWidgetFont (GtkWidget *widget, PangoStyle style, PangoWeight weight,
double scale)
504 { YGUtils::setWidgetFont (widget, style, weight, scale); }
506 static void paned_allocate_cb (GtkWidget *paned, GtkAllocation *alloc, gpointer _rel)
508 if (!g_object_get_data (G_OBJECT (paned),
"init")) {
509 gdouble rel = GPOINTER_TO_INT (_rel) / 100.;
512 gtk_widget_get_allocation(paned, &alloc);
514 if (gtk_orientable_get_orientation (GTK_ORIENTABLE (paned)) == GTK_ORIENTATION_HORIZONTAL)
515 parent_size = alloc.width;
517 parent_size = alloc.height;
518 int pos = parent_size * rel;
519 gtk_paned_set_position (GTK_PANED (paned), pos);
520 g_object_set_data (G_OBJECT (paned),
"init", GINT_TO_POINTER (1));
524 void YGUtils::setPaneRelPosition (GtkWidget *paned, gdouble rel)
526 gint _rel = rel * 100;
527 g_signal_connect_after (G_OBJECT (paned),
"size-allocate",
528 G_CALLBACK (paned_allocate_cb), GINT_TO_POINTER (_rel));
531 void ygutils_setPaneRelPosition (GtkWidget *paned, gdouble rel)
532 { YGUtils::setPaneRelPosition (paned, rel); }
534 GdkPixbuf *YGUtils::loadPixbuf (
const std::string &filename)
536 GdkPixbuf *pixbuf = NULL;
537 if (!filename.empty()) {
539 pixbuf = gdk_pixbuf_new_from_file (filename.c_str(), &error);
541 yuiWarning() <<
"Could not load icon: " << filename <<
"\n"
542 "Reason: " << error->message <<
"\n";
548 static inline guchar pixel_clamp (
int val)
549 {
return MAX (0, MIN (255, val)); }
550 GdkPixbuf *YGUtils::setOpacity (
const GdkPixbuf *src,
int opacity,
bool touchAlpha)
552 if (!src)
return NULL;
553 int shift = 255 - ((opacity * 255) / 100);
554 int rgb_shift = 0, alpha_shift = 0;
560 int width = gdk_pixbuf_get_width (src), height = gdk_pixbuf_get_height (src);
561 gboolean has_alpha = gdk_pixbuf_get_has_alpha (src);
563 GdkPixbuf *dest = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (src),
564 has_alpha, gdk_pixbuf_get_bits_per_sample (src), width, height);
566 guchar *src_pixels_orig = gdk_pixbuf_get_pixels (src);
567 guchar *dest_pixels_orig = gdk_pixbuf_get_pixels (dest);
569 int src_rowstride = gdk_pixbuf_get_rowstride (src);
570 int dest_rowstride = gdk_pixbuf_get_rowstride (dest);
572 for (i = 0; i < height; i++) {
573 guchar *src_pixels = src_pixels_orig + (i * src_rowstride);
574 guchar *dest_pixels = dest_pixels_orig + (i * dest_rowstride);
575 for (j = 0; j < width; j++) {
576 *(dest_pixels++) = pixel_clamp (*(src_pixels++) + rgb_shift);
577 *(dest_pixels++) = pixel_clamp (*(src_pixels++) + rgb_shift);
578 *(dest_pixels++) = pixel_clamp (*(src_pixels++) + rgb_shift);
580 *(dest_pixels++) = pixel_clamp (*(src_pixels++) - alpha_shift);
586 GdkPixbuf *YGUtils::setGray (
const GdkPixbuf *src)
588 int width = gdk_pixbuf_get_width (src), height = gdk_pixbuf_get_height (src);
589 gboolean has_alpha = gdk_pixbuf_get_has_alpha (src);
591 GdkPixbuf *dest = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (src),
592 has_alpha, gdk_pixbuf_get_bits_per_sample (src), width, height);
594 guchar *src_pixels_orig = gdk_pixbuf_get_pixels (src);
595 guchar *dest_pixels_orig = gdk_pixbuf_get_pixels (dest);
597 int src_rowstride = gdk_pixbuf_get_rowstride (src);
598 int dest_rowstride = gdk_pixbuf_get_rowstride (dest);
600 for (i = 0; i < height; i++) {
601 guchar *src_pixels = src_pixels_orig + (i * src_rowstride);
602 guchar *dest_pixels = dest_pixels_orig + (i * dest_rowstride);
603 for (j = 0; j < width; j++) {
604 int clr = (src_pixels[0] + src_pixels[1] + src_pixels[2]) / 3;
605 *(dest_pixels++) = clr;
606 *(dest_pixels++) = clr;
607 *(dest_pixels++) = clr;
610 *(dest_pixels++) = *(src_pixels++);
616 GdkPixbuf *ygutils_setOpacity (
const GdkPixbuf *src,
int opacity, gboolean useAlpha)
617 {
return YGUtils::setOpacity (src, opacity, useAlpha); }
619 static std::string cutUnderline (
const std::string &str)
621 std::string ret (str);
622 std::string::size_type i = 0;
623 if ((i = ret.find (
'_', i)) != std::string::npos)
628 static void stripStart (std::string &str,
char ch)
630 while (!str.empty() && str[0] == ch)
633 static void stripEnd (std::string &str,
char ch)
635 while (!str.empty() && str[str.size()-1] == ch)
636 str.erase (str.size()-1, 1);
640 const char *english, *locale, *stock;
642 static const StockMap stock_map[] = {
643 {
"Apply", _(
"Apply"), GTK_STOCK_APPLY },
644 {
"Accept", _(
"Accept"), GTK_STOCK_APPLY },
645 {
"Install", _(
"Install"), GTK_STOCK_APPLY },
646 {
"OK", _(
"OK"), GTK_STOCK_OK },
647 {
"Cancel", _(
"Cancel"), GTK_STOCK_CANCEL },
648 {
"Abort", _(
"Abort"), GTK_STOCK_CANCEL },
649 {
"Close", _(
"Close"), GTK_STOCK_CLOSE },
650 {
"Yes", _(
"Yes"), GTK_STOCK_YES },
651 {
"No", _(
"No"), GTK_STOCK_NO },
652 {
"Add", _(
"Add"), GTK_STOCK_ADD },
653 {
"Edit", _(
"Edit"), GTK_STOCK_EDIT },
654 {
"Delete", _(
"Delete"), GTK_STOCK_DELETE },
655 {
"Up", _(
"Up"), GTK_STOCK_GO_UP },
656 {
"Down", _(
"Down"), GTK_STOCK_GO_DOWN },
657 {
"Enable", _(
"Enable"), GTK_STOCK_YES },
658 {
"Disable", _(
"Disable"), GTK_STOCK_NO },
659 {
"Exit", _(
"Exit"), GTK_STOCK_QUIT },
661 #define stock_map_length (sizeof (stock_map) / sizeof (StockMap))
663 const char *YGUtils::mapStockIcon (
const std::string &label)
665 static bool firstTime =
true;
static std::map <std::string, std::string> stockMap;
670 GSList *list = gtk_stock_list_ids();
671 for (GSList *i = list; i; i = i->next) {
672 gchar *
id = (gchar *) i->data;
674 if (gtk_stock_lookup (
id, &item)) {
675 const gchar *_id = id;
676 if (!strcmp (
id, GTK_STOCK_MEDIA_NEXT) || !strcmp (
id, GTK_STOCK_MEDIA_FORWARD))
677 _id = GTK_STOCK_GO_FORWARD;
678 else if (!strcmp (
id, GTK_STOCK_MEDIA_PREVIOUS) || !strcmp (
id, GTK_STOCK_MEDIA_REWIND))
679 _id = GTK_STOCK_GO_BACK;
680 else if (!strcmp (
id, GTK_STOCK_MEDIA_RECORD))
681 _id = GTK_STOCK_SAVE;
682 else if (!strcmp (
id, GTK_STOCK_CLEAR))
683 _id = GTK_STOCK_DELETE;
684 else if (!strcmp (
id, GTK_STOCK_QUIT))
685 _id = GTK_STOCK_APPLY;
686 else if (!strcmp (
id, GTK_STOCK_JUMP_TO))
688 else if (!strncmp (
id,
"gtk-dialog-", 11))
692 stockMap[cutUnderline (item.label)] = _id;
700 for (
unsigned int j = 0; j < 2; j++)
701 for (
unsigned int i = 0; i < stock_map_length; i++)
702 stockMap [stock_map[i].english+j] = stock_map[i].stock;
705 std::string
id = cutUnderline (label);
706 stripStart (
id,
' ');
710 std::map <std::string, std::string>::const_iterator it;
711 it = stockMap.find (
id);
712 if (it != stockMap.end())
713 return it->second.c_str();
717 const char *YGUtils::setStockIcon (GtkWidget *button,
const std::string &label,
718 const char *fallbackIcon)
720 const char *icon = mapStockIcon (label);
721 GtkStyleContext *ctx = gtk_widget_get_style_context(button);
723 if (!icon && label.size() < 22)
726 if (gtk_style_context_lookup_icon_set (ctx, icon)) {
728 GtkWidget *image = gtk_image_new_from_stock (icon, GTK_ICON_SIZE_BUTTON);
729 gtk_button_set_image (GTK_BUTTON (button), image);
733 GtkWidget *image = gtk_button_get_image (GTK_BUTTON (button));
735 gtk_widget_hide (image);
740 void YGUtils::shrinkWidget (GtkWidget *widget)
742 static bool first_time =
true;
743 GtkCssProvider *provider;
746 provider = gtk_css_provider_new ();
747 gtk_css_provider_load_from_data (provider,
748 "style \"small-widget-style\"\n"
750 " GtkWidget::focus-padding = 0\n"
751 " GtkWidget::focus-line-width = 0\n"
755 "widget \"*.small-widget\" style \"small-widget-style\"", -1, NULL);
756 gtk_style_context_add_provider (gtk_widget_get_style_context (widget),
757 GTK_STYLE_PROVIDER (provider),
758 GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
759 g_object_unref (provider);
760 gtk_widget_set_name (widget,
"small-widget");
770 ygutils_headerize_help (
const char *help_text, gboolean *cut)
772 char *text = ygutils_convert_to_xhtml (help_text);
774 GString *str = g_string_new (
"");
776 gboolean copy_word = FALSE;
777 for (i = 0; text[i]; i++) {
778 if (text[i] ==
'<') {
784 if (!strncasecmp (text+a,
"<h", 2) || !strncasecmp (text+a,
"<big>", 5) ||
785 (!str->len && !strncasecmp (text+a,
"<b>", 3))) {
786 for (i++; text[i]; i++) {
789 if (text[i] ==
'>') {
790 if (!strncasecmp (text+a,
"</h", 3) || !strncasecmp (text+a,
"</big>", 6) ||
791 !strncasecmp (text+a,
"</b>", 4))
797 else if (g_ascii_isspace (text[i])) {
799 g_string_append_c (str,
' ');
804 g_string_append_c (str, text[i]);
805 if (text[i] ==
'.') {
806 if (g_ascii_isspace (text[i+1]) || text[i+1] ==
'<') {
814 gboolean markup = FALSE;
815 for (; text[i]; i++) {
823 else if (!g_ascii_isspace (text[i])) {
830 return g_string_free (str, FALSE);
833 const char *ygutils_mapStockIcon (
const char *label)
834 {
return YGUtils::mapStockIcon (label); }
836 const char *ygutils_setStockIcon (GtkWidget *button,
const char *label,
const char *fallback)
837 {
return YGUtils::setStockIcon (button, label, fallback); }
843 __LEFT_PTR_WATCH = None
844 def set_busy_cursor (window):
845 global __LEFT_PTR_WATCH
846 if __LEFT_PTR_WATCH is None:
847 os.environ[
'XCURSOR_DISCOVER'] =
'1' #Turn on logging in Xlib
848 # Busy cursor code from Padraig Brady <P@draigBrady.com>
849 # cursor_data hash is 08e8e1c95fe2fc01f976f1e063a24ccd
851 \x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\
852 \x0c\x00\x00\x00\x1c\x00\x00\x00\x3c\x00\x00\x00\
853 \x7c\x00\x00\x00\xfc\x00\x00\x00\xfc\x01\x00\x00\
854 \xfc\x3b\x00\x00\x7c\x38\x00\x00\x6c\x54\x00\x00\
855 \xc4\xdc\x00\x00\xc0\x44\x00\x00\x80\x39\x00\x00\
856 \x80\x39\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
857 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
858 \x00\x00\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"
864 pix = gtk.gdk.bitmap_create_from_data(None, cursor_data, 32, 32)
865 color = gtk.gdk.Color()
866 __LEFT_PTR_WATCH = gtk.gdk.Cursor(pix, pix, color, color, 2, 2)
869 # default
"WATCH" cursor
870 __LEFT_PTR_WATCH = gtk.gdk.Cursor(gtk.gdk.WATCH)
871 window.set_cursor (__LEFT_PTR_WATCH)
875 gboolean YGUtils::empty_row_is_separator_cb (
876 GtkTreeModel *model, GtkTreeIter *iter, gpointer _text_col)
878 int text_col = GPOINTER_TO_INT (_text_col);
880 gtk_tree_model_get (model, iter, text_col, &str, -1);
881 bool ret = !str || !(*str);