[gnome-keyring] gcr: Fix up GcrDisplayView bugs and look
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-keyring] gcr: Fix up GcrDisplayView bugs and look
- Date: Tue, 30 Aug 2011 09:27:02 +0000 (UTC)
commit 8a64c160a7def6363fef332324b6c5a2e28f9e63
Author: Stef Walter <stefw collabora co uk>
Date: Mon Aug 22 11:05:34 2011 +0200
gcr: Fix up GcrDisplayView bugs and look
* Separators between items.
* Clicking details doesn't remove items when more than one
is displayed.
* Better spacing.
gcr/gcr-certificate-renderer.c | 7 +-
gcr/gcr-display-view.c | 191 ++++++++++++++++++++++++++++++++--------
gcr/gcr-display-view.h | 5 +-
gcr/gcr-key-renderer.c | 9 ++-
4 files changed, 171 insertions(+), 41 deletions(-)
---
diff --git a/gcr/gcr-certificate-renderer.c b/gcr/gcr-certificate-renderer.c
index 558f5ce..5f53cb6 100644
--- a/gcr/gcr-certificate-renderer.c
+++ b/gcr/gcr-certificate-renderer.c
@@ -589,12 +589,14 @@ gcr_certificate_renderer_render (GcrRenderer *renderer, GcrViewer *viewer)
return;
}
- _gcr_display_view_clear (view, renderer);
+ _gcr_display_view_begin (view, renderer);
cert = GCR_CERTIFICATE (self);
data = gcr_certificate_get_der_data (cert, &n_data);
- if (!data)
+ if (!data) {
+ _gcr_display_view_end (view, renderer);
return;
+ }
icon = gcr_certificate_get_icon (cert);
_gcr_display_view_set_icon (view, GCR_RENDERER (self), icon);
@@ -724,6 +726,7 @@ gcr_certificate_renderer_render (GcrRenderer *renderer, GcrViewer *viewer)
}
egg_asn1x_destroy (asn);
+ _gcr_display_view_end (view, renderer);
}
static void
diff --git a/gcr/gcr-display-view.c b/gcr/gcr-display-view.c
index 8dd702a..b6cec63 100644
--- a/gcr/gcr-display-view.c
+++ b/gcr/gcr-display-view.c
@@ -64,6 +64,8 @@ struct _GcrDisplayViewPrivate {
GtkTextTag *heading_tag;
GtkTextTag *monospace_tag;
GcrDisplayItem *current_item;
+ gint text_height;
+ GdkCursor *cursor;
gboolean have_measurements;
gint minimal_width;
@@ -135,6 +137,23 @@ ensure_measurements (GcrDisplayView *self)
}
static void
+ensure_text_height (GcrDisplayView *self)
+{
+ PangoRectangle extents;
+ PangoLayout *layout;
+
+ if (self->pv->text_height > 0)
+ return;
+
+ layout = gtk_widget_create_pango_layout (GTK_WIDGET (self), "Wp");
+ pango_layout_get_extents (layout, NULL, &extents);
+ pango_extents_to_pixels (&extents, NULL);
+ g_object_unref (layout);
+
+ self->pv->text_height = extents.height;
+}
+
+static void
recalculate_and_resize (GcrDisplayView *self)
{
self->pv->have_measurements = FALSE;
@@ -158,7 +177,6 @@ create_tag_table (GcrDisplayView *self)
"name", "title",
"scale", PANGO_SCALE_LARGE,
"right-margin", (ICON_MARGIN * 2) + width,
- "pixels-above-lines", 9,
"pixels-below-lines", 6,
"weight", PANGO_WEIGHT_BOLD,
NULL);
@@ -221,7 +239,10 @@ style_display_item (GtkWidget *widget, GcrDisplayItem *item)
gtk_style_context_restore (style);
- gtk_widget_override_background_color (item->details_widget, GTK_STATE_NORMAL, &color);
+ color.red = 255;
+ color.green = 0;
+ color.blue = 0;
+ gtk_widget_override_background_color (item->details_widget, GTK_STATE_FLAG_NORMAL, &color);
}
static GcrDisplayItem*
@@ -255,13 +276,20 @@ create_display_item (GcrDisplayView *self, GcrRenderer *renderer)
item->details_tag = g_object_new (GTK_TYPE_TEXT_TAG, NULL);
gtk_text_tag_table_add (tags, item->details_tag);
- /* The mark that determines the beginning of this item, with left gravity. */
+ /*
+ * Add two zero width spaces that delimit this from later items. The
+ * item will live between the two zero width spaces.
+ */
gtk_text_buffer_get_end_iter (self->pv->buffer, &iter);
+ gtk_text_buffer_insert (self->pv->buffer, &iter, "\n\n", -1);
+ if (!gtk_text_iter_backward_char (&iter))
+ g_assert_not_reached ();
+
+ /* The mark that determines the beginning of this item, with left gravity. */
item->beginning = gtk_text_buffer_create_mark (self->pv->buffer, NULL, &iter, TRUE);
g_object_ref (item->beginning);
/* The mark that determines the end of this item, with right gravity. */
- gtk_text_buffer_get_end_iter (self->pv->buffer, &iter);
item->ending = gtk_text_buffer_create_mark (self->pv->buffer, NULL, &iter, FALSE);
g_object_ref (item->ending);
@@ -280,6 +308,7 @@ create_display_item (GcrDisplayView *self, GcrRenderer *renderer)
gtk_widget_show_all (alignment);
item->details_widget = gtk_event_box_new ();
+ gtk_event_box_set_visible_window (GTK_EVENT_BOX (item->details_widget), FALSE);
gtk_container_add (GTK_CONTAINER (item->details_widget), alignment);
g_signal_connect (item->details_widget, "realize", G_CALLBACK (on_expander_realize), NULL);
g_object_ref (item->details_widget);
@@ -370,45 +399,103 @@ on_renderer_data_changed (GcrRenderer *renderer, GcrViewer *self)
}
static void
-paint_widget_icons (GcrDisplayView *self, cairo_t *cr)
+paint_item_icon (GcrDisplayView *self,
+ GcrDisplayItem *item,
+ GdkRectangle *visible,
+ cairo_t *cr)
{
- GHashTableIter hit;
- GtkTextView *view;
- GdkRectangle visible;
- GdkRectangle location;
- GcrDisplayItem *item;
- gpointer value;
GtkTextIter iter;
+ GdkRectangle location;
+ GtkTextView *view;
+
+ if (item->pixbuf == NULL)
+ return;
view = GTK_TEXT_VIEW (self);
- gtk_text_view_get_visible_rect (view, &visible);
+ gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &iter, item->beginning);
+ gtk_text_view_get_iter_location (view, &iter, &location);
- g_hash_table_iter_init (&hit, self->pv->items);
- while (g_hash_table_iter_next (&hit, NULL, &value)) {
+ location.height = gdk_pixbuf_get_height (item->pixbuf);
+ location.width = gdk_pixbuf_get_width (item->pixbuf);
+ location.x = visible->width - location.width - ICON_MARGIN;
- item = value;
- if (item->pixbuf == NULL)
- continue;
+ if (!gdk_rectangle_intersect (visible, &location, NULL))
+ return;
- gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &iter, item->beginning);
- gtk_text_view_get_iter_location (view, &iter, &location);
+ gtk_text_view_buffer_to_window_coords (view, GTK_TEXT_WINDOW_TEXT,
+ location.x, location.y,
+ &location.x, &location.y);
- location.height = gdk_pixbuf_get_height (item->pixbuf);
- location.width = gdk_pixbuf_get_width (item->pixbuf);
- location.x = visible.width - location.width - ICON_MARGIN;
+ cairo_save (cr);
+ gdk_cairo_set_source_pixbuf (cr, item->pixbuf, location.x, location.y);
+ cairo_rectangle (cr, location.x, location.y, location.width, location.height);
+ cairo_fill (cr);
+ cairo_restore (cr);
+}
- if (!gdk_rectangle_intersect (&visible, &location, NULL))
- continue;
+static void
+paint_item_border (GcrDisplayView *self,
+ GcrDisplayItem *item,
+ GtkStyleContext *context,
+ GdkRectangle *visible,
+ gint index,
+ cairo_t *cr)
+{
+ GdkRGBA color;
+ GtkTextView *view;
+ GtkTextIter iter;
+ GdkRectangle location;
- gtk_text_view_buffer_to_window_coords (view, GTK_TEXT_WINDOW_TEXT,
- location.x, location.y,
- &location.x, &location.y);
+ if (index == 0)
+ return;
- cairo_save (cr);
- gdk_cairo_set_source_pixbuf (cr, item->pixbuf, location.x, location.y);
- cairo_rectangle (cr, location.x, location.y, location.width, location.height);
- cairo_fill (cr);
- cairo_restore (cr);
+ ensure_text_height (self);
+
+ gtk_style_context_get_background_color (context,
+ GTK_STATE_FLAG_SELECTED | GTK_STATE_FLAG_FOCUSED,
+ &color);
+
+ view = GTK_TEXT_VIEW (self);
+ gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &iter, item->beginning);
+ gtk_text_view_get_iter_location (view, &iter, &location);
+
+ location.height = 2;
+ location.width = visible->width - (NORMAL_MARGIN * 2);
+ location.x = NORMAL_MARGIN;
+ location.y -= self->pv->text_height / 2;
+
+ if (!gdk_rectangle_intersect (visible, &location, NULL))
+ return;
+
+ gtk_text_view_buffer_to_window_coords (view, GTK_TEXT_WINDOW_TEXT,
+ location.x, location.y,
+ &location.x, &location.y);
+
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, color.red, color.green, color.blue);
+ cairo_set_line_width (cr, 0.5);
+ cairo_move_to (cr, location.x, location.y);
+ cairo_line_to (cr, location.x + location.width, location.y);
+ cairo_stroke (cr);
+ cairo_restore (cr);
+}
+
+static void
+paint_extras (GcrDisplayView *self, cairo_t *cr)
+{
+ GdkRectangle visible;
+ GcrDisplayItem *item;
+ GtkStyleContext *context;
+ guint i;
+
+ gtk_text_view_get_visible_rect (GTK_TEXT_VIEW (self), &visible);
+ context = gtk_widget_get_style_context (GTK_WIDGET (self));
+
+ for (i = 0; i < self->pv->renderers->len; i++) {
+ item = g_hash_table_lookup (self->pv->items, self->pv->renderers->pdata[i]);
+ g_assert (item != NULL);
+ paint_item_icon (self, item, &visible, cr);
+ paint_item_border (self, item, context, &visible, i, cr);
}
}
@@ -510,6 +597,8 @@ _gcr_display_view_finalize (GObject *obj)
g_object_unref (self->pv->title_tag);
self->pv->title_tag = NULL;
+ g_clear_object (&self->pv->cursor);
+
G_OBJECT_CLASS (_gcr_display_view_parent_class)->finalize (obj);
}
@@ -518,6 +607,7 @@ _gcr_display_view_realize (GtkWidget *widget)
{
GcrDisplayView *self = GCR_DISPLAY_VIEW (widget);
GHashTableIter iter;
+ GdkDisplay *display;
gpointer value;
if (GTK_WIDGET_CLASS (_gcr_display_view_parent_class)->realize)
@@ -527,6 +617,14 @@ _gcr_display_view_realize (GtkWidget *widget)
g_hash_table_iter_init (&iter, self->pv->items);
while (g_hash_table_iter_next (&iter, NULL, &value))
style_display_item (widget, value);
+
+ if (!self->pv->cursor) {
+ display = gtk_widget_get_display (GTK_WIDGET (self));
+ self->pv->cursor = gdk_cursor_new_for_display (display, GDK_ARROW);
+ }
+
+ gdk_window_set_cursor (gtk_text_view_get_window (GTK_TEXT_VIEW (self), GTK_TEXT_WINDOW_WIDGET),
+ self->pv->cursor);
}
static gboolean
@@ -567,7 +665,7 @@ _gcr_display_view_draw (GtkWidget *widget, cairo_t *cr)
window = gtk_text_view_get_window (GTK_TEXT_VIEW (widget), GTK_TEXT_WINDOW_TEXT);
if (gtk_cairo_should_draw_window (cr, window))
- paint_widget_icons (GCR_DISPLAY_VIEW (widget), cr);
+ paint_extras (GCR_DISPLAY_VIEW (widget), cr);
return handled;
}
@@ -700,7 +798,8 @@ _gcr_display_view_new (void)
}
void
-_gcr_display_view_clear (GcrDisplayView *self, GcrRenderer *renderer)
+_gcr_display_view_begin (GcrDisplayView *self,
+ GcrRenderer *renderer)
{
GtkTextIter start, iter;
GcrDisplayItem *item;
@@ -715,15 +814,32 @@ _gcr_display_view_clear (GcrDisplayView *self, GcrRenderer *renderer)
gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &iter, item->ending);
gtk_text_buffer_delete (self->pv->buffer, &start, &iter);
- g_return_if_fail (!gtk_text_mark_get_deleted (item->beginning));
- g_return_if_fail (!gtk_text_mark_get_deleted (item->ending));
-
item->extra_tag = NULL;
item->field_width = 0;
item->details = FALSE;
}
void
+_gcr_display_view_end (GcrDisplayView *self,
+ GcrRenderer *renderer)
+{
+ GtkTextIter start, iter;
+ GcrDisplayItem *item;
+
+ g_return_if_fail (GCR_IS_DISPLAY_VIEW (self));
+ item = lookup_display_item (self, renderer);
+ g_return_if_fail (item);
+
+ gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &start, item->beginning);
+ gtk_text_buffer_get_iter_at_mark (self->pv->buffer, &iter, item->ending);
+
+#if 0
+ if (gtk_text_iter_compare (&start, &iter) != 0)
+ gtk_text_buffer_insert (self->pv->buffer, &iter, "\n", 1);
+#endif
+}
+
+void
_gcr_display_view_start_details (GcrDisplayView *self, GcrRenderer *renderer)
{
GtkTextChildAnchor *anchor;
@@ -809,6 +925,9 @@ _gcr_display_view_append_value (GcrDisplayView *self, GcrRenderer *renderer, con
pango_extents_to_pixels (&extents, NULL);
g_object_unref (layout);
+ /* An estimate of the text height */
+ self->pv->text_height = extents.height;
+
/* Make the tab wide enough to accomodate */
if (extents.width > item->field_width) {
item->field_width = extents.width + COLUMN_MARGIN;
diff --git a/gcr/gcr-display-view.h b/gcr/gcr-display-view.h
index 5f0f2ee..f697e59 100644
--- a/gcr/gcr-display-view.h
+++ b/gcr/gcr-display-view.h
@@ -55,7 +55,10 @@ GType _gcr_display_view_get_type (void);
GcrDisplayView* _gcr_display_view_new (void);
-void _gcr_display_view_clear (GcrDisplayView *self,
+void _gcr_display_view_begin (GcrDisplayView *self,
+ GcrRenderer *renderer);
+
+void _gcr_display_view_end (GcrDisplayView *self,
GcrRenderer *renderer);
void _gcr_display_view_append_value (GcrDisplayView *self,
diff --git a/gcr/gcr-key-renderer.c b/gcr/gcr-key-renderer.c
index 1b7677d..242d842 100644
--- a/gcr/gcr-key-renderer.c
+++ b/gcr/gcr-key-renderer.c
@@ -258,14 +258,17 @@ gcr_key_renderer_real_render (GcrRenderer *renderer, GcrViewer *viewer)
return;
}
- _gcr_display_view_clear (view, renderer);
+ _gcr_display_view_begin (view, renderer);
- if (!self->pv->attributes)
+ if (!self->pv->attributes) {
+ _gcr_display_view_end (view, renderer);
return;
+ }
if (!gck_attributes_find_ulong (self->pv->attributes, CKA_CLASS, &klass) ||
!gck_attributes_find_ulong (self->pv->attributes, CKA_KEY_TYPE, &key_type)) {
g_warning ("private key does not have the CKA_CLASS and CKA_KEY_TYPE attributes");
+ _gcr_display_view_end (view, renderer);
return;
}
@@ -334,6 +337,8 @@ gcr_key_renderer_real_render (GcrRenderer *renderer, GcrViewer *viewer)
_gcr_display_view_append_hex (view, renderer, _("SHA256"), fingerprint, n_fingerprint);
g_free (fingerprint);
}
+
+ _gcr_display_view_end (view, renderer);
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]