2014-05-15 23:34:38 +00:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2014 Red Hat, Inc.
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
2014-07-12 03:14:04 +00:00
|
|
|
|
2014-05-15 23:34:38 +00:00
|
|
|
#include "resource-list.h"
|
|
|
|
|
2018-02-09 00:06:59 +00:00
|
|
|
#include "treewalk.h"
|
|
|
|
|
|
|
|
#include "gtkbutton.h"
|
2014-07-12 03:45:18 +00:00
|
|
|
#include "gtklabel.h"
|
2018-02-09 00:06:59 +00:00
|
|
|
#include "gtksearchbar.h"
|
|
|
|
#include "gtksearchentry.h"
|
2014-07-12 03:45:18 +00:00
|
|
|
#include "gtkstack.h"
|
2014-07-12 03:14:04 +00:00
|
|
|
#include "gtktextbuffer.h"
|
|
|
|
#include "gtktreeselection.h"
|
2018-02-09 00:06:59 +00:00
|
|
|
#include "gtktreestore.h"
|
2018-02-04 08:29:44 +00:00
|
|
|
#include "gtkeventcontrollerkey.h"
|
2018-02-09 00:06:59 +00:00
|
|
|
|
|
|
|
#include <glib/gi18n-lib.h>
|
2014-07-12 03:14:04 +00:00
|
|
|
|
2014-10-11 04:58:47 +00:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
PROP_0,
|
2014-10-25 01:14:16 +00:00
|
|
|
PROP_BUTTONS
|
2014-10-11 04:58:47 +00:00
|
|
|
};
|
|
|
|
|
2014-05-15 23:34:38 +00:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
COLUMN_NAME,
|
2014-07-19 05:20:28 +00:00
|
|
|
COLUMN_PATH,
|
|
|
|
COLUMN_COUNT,
|
|
|
|
COLUMN_SIZE
|
2014-05-15 23:34:38 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct _GtkInspectorResourceListPrivate
|
|
|
|
{
|
|
|
|
GtkTreeStore *model;
|
|
|
|
GtkTextBuffer *buffer;
|
|
|
|
GtkWidget *image;
|
|
|
|
GtkWidget *content;
|
2014-10-11 00:20:02 +00:00
|
|
|
GtkWidget *name_label;
|
2014-07-19 05:20:28 +00:00
|
|
|
GtkWidget *type;
|
2014-05-19 11:10:33 +00:00
|
|
|
GtkWidget *type_label;
|
|
|
|
GtkWidget *size_label;
|
|
|
|
GtkWidget *info_grid;
|
2014-10-11 00:20:02 +00:00
|
|
|
GtkWidget *stack;
|
2014-10-11 03:25:07 +00:00
|
|
|
GtkWidget *tree;
|
2014-10-25 01:14:16 +00:00
|
|
|
GtkWidget *buttons;
|
|
|
|
GtkWidget *open_details_button;
|
2014-10-11 04:58:47 +00:00
|
|
|
GtkWidget *close_details_button;
|
2014-11-08 01:38:42 +00:00
|
|
|
GtkTreeViewColumn *path_column;
|
2014-10-10 23:15:02 +00:00
|
|
|
GtkTreeViewColumn *count_column;
|
|
|
|
GtkCellRenderer *count_renderer;
|
|
|
|
GtkTreeViewColumn *size_column;
|
|
|
|
GtkCellRenderer *size_renderer;
|
2014-11-08 01:38:42 +00:00
|
|
|
GtkWidget *search_bar;
|
|
|
|
GtkWidget *search_entry;
|
|
|
|
GtkTreeWalk *walk;
|
|
|
|
gint search_length;
|
2014-05-15 23:34:38 +00:00
|
|
|
};
|
|
|
|
|
2014-10-11 04:58:47 +00:00
|
|
|
|
2014-05-15 23:34:38 +00:00
|
|
|
G_DEFINE_TYPE_WITH_PRIVATE (GtkInspectorResourceList, gtk_inspector_resource_list, GTK_TYPE_BOX)
|
|
|
|
|
|
|
|
static void
|
|
|
|
load_resources_recurse (GtkInspectorResourceList *sl,
|
|
|
|
GtkTreeIter *parent,
|
2014-07-19 05:20:28 +00:00
|
|
|
const gchar *path,
|
|
|
|
gint *count_out,
|
|
|
|
gsize *size_out)
|
2014-05-15 23:34:38 +00:00
|
|
|
{
|
|
|
|
gchar **names;
|
|
|
|
gint i;
|
|
|
|
GtkTreeIter iter;
|
2015-01-09 19:44:26 +00:00
|
|
|
guint64 stored_size;
|
2014-05-15 23:34:38 +00:00
|
|
|
|
|
|
|
names = g_resources_enumerate_children (path, 0, NULL);
|
|
|
|
for (i = 0; names[i]; i++)
|
|
|
|
{
|
|
|
|
gint len;
|
|
|
|
gchar *p;
|
|
|
|
gboolean has_slash;
|
2014-07-19 05:20:28 +00:00
|
|
|
gint count;
|
|
|
|
gsize size;
|
2014-05-15 23:34:38 +00:00
|
|
|
|
|
|
|
p = g_strconcat (path, names[i], NULL);
|
|
|
|
|
|
|
|
len = strlen (names[i]);
|
|
|
|
has_slash = names[i][len - 1] == '/';
|
|
|
|
|
|
|
|
if (has_slash)
|
|
|
|
names[i][len - 1] = '\0';
|
|
|
|
|
|
|
|
gtk_tree_store_append (sl->priv->model, &iter, parent);
|
|
|
|
gtk_tree_store_set (sl->priv->model, &iter,
|
|
|
|
COLUMN_NAME, names[i],
|
|
|
|
COLUMN_PATH, p,
|
|
|
|
-1);
|
|
|
|
|
2014-07-19 05:20:28 +00:00
|
|
|
count = 0;
|
|
|
|
size = 0;
|
|
|
|
|
2014-05-15 23:34:38 +00:00
|
|
|
if (has_slash)
|
2014-07-19 05:20:28 +00:00
|
|
|
{
|
|
|
|
load_resources_recurse (sl, &iter, p, &count, &size);
|
2014-10-10 23:15:02 +00:00
|
|
|
*count_out += count;
|
|
|
|
*size_out += size;
|
2014-07-19 05:20:28 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-10-10 23:15:02 +00:00
|
|
|
count = 0;
|
2015-07-17 19:56:34 +00:00
|
|
|
if (g_resources_get_info (p, 0, &size, NULL, NULL))
|
|
|
|
{
|
|
|
|
*count_out += 1;
|
|
|
|
*size_out += size;
|
|
|
|
}
|
2014-07-19 05:20:28 +00:00
|
|
|
}
|
|
|
|
|
2015-01-09 19:44:26 +00:00
|
|
|
stored_size = size;
|
2014-07-19 05:20:28 +00:00
|
|
|
gtk_tree_store_set (sl->priv->model, &iter,
|
|
|
|
COLUMN_COUNT, count,
|
2015-01-09 19:44:26 +00:00
|
|
|
COLUMN_SIZE, stored_size,
|
2014-07-19 05:20:28 +00:00
|
|
|
-1);
|
2014-05-15 23:34:38 +00:00
|
|
|
|
|
|
|
g_free (p);
|
|
|
|
}
|
|
|
|
g_strfreev (names);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2014-10-11 00:20:02 +00:00
|
|
|
static gboolean
|
|
|
|
populate_details (GtkInspectorResourceList *rl,
|
|
|
|
GtkTreePath *tree_path)
|
2014-05-15 23:34:38 +00:00
|
|
|
{
|
|
|
|
GtkTreeIter iter;
|
2014-10-11 00:20:02 +00:00
|
|
|
gchar *path;
|
|
|
|
gchar *name;
|
|
|
|
GBytes *bytes;
|
|
|
|
gchar *type;
|
|
|
|
gconstpointer data;
|
|
|
|
gint count;
|
|
|
|
gsize size;
|
2015-01-09 19:44:26 +00:00
|
|
|
guint64 stored_size;
|
2014-10-11 00:20:02 +00:00
|
|
|
GError *error = NULL;
|
|
|
|
gchar *markup;
|
|
|
|
|
|
|
|
|
|
|
|
gtk_tree_model_get_iter (GTK_TREE_MODEL (rl->priv->model), &iter, tree_path);
|
|
|
|
|
|
|
|
gtk_tree_model_get (GTK_TREE_MODEL (rl->priv->model), &iter,
|
|
|
|
COLUMN_PATH, &path,
|
|
|
|
COLUMN_NAME, &name,
|
|
|
|
COLUMN_COUNT, &count,
|
2015-01-09 19:44:26 +00:00
|
|
|
COLUMN_SIZE, &stored_size,
|
2014-10-11 00:20:02 +00:00
|
|
|
-1);
|
2015-01-09 19:44:26 +00:00
|
|
|
size = stored_size;
|
2014-10-11 00:20:02 +00:00
|
|
|
|
|
|
|
if (g_str_has_suffix (path, "/"))
|
|
|
|
{
|
|
|
|
g_free (path);
|
|
|
|
g_free (name);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
markup = g_strconcat ("<span face='Monospace' size='small'>", path, "</span>", NULL);
|
|
|
|
gtk_label_set_markup (GTK_LABEL (rl->priv->name_label), markup);
|
|
|
|
g_free (markup);
|
|
|
|
|
|
|
|
bytes = g_resources_lookup_data (path, 0, &error);
|
|
|
|
if (bytes == NULL)
|
2014-05-15 23:34:38 +00:00
|
|
|
{
|
2014-10-11 00:20:02 +00:00
|
|
|
gtk_text_buffer_set_text (rl->priv->buffer, error->message, -1);
|
|
|
|
g_error_free (error);
|
|
|
|
gtk_stack_set_visible_child_name (GTK_STACK (rl->priv->content), "text");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gchar *text;
|
2017-03-09 03:52:58 +00:00
|
|
|
gchar *content_image;
|
|
|
|
gchar *content_text;
|
|
|
|
|
|
|
|
content_image = g_content_type_from_mime_type ("image/*");
|
|
|
|
content_text = g_content_type_from_mime_type ("text/*");
|
2014-05-19 11:10:33 +00:00
|
|
|
|
2014-10-11 00:20:02 +00:00
|
|
|
data = g_bytes_get_data (bytes, &size);
|
|
|
|
type = g_content_type_guess (name, data, size, NULL);
|
2014-07-19 05:20:28 +00:00
|
|
|
|
2014-10-11 00:20:02 +00:00
|
|
|
text = g_content_type_get_description (type);
|
|
|
|
gtk_label_set_text (GTK_LABEL (rl->priv->type_label), text);
|
|
|
|
g_free (text);
|
2014-07-19 05:20:28 +00:00
|
|
|
|
2014-10-11 00:20:02 +00:00
|
|
|
text = g_format_size (size);
|
|
|
|
gtk_label_set_text (GTK_LABEL (rl->priv->size_label), text);
|
|
|
|
g_free (text);
|
2015-01-09 19:44:26 +00:00
|
|
|
|
2017-03-09 03:52:58 +00:00
|
|
|
if (g_content_type_is_a (type, content_text))
|
2014-10-11 00:20:02 +00:00
|
|
|
{
|
|
|
|
gtk_text_buffer_set_text (rl->priv->buffer, data, -1);
|
2014-05-15 23:34:38 +00:00
|
|
|
gtk_stack_set_visible_child_name (GTK_STACK (rl->priv->content), "text");
|
|
|
|
}
|
2017-03-09 03:52:58 +00:00
|
|
|
else if (g_content_type_is_a (type, content_image))
|
2014-05-15 23:34:38 +00:00
|
|
|
{
|
2014-10-11 00:20:02 +00:00
|
|
|
gtk_image_set_from_resource (GTK_IMAGE (rl->priv->image), path);
|
|
|
|
gtk_stack_set_visible_child_name (GTK_STACK (rl->priv->content), "image");
|
2014-05-15 23:34:38 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-10-11 00:20:02 +00:00
|
|
|
gtk_text_buffer_set_text (rl->priv->buffer, "", 0);
|
|
|
|
gtk_stack_set_visible_child_name (GTK_STACK (rl->priv->content), "text");
|
|
|
|
}
|
2014-05-19 11:10:33 +00:00
|
|
|
|
2014-10-11 00:20:02 +00:00
|
|
|
g_free (type);
|
|
|
|
g_bytes_unref (bytes);
|
2017-03-09 03:52:58 +00:00
|
|
|
|
|
|
|
g_free (content_image);
|
|
|
|
g_free (content_text);
|
2014-10-11 00:20:02 +00:00
|
|
|
}
|
2014-05-19 11:10:33 +00:00
|
|
|
|
2014-10-11 00:20:02 +00:00
|
|
|
g_free (path);
|
|
|
|
g_free (name);
|
2014-05-19 11:10:33 +00:00
|
|
|
|
2014-10-11 00:20:02 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
row_activated (GtkTreeView *treeview,
|
|
|
|
GtkTreePath *path,
|
|
|
|
GtkTreeViewColumn *column,
|
|
|
|
GtkInspectorResourceList *sl)
|
|
|
|
{
|
2014-10-25 01:14:16 +00:00
|
|
|
if (!populate_details (sl, path))
|
|
|
|
return;
|
|
|
|
|
|
|
|
gtk_stack_set_visible_child_name (GTK_STACK (sl->priv->stack), "details");
|
|
|
|
gtk_stack_set_visible_child_name (GTK_STACK (sl->priv->buttons), "details");
|
|
|
|
}
|
|
|
|
|
2014-10-25 01:52:23 +00:00
|
|
|
static gboolean
|
|
|
|
can_show_details (GtkInspectorResourceList *rl)
|
|
|
|
{
|
|
|
|
GtkTreeSelection *selection;
|
|
|
|
GtkTreeModel *model;
|
|
|
|
GtkTreeIter iter;
|
|
|
|
gchar *path;
|
|
|
|
|
|
|
|
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (rl->priv->tree));
|
|
|
|
if (!gtk_tree_selection_get_selected (selection, &model, &iter))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
gtk_tree_model_get (GTK_TREE_MODEL (rl->priv->model), &iter,
|
|
|
|
COLUMN_PATH, &path,
|
|
|
|
-1);
|
|
|
|
|
|
|
|
if (g_str_has_suffix (path, "/"))
|
|
|
|
{
|
|
|
|
g_free (path);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free (path);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
on_selection_changed (GtkTreeSelection *selection,
|
|
|
|
GtkInspectorResourceList *rl)
|
|
|
|
{
|
2014-11-08 01:38:42 +00:00
|
|
|
GtkTreeIter iter;
|
|
|
|
|
|
|
|
if (gtk_tree_selection_get_selected (selection, NULL, &iter))
|
|
|
|
gtk_tree_walk_reset (rl->priv->walk, &iter);
|
|
|
|
else
|
|
|
|
gtk_tree_walk_reset (rl->priv->walk, NULL);
|
|
|
|
|
2014-10-25 01:52:23 +00:00
|
|
|
gtk_widget_set_sensitive (rl->priv->open_details_button, can_show_details (rl));
|
|
|
|
}
|
|
|
|
|
2014-10-25 01:14:16 +00:00
|
|
|
static void
|
|
|
|
open_details (GtkWidget *button,
|
|
|
|
GtkInspectorResourceList *sl)
|
|
|
|
{
|
|
|
|
GtkTreeSelection *selection;
|
|
|
|
GtkTreeModel *model;
|
|
|
|
GtkTreeIter iter;
|
|
|
|
GtkTreePath *path;
|
|
|
|
|
|
|
|
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (sl->priv->tree));
|
|
|
|
if (!gtk_tree_selection_get_selected (selection, &model, &iter))
|
|
|
|
return;
|
|
|
|
|
|
|
|
path = gtk_tree_model_get_path (model, &iter);
|
|
|
|
if (populate_details (sl, path))
|
|
|
|
{
|
|
|
|
gtk_stack_set_visible_child_name (GTK_STACK (sl->priv->stack), "details");
|
|
|
|
gtk_stack_set_visible_child_name (GTK_STACK (sl->priv->buttons), "details");
|
|
|
|
}
|
|
|
|
|
|
|
|
gtk_tree_path_free (path);
|
2014-10-11 00:20:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
close_details (GtkWidget *button,
|
|
|
|
GtkInspectorResourceList *sl)
|
|
|
|
{
|
|
|
|
gtk_stack_set_visible_child_name (GTK_STACK (sl->priv->stack), "list");
|
2014-10-25 01:14:16 +00:00
|
|
|
gtk_stack_set_visible_child_name (GTK_STACK (sl->priv->buttons), "list");
|
2014-05-15 23:34:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
load_resources (GtkInspectorResourceList *sl)
|
|
|
|
{
|
2014-07-19 05:20:28 +00:00
|
|
|
gint count = 0;
|
|
|
|
gsize size = 0;
|
2014-05-15 23:34:38 +00:00
|
|
|
|
2014-07-19 05:20:28 +00:00
|
|
|
load_resources_recurse (sl, NULL, "/", &count, &size);
|
2014-05-15 23:34:38 +00:00
|
|
|
}
|
|
|
|
|
2014-10-10 23:15:02 +00:00
|
|
|
static void
|
|
|
|
count_data_func (GtkTreeViewColumn *col,
|
|
|
|
GtkCellRenderer *cell,
|
|
|
|
GtkTreeModel *model,
|
|
|
|
GtkTreeIter *iter,
|
|
|
|
gpointer data)
|
|
|
|
{
|
|
|
|
gint count;
|
|
|
|
gchar *text;
|
|
|
|
|
|
|
|
gtk_tree_model_get (model, iter, COLUMN_COUNT, &count, -1);
|
|
|
|
if (count > 0)
|
|
|
|
{
|
|
|
|
text = g_strdup_printf ("%d", count);
|
|
|
|
g_object_set (cell, "text", text, NULL);
|
|
|
|
g_free (text);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
g_object_set (cell, "text", "", NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
size_data_func (GtkTreeViewColumn *col,
|
|
|
|
GtkCellRenderer *cell,
|
|
|
|
GtkTreeModel *model,
|
|
|
|
GtkTreeIter *iter,
|
|
|
|
gpointer data)
|
|
|
|
{
|
2015-01-09 19:44:26 +00:00
|
|
|
gsize size;
|
|
|
|
guint64 stored_size;
|
2014-10-10 23:15:02 +00:00
|
|
|
gchar *text;
|
|
|
|
|
2015-01-09 19:44:26 +00:00
|
|
|
gtk_tree_model_get (model, iter, COLUMN_SIZE, &stored_size, -1);
|
|
|
|
size = stored_size;
|
2014-10-10 23:15:02 +00:00
|
|
|
text = g_format_size (size);
|
|
|
|
g_object_set (cell, "text", text, NULL);
|
|
|
|
g_free (text);
|
|
|
|
}
|
|
|
|
|
2014-10-11 00:20:02 +00:00
|
|
|
static void
|
|
|
|
on_map (GtkWidget *widget)
|
|
|
|
{
|
|
|
|
GtkInspectorResourceList *sl = GTK_INSPECTOR_RESOURCE_LIST (widget);
|
|
|
|
|
2014-10-11 03:25:07 +00:00
|
|
|
gtk_tree_view_expand_all (GTK_TREE_VIEW (sl->priv->tree));
|
2014-10-11 00:20:02 +00:00
|
|
|
gtk_stack_set_visible_child_name (GTK_STACK (sl->priv->stack), "list");
|
2014-11-08 05:06:54 +00:00
|
|
|
gtk_widget_set_sensitive (sl->priv->open_details_button, can_show_details (sl));
|
2014-10-11 04:58:47 +00:00
|
|
|
}
|
|
|
|
|
2014-11-08 01:38:42 +00:00
|
|
|
static void
|
|
|
|
move_search_to_row (GtkInspectorResourceList *sl,
|
|
|
|
GtkTreeIter *iter)
|
|
|
|
{
|
|
|
|
GtkTreeSelection *selection;
|
|
|
|
GtkTreePath *path;
|
|
|
|
|
|
|
|
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (sl->priv->tree));
|
|
|
|
path = gtk_tree_model_get_path (GTK_TREE_MODEL (sl->priv->model), iter);
|
|
|
|
gtk_tree_view_expand_to_path (GTK_TREE_VIEW (sl->priv->tree), path);
|
|
|
|
gtk_tree_selection_select_path (selection, path);
|
|
|
|
gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (sl->priv->tree), path, NULL, TRUE, 0.5, 0.0);
|
|
|
|
gtk_tree_path_free (path);
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
2018-02-04 08:29:44 +00:00
|
|
|
key_pressed (GtkEventController *controller,
|
|
|
|
guint keyval,
|
|
|
|
guint keycode,
|
|
|
|
GdkModifierType state,
|
|
|
|
GtkInspectorResourceList *sl)
|
2014-11-08 01:38:42 +00:00
|
|
|
{
|
2018-02-04 08:29:44 +00:00
|
|
|
if (gtk_widget_get_mapped (GTK_WIDGET (sl)))
|
2014-11-08 01:38:42 +00:00
|
|
|
{
|
|
|
|
GdkModifierType default_accel;
|
|
|
|
gboolean search_started;
|
|
|
|
|
|
|
|
search_started = gtk_search_bar_get_search_mode (GTK_SEARCH_BAR (sl->priv->search_bar));
|
|
|
|
default_accel = gtk_widget_get_modifier_mask (GTK_WIDGET (sl), GDK_MODIFIER_INTENT_PRIMARY_ACCELERATOR);
|
|
|
|
|
|
|
|
if (search_started &&
|
2017-08-25 14:57:26 +00:00
|
|
|
(keyval == GDK_KEY_Return ||
|
|
|
|
keyval == GDK_KEY_ISO_Enter ||
|
|
|
|
keyval == GDK_KEY_KP_Enter))
|
2014-11-08 01:38:42 +00:00
|
|
|
{
|
|
|
|
GtkTreeSelection *selection;
|
|
|
|
GtkTreeModel *model;
|
|
|
|
GtkTreeIter iter;
|
|
|
|
GtkTreePath *path;
|
|
|
|
|
|
|
|
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (sl->priv->tree));
|
|
|
|
if (gtk_tree_selection_get_selected (selection, &model, &iter))
|
|
|
|
{
|
|
|
|
path = gtk_tree_model_get_path (model, &iter);
|
|
|
|
gtk_tree_view_row_activated (GTK_TREE_VIEW (sl->priv->tree),
|
|
|
|
path,
|
|
|
|
sl->priv->path_column);
|
|
|
|
gtk_tree_path_free (path);
|
|
|
|
|
|
|
|
return GDK_EVENT_STOP;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return GDK_EVENT_PROPAGATE;
|
|
|
|
}
|
|
|
|
else if (search_started &&
|
2017-08-25 14:57:26 +00:00
|
|
|
(keyval == GDK_KEY_Escape))
|
2014-11-08 01:38:42 +00:00
|
|
|
{
|
|
|
|
gtk_search_bar_set_search_mode (GTK_SEARCH_BAR (sl->priv->search_bar), FALSE);
|
|
|
|
return GDK_EVENT_STOP;
|
|
|
|
}
|
|
|
|
else if (search_started &&
|
2017-08-25 14:57:26 +00:00
|
|
|
((state & (default_accel | GDK_SHIFT_MASK)) == (default_accel | GDK_SHIFT_MASK)) &&
|
|
|
|
(keyval == GDK_KEY_g || keyval == GDK_KEY_G))
|
2014-11-08 01:38:42 +00:00
|
|
|
{
|
|
|
|
GtkTreeIter iter;
|
|
|
|
if (gtk_tree_walk_next_match (sl->priv->walk, TRUE, TRUE, &iter))
|
|
|
|
move_search_to_row (sl, &iter);
|
|
|
|
else
|
|
|
|
gtk_widget_error_bell (GTK_WIDGET (sl));
|
|
|
|
|
|
|
|
return GDK_EVENT_STOP;
|
|
|
|
}
|
|
|
|
else if (search_started &&
|
2017-08-25 14:57:26 +00:00
|
|
|
((state & (default_accel | GDK_SHIFT_MASK)) == default_accel) &&
|
|
|
|
(keyval == GDK_KEY_g || keyval == GDK_KEY_G))
|
2014-11-08 01:38:42 +00:00
|
|
|
{
|
|
|
|
GtkTreeIter iter;
|
|
|
|
|
|
|
|
if (gtk_tree_walk_next_match (sl->priv->walk, TRUE, FALSE, &iter))
|
|
|
|
move_search_to_row (sl, &iter);
|
|
|
|
else
|
|
|
|
gtk_widget_error_bell (GTK_WIDGET (sl));
|
|
|
|
|
|
|
|
return GDK_EVENT_STOP;
|
|
|
|
}
|
|
|
|
}
|
2018-03-11 12:54:54 +00:00
|
|
|
|
|
|
|
return GDK_EVENT_PROPAGATE;
|
2014-11-08 01:38:42 +00:00
|
|
|
}
|
|
|
|
|
2018-05-14 17:03:17 +00:00
|
|
|
static void
|
|
|
|
destroy_controller (GtkEventController *controller)
|
|
|
|
{
|
|
|
|
gtk_widget_remove_controller (gtk_event_controller_get_widget (controller), controller);
|
|
|
|
}
|
|
|
|
|
2014-11-08 01:38:42 +00:00
|
|
|
static void
|
|
|
|
on_hierarchy_changed (GtkWidget *widget,
|
|
|
|
GtkWidget *previous_toplevel)
|
|
|
|
{
|
2018-03-11 12:54:54 +00:00
|
|
|
GtkInspectorResourceList *sl = GTK_INSPECTOR_RESOURCE_LIST (widget);
|
2018-02-04 08:29:44 +00:00
|
|
|
GtkEventController *controller;
|
|
|
|
GtkWidget *toplevel;
|
|
|
|
|
2014-11-08 01:38:42 +00:00
|
|
|
if (previous_toplevel)
|
2018-05-05 07:02:14 +00:00
|
|
|
g_object_set_data (G_OBJECT (previous_toplevel), "resource-controller", NULL);
|
2018-02-04 08:29:44 +00:00
|
|
|
|
|
|
|
toplevel = gtk_widget_get_toplevel (widget);
|
2018-05-05 07:06:22 +00:00
|
|
|
|
|
|
|
if (!GTK_IS_WINDOW (toplevel))
|
|
|
|
return;
|
|
|
|
|
2018-04-20 17:58:06 +00:00
|
|
|
controller = gtk_event_controller_key_new ();
|
2018-05-14 17:03:17 +00:00
|
|
|
g_object_set_data_full (G_OBJECT (toplevel), "resource-controller", controller, (GDestroyNotify)destroy_controller);
|
2018-02-04 08:29:44 +00:00
|
|
|
g_signal_connect (controller, "key-pressed", G_CALLBACK (key_pressed), widget);
|
2018-04-20 17:58:06 +00:00
|
|
|
gtk_widget_add_controller (toplevel, controller);
|
2018-03-11 12:54:54 +00:00
|
|
|
|
|
|
|
gtk_search_bar_set_key_capture_widget (GTK_SEARCH_BAR (sl->priv->search_bar),
|
|
|
|
toplevel);
|
2014-11-08 01:38:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
on_search_changed (GtkSearchEntry *entry,
|
|
|
|
GtkInspectorResourceList *sl)
|
|
|
|
{
|
|
|
|
GtkTreeIter iter;
|
|
|
|
gint length;
|
|
|
|
gboolean backwards;
|
|
|
|
|
|
|
|
length = strlen (gtk_entry_get_text (GTK_ENTRY (entry)));
|
|
|
|
backwards = length < sl->priv->search_length;
|
|
|
|
sl->priv->search_length = length;
|
|
|
|
|
|
|
|
if (length == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (gtk_tree_walk_next_match (sl->priv->walk, backwards, backwards, &iter))
|
|
|
|
move_search_to_row (sl, &iter);
|
|
|
|
else if (!backwards)
|
|
|
|
gtk_widget_error_bell (GTK_WIDGET (sl));
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
match_string (const gchar *string,
|
|
|
|
const gchar *text)
|
|
|
|
{
|
|
|
|
gchar *lower;
|
|
|
|
gboolean match = FALSE;
|
|
|
|
|
|
|
|
if (string)
|
|
|
|
{
|
|
|
|
lower = g_ascii_strdown (string, -1);
|
|
|
|
match = g_str_has_prefix (lower, text);
|
|
|
|
g_free (lower);
|
|
|
|
}
|
|
|
|
|
|
|
|
return match;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
match_row (GtkTreeModel *model,
|
|
|
|
GtkTreeIter *iter,
|
|
|
|
gpointer data)
|
|
|
|
{
|
|
|
|
GtkInspectorResourceList *sl = data;
|
|
|
|
gchar *name, *path;
|
|
|
|
const gchar *text;
|
|
|
|
gboolean match;
|
|
|
|
|
|
|
|
text = gtk_entry_get_text (GTK_ENTRY (sl->priv->search_entry));
|
|
|
|
gtk_tree_model_get (model, iter,
|
|
|
|
COLUMN_NAME, &name,
|
|
|
|
COLUMN_PATH, &path,
|
|
|
|
-1);
|
|
|
|
|
|
|
|
match = (match_string (name, text) ||
|
|
|
|
match_string (path, text));
|
|
|
|
|
|
|
|
g_free (name);
|
|
|
|
g_free (path);
|
|
|
|
|
|
|
|
return match;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
search_mode_changed (GObject *search_bar,
|
|
|
|
GParamSpec *pspec,
|
|
|
|
GtkInspectorResourceList *sl)
|
|
|
|
{
|
|
|
|
if (!gtk_search_bar_get_search_mode (GTK_SEARCH_BAR (search_bar)))
|
|
|
|
{
|
|
|
|
gtk_tree_walk_reset (sl->priv->walk, NULL);
|
|
|
|
sl->priv->search_length = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
next_match (GtkButton *button,
|
|
|
|
GtkInspectorResourceList *sl)
|
|
|
|
{
|
|
|
|
if (gtk_search_bar_get_search_mode (GTK_SEARCH_BAR (sl->priv->search_bar)))
|
|
|
|
{
|
|
|
|
GtkTreeIter iter;
|
|
|
|
|
|
|
|
if (gtk_tree_walk_next_match (sl->priv->walk, TRUE, FALSE, &iter))
|
|
|
|
move_search_to_row (sl, &iter);
|
|
|
|
else
|
|
|
|
gtk_widget_error_bell (GTK_WIDGET (sl));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
previous_match (GtkButton *button,
|
|
|
|
GtkInspectorResourceList *sl)
|
|
|
|
{
|
|
|
|
if (gtk_search_bar_get_search_mode (GTK_SEARCH_BAR (sl->priv->search_bar)))
|
|
|
|
{
|
|
|
|
GtkTreeIter iter;
|
|
|
|
|
|
|
|
if (gtk_tree_walk_next_match (sl->priv->walk, TRUE, TRUE, &iter))
|
|
|
|
move_search_to_row (sl, &iter);
|
|
|
|
else
|
|
|
|
gtk_widget_error_bell (GTK_WIDGET (sl));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-15 23:34:38 +00:00
|
|
|
static void
|
|
|
|
gtk_inspector_resource_list_init (GtkInspectorResourceList *sl)
|
|
|
|
{
|
|
|
|
sl->priv = gtk_inspector_resource_list_get_instance_private (sl);
|
2014-10-11 04:58:47 +00:00
|
|
|
|
2014-05-15 23:34:38 +00:00
|
|
|
gtk_widget_init_template (GTK_WIDGET (sl));
|
2014-10-11 04:58:47 +00:00
|
|
|
|
2014-10-10 23:15:02 +00:00
|
|
|
gtk_tree_view_column_set_cell_data_func (sl->priv->count_column,
|
|
|
|
sl->priv->count_renderer,
|
|
|
|
count_data_func, sl, NULL);
|
|
|
|
gtk_tree_view_column_set_cell_data_func (sl->priv->size_column,
|
|
|
|
sl->priv->size_renderer,
|
|
|
|
size_data_func, sl, NULL);
|
2014-10-11 04:58:47 +00:00
|
|
|
|
2014-10-11 00:20:02 +00:00
|
|
|
g_signal_connect (sl, "map", G_CALLBACK (on_map), NULL);
|
2014-11-08 01:38:42 +00:00
|
|
|
|
|
|
|
gtk_search_bar_connect_entry (GTK_SEARCH_BAR (sl->priv->search_bar),
|
|
|
|
GTK_ENTRY (sl->priv->search_entry));
|
|
|
|
|
|
|
|
g_signal_connect (sl->priv->search_bar, "notify::search-mode-enabled",
|
|
|
|
G_CALLBACK (search_mode_changed), sl);
|
|
|
|
sl->priv->walk = gtk_tree_walk_new (GTK_TREE_MODEL (sl->priv->model), match_row, sl, NULL);
|
2014-10-11 04:58:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
constructed (GObject *object)
|
|
|
|
{
|
|
|
|
GtkInspectorResourceList *rl = GTK_INSPECTOR_RESOURCE_LIST (object);
|
|
|
|
|
2014-10-25 01:14:16 +00:00
|
|
|
g_signal_connect (rl->priv->open_details_button, "clicked",
|
|
|
|
G_CALLBACK (open_details), rl);
|
2014-10-11 04:58:47 +00:00
|
|
|
g_signal_connect (rl->priv->close_details_button, "clicked",
|
|
|
|
G_CALLBACK (close_details), rl);
|
|
|
|
|
|
|
|
load_resources (rl);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
get_property (GObject *object,
|
|
|
|
guint param_id,
|
|
|
|
GValue *value,
|
|
|
|
GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
GtkInspectorResourceList *rl = GTK_INSPECTOR_RESOURCE_LIST (object);
|
|
|
|
|
|
|
|
switch (param_id)
|
|
|
|
{
|
2014-10-25 01:14:16 +00:00
|
|
|
case PROP_BUTTONS:
|
|
|
|
g_value_take_object (value, rl->priv->buttons);
|
2014-10-11 04:58:47 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
set_property (GObject *object,
|
|
|
|
guint param_id,
|
|
|
|
const GValue *value,
|
|
|
|
GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
GtkInspectorResourceList *rl = GTK_INSPECTOR_RESOURCE_LIST (object);
|
|
|
|
|
|
|
|
switch (param_id)
|
|
|
|
{
|
2014-10-25 01:14:16 +00:00
|
|
|
case PROP_BUTTONS:
|
|
|
|
rl->priv->buttons = g_value_get_object (value);
|
|
|
|
rl->priv->open_details_button = gtk_stack_get_child_by_name (GTK_STACK (rl->priv->buttons), "list");
|
|
|
|
rl->priv->close_details_button = gtk_stack_get_child_by_name (GTK_STACK (rl->priv->buttons), "details");
|
2014-10-11 04:58:47 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
|
|
|
|
break;
|
|
|
|
}
|
2014-05-15 23:34:38 +00:00
|
|
|
}
|
|
|
|
|
2014-11-08 01:38:42 +00:00
|
|
|
static void
|
|
|
|
finalize (GObject *object)
|
|
|
|
{
|
|
|
|
GtkInspectorResourceList *sl = GTK_INSPECTOR_RESOURCE_LIST (object);
|
|
|
|
|
|
|
|
gtk_tree_walk_free (sl->priv->walk);
|
|
|
|
|
|
|
|
G_OBJECT_CLASS (gtk_inspector_resource_list_parent_class)->finalize (object);
|
|
|
|
}
|
|
|
|
|
2014-05-15 23:34:38 +00:00
|
|
|
static void
|
|
|
|
gtk_inspector_resource_list_class_init (GtkInspectorResourceListClass *klass)
|
|
|
|
{
|
2014-10-11 04:58:47 +00:00
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
2014-05-15 23:34:38 +00:00
|
|
|
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
|
|
|
|
2014-10-11 04:58:47 +00:00
|
|
|
object_class->get_property = get_property;
|
|
|
|
object_class->set_property = set_property;
|
|
|
|
object_class->constructed = constructed;
|
2014-11-08 01:38:42 +00:00
|
|
|
object_class->finalize = finalize;
|
2014-10-11 04:58:47 +00:00
|
|
|
|
2014-10-25 01:14:16 +00:00
|
|
|
g_object_class_install_property (object_class, PROP_BUTTONS,
|
|
|
|
g_param_spec_object ("buttons", NULL, NULL,
|
2014-10-11 04:58:47 +00:00
|
|
|
GTK_TYPE_WIDGET, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
|
|
|
|
2014-11-30 20:59:53 +00:00
|
|
|
gtk_widget_class_set_template_from_resource (widget_class, "/org/gtk/libgtk/inspector/resource-list.ui");
|
2014-05-15 23:34:38 +00:00
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorResourceList, model);
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorResourceList, buffer);
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorResourceList, content);
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorResourceList, image);
|
2014-10-11 00:20:02 +00:00
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorResourceList, name_label);
|
2014-05-19 11:10:33 +00:00
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorResourceList, type_label);
|
2014-07-19 05:20:28 +00:00
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorResourceList, type);
|
2014-05-19 11:10:33 +00:00
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorResourceList, size_label);
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorResourceList, info_grid);
|
2014-10-10 23:15:02 +00:00
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorResourceList, count_column);
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorResourceList, count_renderer);
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorResourceList, size_column);
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorResourceList, size_renderer);
|
2014-10-11 00:20:02 +00:00
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorResourceList, stack);
|
2014-10-11 03:25:07 +00:00
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorResourceList, tree);
|
2014-11-08 01:38:42 +00:00
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorResourceList, search_bar);
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorResourceList, search_entry);
|
|
|
|
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorResourceList, path_column);
|
2014-05-15 23:34:38 +00:00
|
|
|
|
2014-10-11 00:20:02 +00:00
|
|
|
gtk_widget_class_bind_template_callback (widget_class, row_activated);
|
2014-10-25 01:52:23 +00:00
|
|
|
gtk_widget_class_bind_template_callback (widget_class, on_selection_changed);
|
2014-11-08 01:38:42 +00:00
|
|
|
gtk_widget_class_bind_template_callback (widget_class, on_hierarchy_changed);
|
|
|
|
gtk_widget_class_bind_template_callback (widget_class, on_search_changed);
|
|
|
|
gtk_widget_class_bind_template_callback (widget_class, next_match);
|
|
|
|
gtk_widget_class_bind_template_callback (widget_class, previous_match);
|
2014-05-15 23:34:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// vim: set et sw=2 ts=2:
|