gboolean gui_editor_is_marked (GUIEditor * self, gint ln) { GtkTextIter line_start, line_end; GSList *list_iter; /* get line bounds */ gtk_text_buffer_get_iter_at_line (GTK_TEXT_BUFFER (self->buffer), &line_start, ln); line_end = line_start; gtk_text_iter_forward_to_line_end (&line_end); /* get the markers already in the line */ list_iter = gtk_source_buffer_get_source_marks_at_iter (self->buffer, &line_start, NULL); /* search for the breakpoint marker */ while (list_iter != NULL) { GtkSourceMark *tmp = list_iter->data; const gchar *tmp_type = gtk_source_mark_get_category (tmp); if (tmp_type && !strcmp (tmp_type, MARKER_BREAKPOINT)) { return TRUE; } list_iter = g_slist_next (list_iter); } return FALSE; }
static gint sort_marks_by_priority (gconstpointer m1, gconstpointer m2, gpointer data) { GtkSourceMark *mark1 = GTK_SOURCE_MARK (m1); GtkSourceMark *mark2 = GTK_SOURCE_MARK (m2); GtkSourceView *view = GTK_SOURCE_VIEW (data); GtkTextIter iter1, iter2; gint line1; gint line2; gtk_text_buffer_get_iter_at_mark (gtk_text_mark_get_buffer (GTK_TEXT_MARK (mark1)), &iter1, GTK_TEXT_MARK (mark1)); gtk_text_buffer_get_iter_at_mark (gtk_text_mark_get_buffer (GTK_TEXT_MARK (mark2)), &iter2, GTK_TEXT_MARK (mark2)); line1 = gtk_text_iter_get_line (&iter1); line2 = gtk_text_iter_get_line (&iter2); if (line1 == line2) { gint priority1 = -1; gint priority2 = -1; gtk_source_view_get_mark_attributes (view, gtk_source_mark_get_category (mark1), &priority1); gtk_source_view_get_mark_attributes (view, gtk_source_mark_get_category (mark2), &priority2); return priority1 - priority2; } else { return line2 - line1; } }
static void gtk_source_mark_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { GtkSourceMark *mark; g_return_if_fail (GTK_IS_SOURCE_MARK (object)); mark = GTK_SOURCE_MARK (object); switch (prop_id) { case PROP_CATEGORY: g_value_set_string (value, gtk_source_mark_get_category (mark)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } }
static GdkPixbuf * composite_marks (GtkSourceView *view, GSList *marks, gint size) { GdkPixbuf *composite; gint mark_width; gint mark_height; /* Draw the mark with higher priority */ marks = g_slist_sort_with_data (marks, sort_marks_by_priority, view); composite = NULL; mark_width = 0; mark_height = 0; /* composite all the pixbufs for the marks present at the line */ do { GtkSourceMark *mark; GtkSourceMarkAttributes *attrs; const GdkPixbuf *pixbuf; mark = marks->data; attrs = gtk_source_view_get_mark_attributes (view, gtk_source_mark_get_category (mark), NULL); if (attrs == NULL) { continue; } pixbuf = gtk_source_mark_attributes_render_icon (attrs, GTK_WIDGET (view), size); if (pixbuf != NULL) { if (composite == NULL) { composite = gdk_pixbuf_copy (pixbuf); mark_width = gdk_pixbuf_get_width (composite); mark_height = gdk_pixbuf_get_height (composite); } else { gint pixbuf_w; gint pixbuf_h; pixbuf_w = gdk_pixbuf_get_width (pixbuf); pixbuf_h = gdk_pixbuf_get_height (pixbuf); gdk_pixbuf_composite (pixbuf, composite, 0, 0, mark_width, mark_height, 0, 0, (gdouble) pixbuf_w / mark_width, (gdouble) pixbuf_h / mark_height, GDK_INTERP_BILINEAR, COMPOSITE_ALPHA); } } marks = g_slist_next (marks); } while (marks); return composite; }
static gboolean set_tooltip_widget_from_marks (GtkSourceView *view, GtkTooltip *tooltip, GSList *marks) { GtkGrid *grid = NULL; gint row_num = 0; gint icon_size; gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, NULL, &icon_size); for (; marks; marks = g_slist_next (marks)) { const gchar *category; GtkSourceMark *mark; GtkSourceMarkAttributes *attrs; gchar *text; gboolean ismarkup = FALSE; GtkWidget *label; const GdkPixbuf *pixbuf; mark = marks->data; category = gtk_source_mark_get_category (mark); attrs = gtk_source_view_get_mark_attributes (view, category, NULL); if (attrs == NULL) { continue; } text = gtk_source_mark_attributes_get_tooltip_markup (attrs, mark); if (text == NULL) { text = gtk_source_mark_attributes_get_tooltip_text (attrs, mark); } else { ismarkup = TRUE; } if (text == NULL) { continue; } if (grid == NULL) { grid = GTK_GRID (gtk_grid_new ()); gtk_grid_set_column_spacing (grid, 4); gtk_widget_show (GTK_WIDGET (grid)); } label = gtk_label_new (NULL); if (ismarkup) { gtk_label_set_markup (GTK_LABEL (label), text); } else { gtk_label_set_text (GTK_LABEL (label), text); } gtk_widget_set_halign (label, GTK_ALIGN_START); gtk_widget_set_valign (label, GTK_ALIGN_START); gtk_widget_show (label); pixbuf = gtk_source_mark_attributes_render_icon (attrs, GTK_WIDGET (view), icon_size); if (pixbuf == NULL) { gtk_grid_attach (grid, label, 0, row_num, 2, 1); } else { GtkWidget *image; GdkPixbuf *copy; /* FIXME why a copy is needed? */ copy = gdk_pixbuf_copy (pixbuf); image = gtk_image_new_from_pixbuf (copy); g_object_unref (copy); gtk_widget_set_halign (image, GTK_ALIGN_START); gtk_widget_set_valign (image, GTK_ALIGN_START); gtk_widget_show (image); gtk_grid_attach (grid, image, 0, row_num, 1, 1); gtk_grid_attach (grid, label, 1, row_num, 1, 1); } row_num++; if (marks->next != NULL) { GtkWidget *separator; separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL); gtk_widget_show (separator); gtk_grid_attach (grid, separator, 0, row_num, 2, 1); row_num++; } g_free (text); } if (grid == NULL) { return FALSE; } gtk_tooltip_set_custom (tooltip, GTK_WIDGET (grid)); return TRUE; }
static gboolean set_tooltip_widget_from_marks (GtkSourceView *view, GtkTooltip *tooltip, GSList *marks) { GtkWidget *vbox = NULL; for (; marks; marks = g_slist_next (marks)) { const gchar *category; GtkSourceMark *mark; GtkSourceMarkAttributes *attrs; gchar *text; gboolean ismarkup = FALSE; GtkWidget *label; GtkWidget *hbox; const GdkPixbuf *pixbuf; gint size; mark = marks->data; category = gtk_source_mark_get_category (mark); attrs = gtk_source_view_get_mark_attributes (view, category, NULL); if (attrs == NULL) { continue; } text = gtk_source_mark_attributes_get_tooltip_markup (attrs, mark); if (text == NULL) { text = gtk_source_mark_attributes_get_tooltip_text (attrs, mark); } else { ismarkup = TRUE; } if (text == NULL) { continue; } if (vbox == NULL) { vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); gtk_widget_show (vbox); } hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4); gtk_widget_show (hbox); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); label = gtk_label_new (NULL); if (ismarkup) { gtk_label_set_markup (GTK_LABEL (label), text); } else { gtk_label_set_text (GTK_LABEL (label), text); } gtk_misc_set_alignment (GTK_MISC (label), 0, 0); gtk_widget_show (label); gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, NULL, &size); pixbuf = gtk_source_mark_attributes_render_icon (attrs, GTK_WIDGET (view), size); if (pixbuf != NULL) { GtkWidget *image; PangoLayoutLine *line; PangoRectangle rect; GtkWidget *align; GdkPixbuf *copy; align = gtk_alignment_new (0, 0, 0, 0); gtk_widget_show (align); copy = gdk_pixbuf_copy (pixbuf); image = gtk_image_new_from_pixbuf (copy); g_object_unref (copy); gtk_misc_set_alignment (GTK_MISC (image), 0, 0); gtk_widget_show (image); /* Measure up to align exact */ line = pango_layout_get_line (gtk_label_get_layout (GTK_LABEL (label)), 0); pango_layout_line_get_pixel_extents (line, NULL, &rect); gtk_alignment_set_padding (GTK_ALIGNMENT (align), (rect.height > size ? rect.height - size : size - rect.height) - 1, 0, 0, 0); if (rect.height > size) { gtk_container_add (GTK_CONTAINER (align), image); image = align; } else if (size > rect.height) { gtk_container_add (GTK_CONTAINER (align), label); label = align; } else { gtk_widget_destroy (align); } gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0); } gtk_box_pack_end (GTK_BOX (hbox), label, TRUE, TRUE, 0); if (g_slist_length (marks) != 1) { GtkWidget *separator; separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL); gtk_widget_show (separator); gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, FALSE, 0); } g_free (text); } if (vbox == NULL) { return FALSE; } gtk_tooltip_set_custom (tooltip, vbox); return TRUE; }