Compare commits
133 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8815e1bb0c | |||
| a57e0a4bf6 | |||
| b74b0edf0d | |||
| 36fac37cda | |||
| 91e2661306 | |||
| 559ea908de | |||
| f0b146d7c8 | |||
| a030197974 | |||
| bf2bf948ab | |||
| 5cb49363fa | |||
| 802c99d4b4 | |||
| 173534710a | |||
| 347959a112 | |||
| 1ae939cf5a | |||
| edf523fe30 | |||
| bfe2970a98 | |||
| c7749b9098 | |||
| 2226fe0fca | |||
| cbf9375f97 | |||
| 5297eb36b9 | |||
| b69e7777cd | |||
| 817da34f7e | |||
| 8fa44fc3e6 | |||
| c7e94151b2 | |||
| 729ba44297 | |||
| 2a2a6879c5 | |||
| e7b773b031 | |||
| 57a225681c | |||
| ea07a92366 | |||
| 76290e8ddb | |||
| 26d83b1ab7 | |||
| 2bba856206 | |||
| bf3382a89e | |||
| 3162e25671 | |||
| 3d931b4fe2 | |||
| fc770a383a | |||
| 62c385a9dd | |||
| 7c4ad1a5c4 | |||
| ac524bb13a | |||
| 66fa9380b5 | |||
| b64eb6ca13 | |||
| 9b2d8ac362 | |||
| 2a90bc1a9b | |||
| d4b868d9bc | |||
| b54f6710a7 | |||
| 6bb7caf155 | |||
| 202348f9d0 | |||
| 1a613de2f6 | |||
| 665df37703 | |||
| acad5e4e3d | |||
| 6267c8469b | |||
| 5a2f791bdd | |||
| 286a00a1db | |||
| 11dd602b28 | |||
| 35988d659d | |||
| be3449b3ce | |||
| 2d8fddc1e9 | |||
| 644d522d19 | |||
| a8b0125da1 | |||
| acccac516e | |||
| d65214fa4e | |||
| 1d96fc8237 | |||
| 882a87ca19 | |||
| 1dbb8df95f | |||
| f6c2c2edbd | |||
| c4e4de36f6 | |||
| 67cbb2a7d3 | |||
| a979daa8ea | |||
| fb14f50ec1 | |||
| 6099fbafc1 | |||
| 6f2f828bce | |||
| 795d3122cc | |||
| 5080730728 | |||
| f75a3a0e95 | |||
| b75db7d1c6 | |||
| b03069bdf6 | |||
| 1c71e56e75 | |||
| 9332d0dcc8 | |||
| 9ad37583e6 | |||
| 69975627e9 | |||
| b74a489aba | |||
| 599b807726 | |||
| 6510ca8bdd | |||
| be20a04e04 | |||
| 92e5536335 | |||
| c2da2f7ecd | |||
| 54bfd380a8 | |||
| f01d695e6c | |||
| 619b2465c1 | |||
| cc18191a8e | |||
| 1f8e7c8aab | |||
| 671daea262 | |||
| 76533513c2 | |||
| 0d3988365b | |||
| 0966636803 | |||
| 7c3b30036e | |||
| 988901294d | |||
| 43b9fc6981 | |||
| 25f670faae | |||
| d0068a036f | |||
| fae014eb45 | |||
| f0ea0be15d | |||
| 9650236b23 | |||
| c0e2d7c62f | |||
| cc072eb7cd | |||
| 613213f597 | |||
| e25c25fcb5 | |||
| 52666d6fe5 | |||
| 56b3669411 | |||
| e3b5b76cdd | |||
| bbb28196e5 | |||
| 72d3a9042c | |||
| f2853ffa8e | |||
| fca2ba963d | |||
| 806779769e | |||
| 82aa0d1f7c | |||
| 72f1d34eca | |||
| c267a75eef | |||
| 83543423e2 | |||
| d0bb72a2aa | |||
| 8cc2a44268 | |||
| 4800dd3f95 | |||
| 2534310ce9 | |||
| 3a4fbc5e50 | |||
| 89a67ac719 | |||
| 21b84b1890 | |||
| 20935f678b | |||
| c41b4130c6 | |||
| f1b010af66 | |||
| ec1133d6e1 | |||
| 8fcf1b78a4 | |||
| 21f9148155 | |||
| d4f0593b37 |
@@ -9,7 +9,6 @@
|
|||||||
<property name="default-height">768</property>
|
<property name="default-height">768</property>
|
||||||
<child type="titlebar">
|
<child type="titlebar">
|
||||||
<object class="GtkHeaderBar" id="header">
|
<object class="GtkHeaderBar" id="header">
|
||||||
<property name="show-title-buttons">1</property>
|
|
||||||
<child type="start">
|
<child type="start">
|
||||||
<object class="GtkButton">
|
<object class="GtkButton">
|
||||||
<property name="icon-name">document-open-symbolic</property>
|
<property name="icon-name">document-open-symbolic</property>
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ constraint_view_init (ConstraintView *self)
|
|||||||
g_list_store_append (list, children);
|
g_list_store_append (list, children);
|
||||||
g_list_store_append (list, guides);
|
g_list_store_append (list, guides);
|
||||||
g_list_store_append (list, constraints);
|
g_list_store_append (list, constraints);
|
||||||
self->model = G_LIST_MODEL (gtk_flatten_list_model_new (G_TYPE_OBJECT, G_LIST_MODEL (list)));
|
self->model = G_LIST_MODEL (gtk_flatten_list_model_new (G_LIST_MODEL (list)));
|
||||||
g_object_unref (children);
|
g_object_unref (children);
|
||||||
g_object_unref (guides);
|
g_object_unref (guides);
|
||||||
g_object_unref (constraints);
|
g_object_unref (constraints);
|
||||||
|
|||||||
@@ -140,6 +140,7 @@
|
|||||||
</gresource>
|
</gresource>
|
||||||
<gresource prefix="/listview_colors">
|
<gresource prefix="/listview_colors">
|
||||||
<file compressed="true">color.names.txt</file>
|
<file compressed="true">color.names.txt</file>
|
||||||
|
<file>listview_colors.css</file>
|
||||||
</gresource>
|
</gresource>
|
||||||
<gresource prefix="/shortcuts">
|
<gresource prefix="/shortcuts">
|
||||||
<file>shortcuts.ui</file>
|
<file>shortcuts.ui</file>
|
||||||
@@ -225,6 +226,7 @@
|
|||||||
<file>listview_minesweeper.c</file>
|
<file>listview_minesweeper.c</file>
|
||||||
<file>listview_settings.c</file>
|
<file>listview_settings.c</file>
|
||||||
<file>listview_weather.c</file>
|
<file>listview_weather.c</file>
|
||||||
|
<file>listview_words.c</file>
|
||||||
<file>list_store.c</file>
|
<file>list_store.c</file>
|
||||||
<file>markup.c</file>
|
<file>markup.c</file>
|
||||||
<file>modelbutton.c</file>
|
<file>modelbutton.c</file>
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ strings_setup_item_full (GtkSignalListItemFactory *factory,
|
|||||||
gtk_label_set_xalign (GTK_LABEL (title), 0.0);
|
gtk_label_set_xalign (GTK_LABEL (title), 0.0);
|
||||||
description = gtk_label_new ("");
|
description = gtk_label_new ("");
|
||||||
gtk_label_set_xalign (GTK_LABEL (description), 0.0);
|
gtk_label_set_xalign (GTK_LABEL (description), 0.0);
|
||||||
gtk_style_context_add_class (gtk_widget_get_style_context (description), "dim-label");
|
gtk_widget_add_css_class (description, "dim-label");
|
||||||
|
|
||||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
|
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
|
||||||
box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
|
box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
<property name="default-height">400</property>
|
<property name="default-height">400</property>
|
||||||
<child type="titlebar">
|
<child type="titlebar">
|
||||||
<object class="GtkHeaderBar" id="">
|
<object class="GtkHeaderBar" id="">
|
||||||
<property name="show-title-buttons">1</property>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
<property name="title">Font Explorer</property>
|
<property name="title">Font Explorer</property>
|
||||||
<child type="titlebar">
|
<child type="titlebar">
|
||||||
<object class="GtkHeaderBar">
|
<object class="GtkHeaderBar">
|
||||||
<property name="show-title-buttons">1</property>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton" id="reset">
|
<object class="GtkButton" id="reset">
|
||||||
<property name="receives-default">1</property>
|
<property name="receives-default">1</property>
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ do_headerbar (GtkWidget *do_widget)
|
|||||||
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
|
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
|
||||||
|
|
||||||
header = gtk_header_bar_new ();
|
header = gtk_header_bar_new ();
|
||||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
|
|
||||||
|
|
||||||
button = gtk_button_new ();
|
button = gtk_button_new ();
|
||||||
icon = g_themed_icon_new ("mail-send-receive-symbolic");
|
icon = g_themed_icon_new ("mail-send-receive-symbolic");
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
<property name="default-height">500</property>
|
<property name="default-height">500</property>
|
||||||
<child type="titlebar">
|
<child type="titlebar">
|
||||||
<object class="GtkHeaderBar">
|
<object class="GtkHeaderBar">
|
||||||
<property name="show-title-buttons">1</property>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
@@ -627,6 +627,23 @@ setup_listitem_cb (GtkListItemFactory *factory,
|
|||||||
gtk_expression_unref (color_expression);
|
gtk_expression_unref (color_expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
setup_selection_listitem_cb (GtkListItemFactory *factory,
|
||||||
|
GtkListItem *list_item)
|
||||||
|
{
|
||||||
|
GtkWidget *picture;
|
||||||
|
GtkExpression *color_expression, *expression;
|
||||||
|
|
||||||
|
expression = gtk_constant_expression_new (GTK_TYPE_LIST_ITEM, list_item);
|
||||||
|
color_expression = gtk_property_expression_new (GTK_TYPE_LIST_ITEM, expression, "item");
|
||||||
|
|
||||||
|
picture = gtk_picture_new ();
|
||||||
|
gtk_widget_set_size_request (picture, 8, 8);
|
||||||
|
gtk_expression_bind (color_expression, picture, "paintable", NULL);
|
||||||
|
|
||||||
|
gtk_list_item_set_child (list_item, picture);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_title (gpointer item,
|
set_title (gpointer item,
|
||||||
const char *title)
|
const char *title)
|
||||||
@@ -659,7 +676,7 @@ create_color_grid (void)
|
|||||||
gtk_grid_view_set_max_columns (GTK_GRID_VIEW (gridview), 24);
|
gtk_grid_view_set_max_columns (GTK_GRID_VIEW (gridview), 24);
|
||||||
gtk_grid_view_set_enable_rubberband (GTK_GRID_VIEW (gridview), TRUE);
|
gtk_grid_view_set_enable_rubberband (GTK_GRID_VIEW (gridview), TRUE);
|
||||||
|
|
||||||
model = G_LIST_MODEL (gtk_sort_list_model_new (gtk_color_list_new (0), NULL));
|
model = G_LIST_MODEL (gtk_sor5_list_model_new (gtk_color_list_new (0), NULL));
|
||||||
|
|
||||||
selection = G_LIST_MODEL (gtk_multi_selection_new (model));
|
selection = G_LIST_MODEL (gtk_multi_selection_new (model));
|
||||||
gtk_grid_view_set_model (GTK_GRID_VIEW (gridview), selection);
|
gtk_grid_view_set_model (GTK_GRID_VIEW (gridview), selection);
|
||||||
@@ -777,6 +794,95 @@ bind_number_item (GtkSignalListItemFactory *factory,
|
|||||||
g_free (string);
|
g_free (string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_selection_count (GListModel *model,
|
||||||
|
guint position,
|
||||||
|
guint removed,
|
||||||
|
guint added,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
char *text;
|
||||||
|
text = g_strdup_printf ("%u", g_list_model_get_n_items (model));
|
||||||
|
gtk_label_set_label (GTK_LABEL (data), text);
|
||||||
|
g_free (text);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_selection_average (GListModel *model,
|
||||||
|
guint position,
|
||||||
|
guint removed,
|
||||||
|
guint added,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
guint n = g_list_model_get_n_items (model);
|
||||||
|
GdkRGBA c = { 0, 0, 0, 1 };
|
||||||
|
guint i;
|
||||||
|
GtkColor *color;
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
color = g_list_model_get_item (model, i);
|
||||||
|
|
||||||
|
c.red += color->color.red;
|
||||||
|
c.green += color->color.green;
|
||||||
|
c.blue += color->color.blue;
|
||||||
|
|
||||||
|
g_object_unref (color);
|
||||||
|
}
|
||||||
|
|
||||||
|
color = gtk_color_new ("", c.red / n, c.green / n, c.blue / n);
|
||||||
|
gtk_picture_set_paintable (GTK_PICTURE (data), GDK_PAINTABLE (color));
|
||||||
|
g_object_unref (color);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
compare_red (gconstpointer a,
|
||||||
|
gconstpointer b,
|
||||||
|
gpointer unused)
|
||||||
|
{
|
||||||
|
GtkColor *colora = (GtkColor *) a;
|
||||||
|
GtkColor *colorb = (GtkColor *) b;
|
||||||
|
|
||||||
|
if (colora->color.red < colorb->color.red)
|
||||||
|
return GTK_ORDERING_LARGER;
|
||||||
|
else if (colora->color.red > colorb->color.red)
|
||||||
|
return GTK_ORDERING_SMALLER;
|
||||||
|
else
|
||||||
|
return GTK_ORDERING_EQUAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
compare_green (gconstpointer a,
|
||||||
|
gconstpointer b,
|
||||||
|
gpointer unused)
|
||||||
|
{
|
||||||
|
GtkColor *colora = (GtkColor *) a;
|
||||||
|
GtkColor *colorb = (GtkColor *) b;
|
||||||
|
|
||||||
|
if (colora->color.green < colorb->color.green)
|
||||||
|
return GTK_ORDERING_LARGER;
|
||||||
|
else if (colora->color.green > colorb->color.green)
|
||||||
|
return GTK_ORDERING_SMALLER;
|
||||||
|
else
|
||||||
|
return GTK_ORDERING_EQUAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
compare_blue (gconstpointer a,
|
||||||
|
gconstpointer b,
|
||||||
|
gpointer unused)
|
||||||
|
{
|
||||||
|
GtkColor *colora = (GtkColor *) a;
|
||||||
|
GtkColor *colorb = (GtkColor *) b;
|
||||||
|
|
||||||
|
if (colora->color.blue < colorb->color.blue)
|
||||||
|
return GTK_ORDERING_LARGER;
|
||||||
|
else if (colora->color.blue > colorb->color.blue)
|
||||||
|
return GTK_ORDERING_SMALLER;
|
||||||
|
else
|
||||||
|
return GTK_ORDERING_EQUAL;
|
||||||
|
}
|
||||||
|
|
||||||
static GtkWidget *window = NULL;
|
static GtkWidget *window = NULL;
|
||||||
|
|
||||||
GtkWidget *
|
GtkWidget *
|
||||||
@@ -797,11 +903,26 @@ do_listview_colors (GtkWidget *do_widget)
|
|||||||
PangoAttrList *attrs;
|
PangoAttrList *attrs;
|
||||||
char *string;
|
char *string;
|
||||||
guint len;
|
guint len;
|
||||||
|
GtkWidget *selection_view;
|
||||||
|
GListModel *selection_filter;
|
||||||
|
GListModel *no_selection;
|
||||||
|
GtkWidget *grid;
|
||||||
|
GtkWidget *selection_size_label;
|
||||||
|
GtkWidget *selection_average_picture;
|
||||||
|
GtkWidget *selection_info_toggle;
|
||||||
|
GtkWidget *selection_info_revealer;
|
||||||
|
GtkCssProvider *provider;
|
||||||
|
|
||||||
|
provider = gtk_css_provider_new ();
|
||||||
|
gtk_css_provider_load_from_resource (provider, "/listview_colors/listview_colors.css");
|
||||||
|
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
|
||||||
|
GTK_STYLE_PROVIDER (provider),
|
||||||
|
800);
|
||||||
|
g_object_unref (provider);
|
||||||
|
|
||||||
window = gtk_window_new ();
|
window = gtk_window_new ();
|
||||||
gtk_window_set_title (GTK_WINDOW (window), "Colors");
|
gtk_window_set_title (GTK_WINDOW (window), "Colors");
|
||||||
header = gtk_header_bar_new ();
|
header = gtk_header_bar_new ();
|
||||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
|
|
||||||
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
||||||
|
|
||||||
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
|
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
|
||||||
@@ -809,18 +930,89 @@ do_listview_colors (GtkWidget *do_widget)
|
|||||||
gtk_widget_get_display (do_widget));
|
gtk_widget_get_display (do_widget));
|
||||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer*)&window);
|
g_object_add_weak_pointer (G_OBJECT (window), (gpointer*)&window);
|
||||||
|
|
||||||
|
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||||
|
gtk_window_set_child (GTK_WINDOW (window), box);
|
||||||
|
|
||||||
|
selection_info_revealer = gtk_revealer_new ();
|
||||||
|
gtk_box_append (GTK_BOX (box), selection_info_revealer);
|
||||||
|
|
||||||
|
grid = gtk_grid_new ();
|
||||||
|
gtk_revealer_set_child (GTK_REVEALER (selection_info_revealer), grid);
|
||||||
|
gtk_widget_set_margin_start (grid, 10);
|
||||||
|
gtk_widget_set_margin_end (grid, 10);
|
||||||
|
gtk_widget_set_margin_top (grid, 10);
|
||||||
|
gtk_widget_set_margin_bottom (grid, 10);
|
||||||
|
gtk_grid_set_row_spacing (GTK_GRID (grid), 10);
|
||||||
|
gtk_grid_set_column_spacing (GTK_GRID (grid), 10);
|
||||||
|
|
||||||
|
label = gtk_label_new ("Selection");
|
||||||
|
gtk_widget_set_hexpand (label, TRUE);
|
||||||
|
gtk_widget_add_css_class (label, "title-3");
|
||||||
|
gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 5, 1);
|
||||||
|
|
||||||
|
gtk_grid_attach (GTK_GRID (grid), gtk_label_new ("Size:"), 0, 2, 1, 1);
|
||||||
|
|
||||||
|
selection_size_label = gtk_label_new ("0");
|
||||||
|
gtk_grid_attach (GTK_GRID (grid), selection_size_label, 1, 2, 1, 1);
|
||||||
|
|
||||||
|
gtk_grid_attach (GTK_GRID (grid), gtk_label_new ("Average:"), 2, 2, 1, 1);
|
||||||
|
|
||||||
|
selection_average_picture = gtk_picture_new ();
|
||||||
|
gtk_widget_set_size_request (selection_average_picture, 32, 32);
|
||||||
|
gtk_grid_attach (GTK_GRID (grid), selection_average_picture, 3, 2, 1, 1);
|
||||||
|
|
||||||
|
label = gtk_label_new ("");
|
||||||
|
gtk_widget_set_hexpand (label, TRUE);
|
||||||
|
gtk_grid_attach (GTK_GRID (grid), label, 4, 2, 1, 1);
|
||||||
|
|
||||||
sw = gtk_scrolled_window_new ();
|
sw = gtk_scrolled_window_new ();
|
||||||
gtk_window_set_child (GTK_WINDOW (window), sw);
|
gtk_widget_set_hexpand (sw, TRUE);
|
||||||
|
|
||||||
|
gtk_grid_attach (GTK_GRID (grid), sw, 0, 1, 5, 1);
|
||||||
|
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||||
|
GTK_POLICY_NEVER,
|
||||||
|
GTK_POLICY_AUTOMATIC);
|
||||||
|
|
||||||
|
factory = gtk_signal_list_item_factory_new ();
|
||||||
|
g_signal_connect (factory, "setup", G_CALLBACK (setup_selection_listitem_cb), NULL);
|
||||||
|
selection_view = gtk_grid_view_new_with_factory (factory);
|
||||||
|
gtk_widget_add_css_class (selection_view, "compact");
|
||||||
|
gtk_grid_view_set_max_columns (GTK_GRID_VIEW (selection_view), 200);
|
||||||
|
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), selection_view);
|
||||||
|
|
||||||
|
sw = gtk_scrolled_window_new ();
|
||||||
|
gtk_box_append (GTK_BOX (box), sw);
|
||||||
|
|
||||||
gridview = create_color_grid ();
|
gridview = create_color_grid ();
|
||||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), gridview);
|
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), gridview);
|
||||||
|
gtk_widget_set_hexpand (sw, TRUE);
|
||||||
|
gtk_widget_set_vexpand (sw, TRUE);
|
||||||
model = gtk_grid_view_get_model (GTK_GRID_VIEW (gridview));
|
model = gtk_grid_view_get_model (GTK_GRID_VIEW (gridview));
|
||||||
|
|
||||||
|
selection_filter = G_LIST_MODEL (gtk_selection_filter_model_new (GTK_SELECTION_MODEL (model)));
|
||||||
|
g_signal_connect (selection_filter, "items-changed", G_CALLBACK (update_selection_count), selection_size_label);
|
||||||
|
g_signal_connect (selection_filter, "items-changed", G_CALLBACK (update_selection_average), selection_average_picture);
|
||||||
|
|
||||||
|
no_selection = G_LIST_MODEL (gtk_no_selection_new (selection_filter));
|
||||||
|
gtk_grid_view_set_model (GTK_GRID_VIEW (selection_view), no_selection);
|
||||||
|
g_object_unref (selection_filter);
|
||||||
|
g_object_unref (no_selection);
|
||||||
|
|
||||||
g_object_get (model, "model", &model, NULL);
|
g_object_get (model, "model", &model, NULL);
|
||||||
|
|
||||||
|
selection_info_toggle = gtk_toggle_button_new ();
|
||||||
|
gtk_button_set_icon_name (GTK_BUTTON (selection_info_toggle), "emblem-important-symbolic");
|
||||||
|
gtk_widget_set_tooltip_text (selection_info_toggle, "Show selection info");
|
||||||
|
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), selection_info_toggle);
|
||||||
|
|
||||||
|
g_object_bind_property (selection_info_toggle, "active",
|
||||||
|
selection_info_revealer, "reveal-child",
|
||||||
|
G_BINDING_DEFAULT);
|
||||||
|
|
||||||
button = gtk_button_new_with_mnemonic ("_Refill");
|
button = gtk_button_new_with_mnemonic ("_Refill");
|
||||||
g_signal_connect (button, "clicked",
|
g_signal_connect (button, "clicked",
|
||||||
G_CALLBACK (refill),
|
G_CALLBACK (refill),
|
||||||
gtk_sort_list_model_get_model (GTK_SORT_LIST_MODEL (model)));
|
gtk_sor5_list_model_get_model (GTK_SOR5_LIST_MODEL (model)));
|
||||||
|
|
||||||
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), button);
|
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), button);
|
||||||
|
|
||||||
@@ -843,7 +1035,7 @@ do_listview_colors (GtkWidget *do_widget)
|
|||||||
gtk_drop_down_set_from_strings (GTK_DROP_DOWN (dropdown), (const char *[]) { "8", "64", "512", "4096", "32768", "262144", "2097152", "16777216", NULL });
|
gtk_drop_down_set_from_strings (GTK_DROP_DOWN (dropdown), (const char *[]) { "8", "64", "512", "4096", "32768", "262144", "2097152", "16777216", NULL });
|
||||||
g_signal_connect (dropdown, "notify::selected",
|
g_signal_connect (dropdown, "notify::selected",
|
||||||
G_CALLBACK (limit_changed_cb),
|
G_CALLBACK (limit_changed_cb),
|
||||||
gtk_sort_list_model_get_model (GTK_SORT_LIST_MODEL (model)));
|
gtk_sor5_list_model_get_model (GTK_SOR5_LIST_MODEL (model)));
|
||||||
g_signal_connect (dropdown, "notify::selected",
|
g_signal_connect (dropdown, "notify::selected",
|
||||||
G_CALLBACK (limit_changed_cb2),
|
G_CALLBACK (limit_changed_cb2),
|
||||||
label);
|
label);
|
||||||
@@ -878,18 +1070,30 @@ do_listview_colors (GtkWidget *do_widget)
|
|||||||
g_list_store_append (sorters, sorter);
|
g_list_store_append (sorters, sorter);
|
||||||
gtk_multi_sorter_append (GTK_MULTI_SORTER (multi_sorter), sorter);
|
gtk_multi_sorter_append (GTK_MULTI_SORTER (multi_sorter), sorter);
|
||||||
|
|
||||||
|
sorter = gtk_custom_sorter_new (compare_red, NULL, NULL);
|
||||||
|
set_title (sorter, "Red (fast)");
|
||||||
|
g_list_store_append (sorters, sorter);
|
||||||
|
|
||||||
sorter = gtk_numeric_sorter_new (gtk_property_expression_new (GTK_TYPE_COLOR, NULL, "green"));
|
sorter = gtk_numeric_sorter_new (gtk_property_expression_new (GTK_TYPE_COLOR, NULL, "green"));
|
||||||
gtk_numeric_sorter_set_sort_order (GTK_NUMERIC_SORTER (sorter), GTK_SORT_DESCENDING);
|
gtk_numeric_sorter_set_sort_order (GTK_NUMERIC_SORTER (sorter), GTK_SORT_DESCENDING);
|
||||||
set_title (sorter, "Green");
|
set_title (sorter, "Green");
|
||||||
g_list_store_append (sorters, sorter);
|
g_list_store_append (sorters, sorter);
|
||||||
gtk_multi_sorter_append (GTK_MULTI_SORTER (multi_sorter), sorter);
|
gtk_multi_sorter_append (GTK_MULTI_SORTER (multi_sorter), sorter);
|
||||||
|
|
||||||
|
sorter = gtk_custom_sorter_new (compare_green, NULL, NULL);
|
||||||
|
set_title (sorter, "Green (fast)");
|
||||||
|
g_list_store_append (sorters, sorter);
|
||||||
|
|
||||||
sorter = gtk_numeric_sorter_new (gtk_property_expression_new (GTK_TYPE_COLOR, NULL, "blue"));
|
sorter = gtk_numeric_sorter_new (gtk_property_expression_new (GTK_TYPE_COLOR, NULL, "blue"));
|
||||||
gtk_numeric_sorter_set_sort_order (GTK_NUMERIC_SORTER (sorter), GTK_SORT_DESCENDING);
|
gtk_numeric_sorter_set_sort_order (GTK_NUMERIC_SORTER (sorter), GTK_SORT_DESCENDING);
|
||||||
set_title (sorter, "Blue");
|
set_title (sorter, "Blue");
|
||||||
g_list_store_append (sorters, sorter);
|
g_list_store_append (sorters, sorter);
|
||||||
gtk_multi_sorter_append (GTK_MULTI_SORTER (multi_sorter), sorter);
|
gtk_multi_sorter_append (GTK_MULTI_SORTER (multi_sorter), sorter);
|
||||||
|
|
||||||
|
sorter = gtk_custom_sorter_new (compare_blue, NULL, NULL);
|
||||||
|
set_title (sorter, "Blue (fast)");
|
||||||
|
g_list_store_append (sorters, sorter);
|
||||||
|
|
||||||
set_title (multi_sorter, "RGB");
|
set_title (multi_sorter, "RGB");
|
||||||
g_list_store_append (sorters, multi_sorter);
|
g_list_store_append (sorters, multi_sorter);
|
||||||
g_object_unref (multi_sorter);
|
g_object_unref (multi_sorter);
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
.view.compact > child {
|
||||||
|
padding: 1px;
|
||||||
|
}
|
||||||
@@ -174,7 +174,6 @@
|
|||||||
<property name="default-height">400</property>
|
<property name="default-height">400</property>
|
||||||
<child type="titlebar">
|
<child type="titlebar">
|
||||||
<object class="GtkHeaderBar" id="">
|
<object class="GtkHeaderBar" id="">
|
||||||
<property name="show-title-buttons">1</property>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton">
|
<object class="GtkButton">
|
||||||
<property name="icon-name">go-up-symbolic</property>
|
<property name="icon-name">go-up-symbolic</property>
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
<property name="title" translatable="yes">Minesweeper</property>
|
<property name="title" translatable="yes">Minesweeper</property>
|
||||||
<child type="titlebar">
|
<child type="titlebar">
|
||||||
<object class="GtkHeaderBar" id="">
|
<object class="GtkHeaderBar" id="">
|
||||||
<property name="show-title-buttons">1</property>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton">
|
<object class="GtkButton">
|
||||||
<property name="label">New Game</property>
|
<property name="label">New Game</property>
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
<property name="default-height">480</property>
|
<property name="default-height">480</property>
|
||||||
<child type="titlebar">
|
<child type="titlebar">
|
||||||
<object class="GtkHeaderBar">
|
<object class="GtkHeaderBar">
|
||||||
<property name="show-title-buttons">1</property>
|
|
||||||
<child type="end">
|
<child type="end">
|
||||||
<object class="GtkToggleButton" id="search_button">
|
<object class="GtkToggleButton" id="search_button">
|
||||||
<property name="icon-name">system-search-symbolic</property>
|
<property name="icon-name">system-search-symbolic</property>
|
||||||
|
|||||||
@@ -194,8 +194,8 @@ create_weather_model (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
setup_widget (GtkListItem *list_item,
|
setup_widget (GtkSignalListItemFactory *factory,
|
||||||
gpointer unused)
|
GtkListItem *list_item)
|
||||||
{
|
{
|
||||||
GtkWidget *box, *child;
|
GtkWidget *box, *child;
|
||||||
|
|
||||||
@@ -218,8 +218,8 @@ setup_widget (GtkListItem *list_item,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
bind_widget (GtkListItem *list_item,
|
bind_widget (GtkSignalListItemFactory *factory,
|
||||||
gpointer unused)
|
GtkListItem *list_item)
|
||||||
{
|
{
|
||||||
GtkWidget *box, *child;
|
GtkWidget *box, *child;
|
||||||
GtkWeatherInfo *info;
|
GtkWeatherInfo *info;
|
||||||
@@ -282,11 +282,12 @@ create_weather_view (void)
|
|||||||
{
|
{
|
||||||
GtkWidget *listview;
|
GtkWidget *listview;
|
||||||
GListModel *model, *selection;
|
GListModel *model, *selection;
|
||||||
|
GtkListItemFactory *factory;
|
||||||
|
|
||||||
listview = gtk_list_view_new_with_factory (
|
factory = gtk_signal_list_item_factory_new ();
|
||||||
gtk_functions_list_item_factory_new (setup_widget,
|
g_signal_connect (factory, "setup", G_CALLBACK (setup_widget), NULL);
|
||||||
bind_widget,
|
g_signal_connect (factory, "bind", G_CALLBACK (bind_widget), NULL);
|
||||||
NULL, NULL));
|
listview = gtk_list_view_new_with_factory (factory);
|
||||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (listview), GTK_ORIENTATION_HORIZONTAL);
|
gtk_orientable_set_orientation (GTK_ORIENTABLE (listview), GTK_ORIENTATION_HORIZONTAL);
|
||||||
gtk_list_view_set_show_separators (GTK_LIST_VIEW (listview), TRUE);
|
gtk_list_view_set_show_separators (GTK_LIST_VIEW (listview), TRUE);
|
||||||
model = create_weather_model ();
|
model = create_weather_model ();
|
||||||
|
|||||||
@@ -0,0 +1,241 @@
|
|||||||
|
/* Lists/Words
|
||||||
|
*
|
||||||
|
* This demo shows filtering a long list - of words.
|
||||||
|
*
|
||||||
|
* You should have the file `/usr/share/dict/words` installed for
|
||||||
|
* this demo to work.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
static GtkWidget *window = NULL;
|
||||||
|
static GtkWidget *progress;
|
||||||
|
|
||||||
|
const char *factory_text =
|
||||||
|
"<?xml version='1.0' encoding='UTF-8'?>\n"
|
||||||
|
"<interface>\n"
|
||||||
|
" <template class='GtkListItem'>\n"
|
||||||
|
" <property name='child'>\n"
|
||||||
|
" <object class='GtkLabel'>\n"
|
||||||
|
" <property name='ellipsize'>end</property>\n"
|
||||||
|
" <property name='xalign'>0</property>\n"
|
||||||
|
" <binding name='label'>\n"
|
||||||
|
" <lookup name='string' type='GtkStringObject'>\n"
|
||||||
|
" <lookup name='item'>GtkListItem</lookup>\n"
|
||||||
|
" </lookup>\n"
|
||||||
|
" </binding>\n"
|
||||||
|
" </object>\n"
|
||||||
|
" </property>\n"
|
||||||
|
" </template>\n"
|
||||||
|
"</interface>\n";
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_title_cb (GtkFilterListModel *model)
|
||||||
|
{
|
||||||
|
guint total;
|
||||||
|
char *title;
|
||||||
|
guint pending;
|
||||||
|
|
||||||
|
total = g_list_model_get_n_items (gtk_filter_list_model_get_model (model));
|
||||||
|
pending = gtk_filter_list_model_get_pending (model);
|
||||||
|
|
||||||
|
title = g_strdup_printf ("%u lines", g_list_model_get_n_items (G_LIST_MODEL (model)));
|
||||||
|
|
||||||
|
gtk_widget_set_visible (progress, pending != 0);
|
||||||
|
gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progress), (total - pending) / (double) total);
|
||||||
|
gtk_window_set_title (GTK_WINDOW (window), title);
|
||||||
|
g_free (title);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
read_lines_cb (GObject *object,
|
||||||
|
GAsyncResult *result,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
GBufferedInputStream *stream = G_BUFFERED_INPUT_STREAM (object);
|
||||||
|
GtkStringList *stringlist = data;
|
||||||
|
GError *error = NULL;
|
||||||
|
gsize size;
|
||||||
|
GPtrArray *lines;
|
||||||
|
gssize n_filled;
|
||||||
|
const char *buffer, *newline;
|
||||||
|
|
||||||
|
n_filled = g_buffered_input_stream_fill_finish (stream, result, &error);
|
||||||
|
if (n_filled < 0)
|
||||||
|
{
|
||||||
|
g_print ("Could not read data: %s\n", error->message);
|
||||||
|
g_clear_error (&error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer = g_buffered_input_stream_peek_buffer (stream, &size);
|
||||||
|
|
||||||
|
if (n_filled == 0)
|
||||||
|
{
|
||||||
|
if (size)
|
||||||
|
gtk_string_list_take (stringlist, g_utf8_make_valid (buffer, size));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lines = NULL;
|
||||||
|
while ((newline = memchr (buffer, '\n', size)))
|
||||||
|
{
|
||||||
|
if (newline > buffer)
|
||||||
|
{
|
||||||
|
if (lines == NULL)
|
||||||
|
lines = g_ptr_array_new_with_free_func (g_free);
|
||||||
|
g_ptr_array_add (lines, g_utf8_make_valid (buffer, newline - buffer));
|
||||||
|
}
|
||||||
|
if (g_input_stream_skip (G_INPUT_STREAM (stream), newline - buffer + 1, NULL, &error) < 0)
|
||||||
|
{
|
||||||
|
g_clear_error (&error);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
buffer = g_buffered_input_stream_peek_buffer (stream, &size);
|
||||||
|
}
|
||||||
|
if (lines == NULL)
|
||||||
|
{
|
||||||
|
g_buffered_input_stream_set_buffer_size (stream, g_buffered_input_stream_get_buffer_size (stream) + 4096);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_ptr_array_add (lines, NULL);
|
||||||
|
gtk_string_list_splice (stringlist, g_list_model_get_n_items (G_LIST_MODEL (stringlist)), 0, (const char **) lines->pdata);
|
||||||
|
g_ptr_array_free (lines, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_buffered_input_stream_fill_async (stream, -1, G_PRIORITY_HIGH_IDLE, NULL, read_lines_cb, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
file_is_open_cb (GObject *file,
|
||||||
|
GAsyncResult *result,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
GFileInputStream *file_stream;
|
||||||
|
GBufferedInputStream *stream;
|
||||||
|
|
||||||
|
file_stream = g_file_read_finish (G_FILE (file), result, &error);
|
||||||
|
if (file_stream == NULL)
|
||||||
|
{
|
||||||
|
g_print ("Could not open file: %s\n", error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream = G_BUFFERED_INPUT_STREAM (g_buffered_input_stream_new (G_INPUT_STREAM (file_stream)));
|
||||||
|
g_buffered_input_stream_fill_async (stream, -1, G_PRIORITY_HIGH_IDLE, NULL, read_lines_cb, data);
|
||||||
|
g_object_unref (stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
load_file (GtkStringList *list,
|
||||||
|
GFile *file)
|
||||||
|
{
|
||||||
|
gtk_string_list_splice (list, 0, g_list_model_get_n_items (G_LIST_MODEL (list)), NULL);
|
||||||
|
g_file_read_async (file, G_PRIORITY_HIGH_IDLE, NULL, file_is_open_cb, list);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
file_selected_cb (GtkWidget *button,
|
||||||
|
GtkStringList *stringlist)
|
||||||
|
{
|
||||||
|
GFile *file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (button));
|
||||||
|
|
||||||
|
if (file)
|
||||||
|
{
|
||||||
|
load_file (stringlist, file);
|
||||||
|
g_object_unref (file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GtkWidget *
|
||||||
|
do_listview_words (GtkWidget *do_widget)
|
||||||
|
{
|
||||||
|
if (window == NULL)
|
||||||
|
{
|
||||||
|
GtkWidget *header, *listview, *sw, *vbox, *search_entry, *open_button, *overlay;
|
||||||
|
GtkFilterListModel *filter_model;
|
||||||
|
GtkNoSelection *selection;
|
||||||
|
GtkStringList *stringlist;
|
||||||
|
GtkFilter *filter;
|
||||||
|
GtkExpression *expression;
|
||||||
|
GFile *file;
|
||||||
|
|
||||||
|
file = g_file_new_for_path ("/usr/share/dict/words");
|
||||||
|
if (g_file_query_exists (file, NULL))
|
||||||
|
{
|
||||||
|
stringlist = gtk_string_list_new (NULL);
|
||||||
|
load_file (stringlist, file);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char **words;
|
||||||
|
words = g_strsplit ("lorem ipsum dolor sit amet consectetur adipisci elit sed eiusmod tempor incidunt labore et dolore magna aliqua ut enim ad minim veniam quis nostrud exercitation ullamco laboris nisi ut aliquid ex ea commodi consequat", " ", -1);
|
||||||
|
stringlist = gtk_string_list_new ((const char **) words);
|
||||||
|
g_strfreev (words);
|
||||||
|
}
|
||||||
|
|
||||||
|
filter = gtk_string_filter_new ();
|
||||||
|
expression = gtk_property_expression_new (GTK_TYPE_STRING_OBJECT, NULL, "string");
|
||||||
|
gtk_string_filter_set_expression (GTK_STRING_FILTER (filter), expression);
|
||||||
|
gtk_expression_unref (expression);
|
||||||
|
filter_model = gtk_filter_list_model_new (G_LIST_MODEL (stringlist), filter);
|
||||||
|
gtk_filter_list_model_set_incremental (filter_model, TRUE);
|
||||||
|
|
||||||
|
window = gtk_window_new ();
|
||||||
|
gtk_window_set_default_size (GTK_WINDOW (window), 400, 600);
|
||||||
|
|
||||||
|
header = gtk_header_bar_new ();
|
||||||
|
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
|
||||||
|
open_button = gtk_file_chooser_button_new ("_Open", GTK_FILE_CHOOSER_ACTION_OPEN);
|
||||||
|
g_signal_connect (open_button, "file-set", G_CALLBACK (file_selected_cb), stringlist);
|
||||||
|
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), open_button);
|
||||||
|
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
||||||
|
|
||||||
|
gtk_window_set_display (GTK_WINDOW (window),
|
||||||
|
gtk_widget_get_display (do_widget));
|
||||||
|
g_object_add_weak_pointer (G_OBJECT (window), (gpointer*)&window);
|
||||||
|
|
||||||
|
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||||
|
gtk_window_set_child (GTK_WINDOW (window), vbox);
|
||||||
|
|
||||||
|
search_entry = gtk_search_entry_new ();
|
||||||
|
g_object_bind_property (search_entry, "text", filter, "search", 0);
|
||||||
|
gtk_box_append (GTK_BOX (vbox), search_entry);
|
||||||
|
|
||||||
|
overlay = gtk_overlay_new ();
|
||||||
|
gtk_box_append (GTK_BOX (vbox), overlay);
|
||||||
|
|
||||||
|
progress = gtk_progress_bar_new ();
|
||||||
|
gtk_widget_set_halign (progress, GTK_ALIGN_FILL);
|
||||||
|
gtk_widget_set_valign (progress, GTK_ALIGN_START);
|
||||||
|
gtk_widget_set_hexpand (progress, TRUE);
|
||||||
|
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), progress);
|
||||||
|
|
||||||
|
sw = gtk_scrolled_window_new ();
|
||||||
|
gtk_overlay_set_child (GTK_OVERLAY (overlay), sw);
|
||||||
|
|
||||||
|
listview = gtk_list_view_new_with_factory (
|
||||||
|
gtk_builder_list_item_factory_new_from_bytes (NULL,
|
||||||
|
g_bytes_new_static (factory_text, strlen (factory_text))));
|
||||||
|
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), listview);
|
||||||
|
selection = gtk_no_selection_new (G_LIST_MODEL (filter_model));
|
||||||
|
gtk_list_view_set_model (GTK_LIST_VIEW (listview), G_LIST_MODEL (selection));
|
||||||
|
g_object_unref (selection);
|
||||||
|
|
||||||
|
g_signal_connect (filter_model, "items-changed", G_CALLBACK (update_title_cb), progress);
|
||||||
|
g_signal_connect (filter_model, "notify::pending", G_CALLBACK (update_title_cb), progress);
|
||||||
|
update_title_cb (filter_model);
|
||||||
|
|
||||||
|
g_object_unref (filter_model);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gtk_widget_get_visible (window))
|
||||||
|
gtk_widget_show (window);
|
||||||
|
else
|
||||||
|
gtk_window_destroy (GTK_WINDOW (window));
|
||||||
|
|
||||||
|
return window;
|
||||||
|
}
|
||||||
@@ -24,7 +24,6 @@
|
|||||||
<property name="default-height">600</property>
|
<property name="default-height">600</property>
|
||||||
<child type="titlebar">
|
<child type="titlebar">
|
||||||
<object class="GtkHeaderBar" id="headerbar">
|
<object class="GtkHeaderBar" id="headerbar">
|
||||||
<property name="show-title-buttons">1</property>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton">
|
<object class="GtkButton">
|
||||||
<property name="valign">center</property>
|
<property name="valign">center</property>
|
||||||
|
|||||||
@@ -69,7 +69,6 @@ do_markup (GtkWidget *do_widget)
|
|||||||
g_signal_connect (show_source, "toggled", G_CALLBACK (source_toggled), stack);
|
g_signal_connect (show_source, "toggled", G_CALLBACK (source_toggled), stack);
|
||||||
|
|
||||||
header = gtk_header_bar_new ();
|
header = gtk_header_bar_new ();
|
||||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
|
|
||||||
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), show_source);
|
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), show_source);
|
||||||
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ demos = files([
|
|||||||
'listview_minesweeper.c',
|
'listview_minesweeper.c',
|
||||||
'listview_settings.c',
|
'listview_settings.c',
|
||||||
'listview_weather.c',
|
'listview_weather.c',
|
||||||
|
'listview_words.c',
|
||||||
'markup.c',
|
'markup.c',
|
||||||
'modelbutton.c',
|
'modelbutton.c',
|
||||||
'overlay.c',
|
'overlay.c',
|
||||||
|
|||||||
@@ -4,9 +4,7 @@
|
|||||||
<property name="title" translatable="yes">Model Button</property>
|
<property name="title" translatable="yes">Model Button</property>
|
||||||
<property name="resizable">0</property>
|
<property name="resizable">0</property>
|
||||||
<child type="titlebar">
|
<child type="titlebar">
|
||||||
<object class="GtkHeaderBar">
|
<object class="GtkHeaderBar"/>
|
||||||
<property name="show-title-buttons">1</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
|
|||||||
@@ -392,7 +392,6 @@ do_paint (GtkWidget *toplevel)
|
|||||||
gtk_window_set_child (GTK_WINDOW (window), draw_area);
|
gtk_window_set_child (GTK_WINDOW (window), draw_area);
|
||||||
|
|
||||||
headerbar = gtk_header_bar_new ();
|
headerbar = gtk_header_bar_new ();
|
||||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (headerbar), TRUE);
|
|
||||||
|
|
||||||
colorbutton = gtk_color_button_new ();
|
colorbutton = gtk_color_button_new ();
|
||||||
g_signal_connect (colorbutton, "color-set",
|
g_signal_connect (colorbutton, "color-set",
|
||||||
|
|||||||
@@ -276,7 +276,6 @@ do_peg_solitaire (GtkWidget *do_widget)
|
|||||||
g_signal_connect (restart, "clicked", G_CALLBACK (restart), NULL);
|
g_signal_connect (restart, "clicked", G_CALLBACK (restart), NULL);
|
||||||
|
|
||||||
header = gtk_header_bar_new ();
|
header = gtk_header_bar_new ();
|
||||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
|
|
||||||
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), restart);
|
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), restart);
|
||||||
window = gtk_window_new ();
|
window = gtk_window_new ();
|
||||||
gtk_window_set_display (GTK_WINDOW (window),
|
gtk_window_set_display (GTK_WINDOW (window),
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ do_sidebar (GtkWidget *do_widget)
|
|||||||
gtk_widget_set_size_request (window, 500, 350);
|
gtk_widget_set_size_request (window, 500, 350);
|
||||||
|
|
||||||
header = gtk_header_bar_new ();
|
header = gtk_header_bar_new ();
|
||||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR(header), TRUE);
|
|
||||||
gtk_window_set_titlebar (GTK_WINDOW(window), header);
|
gtk_window_set_titlebar (GTK_WINDOW(window), header);
|
||||||
gtk_window_set_title (GTK_WINDOW(window), "Stack Sidebar");
|
gtk_window_set_title (GTK_WINDOW(window), "Stack Sidebar");
|
||||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||||
|
|||||||
@@ -470,7 +470,6 @@ do_sliding_puzzle (GtkWidget *do_widget)
|
|||||||
g_signal_connect (restart, "clicked", G_CALLBACK (reshuffle), NULL);
|
g_signal_connect (restart, "clicked", G_CALLBACK (reshuffle), NULL);
|
||||||
|
|
||||||
header = gtk_header_bar_new ();
|
header = gtk_header_bar_new ();
|
||||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
|
|
||||||
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), restart);
|
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), restart);
|
||||||
gtk_header_bar_pack_end (GTK_HEADER_BAR (header), tweak);
|
gtk_header_bar_pack_end (GTK_HEADER_BAR (header), tweak);
|
||||||
window = gtk_window_new ();
|
window = gtk_window_new ();
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
<property name="resizable">0</property>
|
<property name="resizable">0</property>
|
||||||
<child type="titlebar">
|
<child type="titlebar">
|
||||||
<object class="GtkHeaderBar" id="header">
|
<object class="GtkHeaderBar" id="header">
|
||||||
<property name="show-title-buttons">1</property>
|
|
||||||
<child type="start">
|
<child type="start">
|
||||||
<object class="GtkToggleButton" id="toggle">
|
<object class="GtkToggleButton" id="toggle">
|
||||||
<property name="label">Cycle</property>
|
<property name="label">Cycle</property>
|
||||||
|
|||||||
@@ -73,7 +73,6 @@ do_video_player (GtkWidget *do_widget)
|
|||||||
gtk_window_set_child (GTK_WINDOW (window), video);
|
gtk_window_set_child (GTK_WINDOW (window), video);
|
||||||
|
|
||||||
title = gtk_header_bar_new ();
|
title = gtk_header_bar_new ();
|
||||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (title), TRUE);
|
|
||||||
gtk_window_set_titlebar (GTK_WINDOW (window), title);
|
gtk_window_set_titlebar (GTK_WINDOW (window), title);
|
||||||
|
|
||||||
open_button = gtk_button_new_with_mnemonic ("_Open");
|
open_button = gtk_button_new_with_mnemonic ("_Open");
|
||||||
|
|||||||
@@ -21,7 +21,6 @@
|
|||||||
<property name="default-height">768</property>
|
<property name="default-height">768</property>
|
||||||
<child type="titlebar">
|
<child type="titlebar">
|
||||||
<object class="GtkHeaderBar" id="header">
|
<object class="GtkHeaderBar" id="header">
|
||||||
<property name="show-title-buttons">1</property>
|
|
||||||
<child type="title">
|
<child type="title">
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
@@ -103,7 +103,6 @@
|
|||||||
<property name="focus-widget">text_view</property>
|
<property name="focus-widget">text_view</property>
|
||||||
<child type="titlebar">
|
<child type="titlebar">
|
||||||
<object class="GtkHeaderBar" id="header">
|
<object class="GtkHeaderBar" id="header">
|
||||||
<property name="show-title-buttons">1</property>
|
|
||||||
<child type="start">
|
<child type="start">
|
||||||
<object class="GtkButton">
|
<object class="GtkButton">
|
||||||
<property name="icon-name">document-open-symbolic</property>
|
<property name="icon-name">document-open-symbolic</property>
|
||||||
|
|||||||
@@ -436,7 +436,6 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
|||||||
<property name="title">GTK Widget Factory</property>
|
<property name="title">GTK Widget Factory</property>
|
||||||
<child type="titlebar">
|
<child type="titlebar">
|
||||||
<object class="GtkHeaderBar" id="headerbar1">
|
<object class="GtkHeaderBar" id="headerbar1">
|
||||||
<property name="show-title-buttons">1</property>
|
|
||||||
<child type="title">
|
<child type="title">
|
||||||
<object class="GtkStackSwitcher" id="stack_switcher">
|
<object class="GtkStackSwitcher" id="stack_switcher">
|
||||||
<property name="stack">toplevel_stack</property>
|
<property name="stack">toplevel_stack</property>
|
||||||
|
|||||||
@@ -1423,7 +1423,6 @@ the search bar below the header bar.
|
|||||||
<property name="default-height">400</property>
|
<property name="default-height">400</property>
|
||||||
<child type="titlebar">
|
<child type="titlebar">
|
||||||
<object class="GtkHeaderBar" id="header">
|
<object class="GtkHeaderBar" id="header">
|
||||||
<property name="show-title-buttons">1</property>
|
|
||||||
<child type="title">
|
<child type="title">
|
||||||
<object class="GtkStackSwitcher" id="tabs">
|
<object class="GtkStackSwitcher" id="tabs">
|
||||||
<property name="stack">stack</property>
|
<property name="stack">stack</property>
|
||||||
@@ -1537,7 +1536,6 @@ GtkMenuButton, GtkRevealer and GtkListBox.
|
|||||||
<property name="default-height">400</property>
|
<property name="default-height">400</property>
|
||||||
<child type="titlebar">
|
<child type="titlebar">
|
||||||
<object class="GtkHeaderBar" id="header">
|
<object class="GtkHeaderBar" id="header">
|
||||||
<property name="show-title-buttons">1</property>
|
|
||||||
<child type="title">
|
<child type="title">
|
||||||
<object class="GtkStackSwitcher" id="tabs">
|
<object class="GtkStackSwitcher" id="tabs">
|
||||||
<property name="stack">stack</property>
|
<property name="stack">stack</property>
|
||||||
|
|||||||
@@ -54,8 +54,9 @@
|
|||||||
<section>
|
<section>
|
||||||
<xi:include href="xml/gtkfilter.xml" />
|
<xi:include href="xml/gtkfilter.xml" />
|
||||||
<xi:include href="xml/gtkcustomfilter.xml" />
|
<xi:include href="xml/gtkcustomfilter.xml" />
|
||||||
<xi:include href="xml/gtkstringfilter.xml" />
|
|
||||||
<xi:include href="xml/gtkmultifilter.xml" />
|
<xi:include href="xml/gtkmultifilter.xml" />
|
||||||
|
<xi:include href="xml/gtkstringfilter.xml" />
|
||||||
|
<xi:include href="xml/gtkfilefilter.xml" />
|
||||||
</section>
|
</section>
|
||||||
<xi:include href="xml/gtkflattenlistmodel.xml" />
|
<xi:include href="xml/gtkflattenlistmodel.xml" />
|
||||||
<xi:include href="xml/gtkmaplistmodel.xml" />
|
<xi:include href="xml/gtkmaplistmodel.xml" />
|
||||||
@@ -74,6 +75,7 @@
|
|||||||
<xi:include href="xml/gtksingleselection.xml" />
|
<xi:include href="xml/gtksingleselection.xml" />
|
||||||
<xi:include href="xml/gtkmultiselection.xml" />
|
<xi:include href="xml/gtkmultiselection.xml" />
|
||||||
</section>
|
</section>
|
||||||
|
<xi:include href="xml/gtkselectionfiltermodel.xml" />
|
||||||
<xi:include href="xml/gtkbookmarklist.xml" />
|
<xi:include href="xml/gtkbookmarklist.xml" />
|
||||||
<xi:include href="xml/gtkdirectorylist.xml" />
|
<xi:include href="xml/gtkdirectorylist.xml" />
|
||||||
<xi:include href="xml/gtkstringlist.xml" />
|
<xi:include href="xml/gtkstringlist.xml" />
|
||||||
@@ -284,7 +286,6 @@
|
|||||||
<xi:include href="xml/gtkfilechoosernative.xml" />
|
<xi:include href="xml/gtkfilechoosernative.xml" />
|
||||||
<xi:include href="xml/gtkfilechooserdialog.xml" />
|
<xi:include href="xml/gtkfilechooserdialog.xml" />
|
||||||
<xi:include href="xml/gtkfilechooserwidget.xml" />
|
<xi:include href="xml/gtkfilechooserwidget.xml" />
|
||||||
<xi:include href="xml/gtkfilefilter.xml" />
|
|
||||||
<xi:include href="xml/gtkfontchooser.xml" />
|
<xi:include href="xml/gtkfontchooser.xml" />
|
||||||
<xi:include href="xml/gtkfontbutton.xml" />
|
<xi:include href="xml/gtkfontbutton.xml" />
|
||||||
<xi:include href="xml/gtkfontchooserwidget.xml" />
|
<xi:include href="xml/gtkfontchooserwidget.xml" />
|
||||||
|
|||||||
@@ -348,6 +348,7 @@ GtkBitset
|
|||||||
gtk_bitset_ref
|
gtk_bitset_ref
|
||||||
gtk_bitset_unref
|
gtk_bitset_unref
|
||||||
gtk_bitset_new_empty
|
gtk_bitset_new_empty
|
||||||
|
gtk_bitset_new_range
|
||||||
gtk_bitset_copy
|
gtk_bitset_copy
|
||||||
<SUBSECTION>
|
<SUBSECTION>
|
||||||
gtk_bitset_contains
|
gtk_bitset_contains
|
||||||
@@ -355,6 +356,9 @@ gtk_bitset_is_empty
|
|||||||
gtk_bitset_equals
|
gtk_bitset_equals
|
||||||
gtk_bitset_get_minimum
|
gtk_bitset_get_minimum
|
||||||
gtk_bitset_get_maximum
|
gtk_bitset_get_maximum
|
||||||
|
gtk_bitset_get_size
|
||||||
|
gtk_bitset_get_size_in_range
|
||||||
|
gtk_bitset_get_nth
|
||||||
<SUBSECTION>
|
<SUBSECTION>
|
||||||
gtk_bitset_remove_all
|
gtk_bitset_remove_all
|
||||||
gtk_bitset_add
|
gtk_bitset_add
|
||||||
@@ -371,7 +375,7 @@ gtk_bitset_subtract
|
|||||||
gtk_bitset_difference
|
gtk_bitset_difference
|
||||||
gtk_bitset_shift_left
|
gtk_bitset_shift_left
|
||||||
gtk_bitset_shift_right
|
gtk_bitset_shift_right
|
||||||
gtk_bitset_slice
|
gtk_bitset_splice
|
||||||
<SUBSECTION>
|
<SUBSECTION>
|
||||||
GtkBitsetIter
|
GtkBitsetIter
|
||||||
gtk_bitset_iter_init_first
|
gtk_bitset_iter_init_first
|
||||||
@@ -419,6 +423,7 @@ gtk_selection_model_get_type
|
|||||||
GtkNoSelection
|
GtkNoSelection
|
||||||
gtk_no_selection_new
|
gtk_no_selection_new
|
||||||
gtk_no_selection_get_model
|
gtk_no_selection_get_model
|
||||||
|
gtk_no_selection_set_model
|
||||||
<SUBSECTION Private>
|
<SUBSECTION Private>
|
||||||
gtk_no_selection_get_type
|
gtk_no_selection_get_type
|
||||||
</SECTION>
|
</SECTION>
|
||||||
@@ -430,6 +435,7 @@ GtkSingleSelection
|
|||||||
GTK_INVALID_LIST_POSITION
|
GTK_INVALID_LIST_POSITION
|
||||||
gtk_single_selection_new
|
gtk_single_selection_new
|
||||||
gtk_single_selection_get_model
|
gtk_single_selection_get_model
|
||||||
|
gtk_single_selection_set_model
|
||||||
gtk_single_selection_get_selected
|
gtk_single_selection_get_selected
|
||||||
gtk_single_selection_set_selected
|
gtk_single_selection_set_selected
|
||||||
gtk_single_selection_get_selected_item
|
gtk_single_selection_get_selected_item
|
||||||
@@ -446,6 +452,8 @@ gtk_single_selection_get_type
|
|||||||
<TITLE>GtkMultiSeledction</TITLE>
|
<TITLE>GtkMultiSeledction</TITLE>
|
||||||
GtkMultiSelection
|
GtkMultiSelection
|
||||||
gtk_multi_selection_new
|
gtk_multi_selection_new
|
||||||
|
gtk_multi_selection_get_model
|
||||||
|
gtk_multi_selection_set_model
|
||||||
<SUBSECTION Private>
|
<SUBSECTION Private>
|
||||||
gtk_multi_selection_get_type
|
gtk_multi_selection_get_type
|
||||||
</SECTION>
|
</SECTION>
|
||||||
@@ -1302,7 +1310,7 @@ gtk_file_chooser_get_current_folder
|
|||||||
<SUBSECTION>
|
<SUBSECTION>
|
||||||
gtk_file_chooser_add_filter
|
gtk_file_chooser_add_filter
|
||||||
gtk_file_chooser_remove_filter
|
gtk_file_chooser_remove_filter
|
||||||
gtk_file_chooser_list_filters
|
gtk_file_chooser_get_filters
|
||||||
gtk_file_chooser_set_filter
|
gtk_file_chooser_set_filter
|
||||||
gtk_file_chooser_get_filter
|
gtk_file_chooser_get_filter
|
||||||
<SUBSECTION>
|
<SUBSECTION>
|
||||||
@@ -1405,18 +1413,13 @@ GtkFileChooserButtonPrivate
|
|||||||
<SECTION>
|
<SECTION>
|
||||||
<FILE>gtkfilefilter</FILE>
|
<FILE>gtkfilefilter</FILE>
|
||||||
GtkFileFilter
|
GtkFileFilter
|
||||||
GtkFileFilterInfo
|
|
||||||
GtkFileFilterFlags
|
|
||||||
GtkFileFilterFunc
|
|
||||||
gtk_file_filter_new
|
gtk_file_filter_new
|
||||||
gtk_file_filter_set_name
|
gtk_file_filter_set_name
|
||||||
gtk_file_filter_get_name
|
gtk_file_filter_get_name
|
||||||
gtk_file_filter_add_mime_type
|
gtk_file_filter_add_mime_type
|
||||||
gtk_file_filter_add_pattern
|
gtk_file_filter_add_pattern
|
||||||
gtk_file_filter_add_pixbuf_formats
|
gtk_file_filter_add_pixbuf_formats
|
||||||
gtk_file_filter_add_custom
|
gtk_file_filter_get_attributes
|
||||||
gtk_file_filter_get_needed
|
|
||||||
gtk_file_filter_filter
|
|
||||||
|
|
||||||
<SUBSECTION Serialization>
|
<SUBSECTION Serialization>
|
||||||
gtk_file_filter_new_from_gvariant
|
gtk_file_filter_new_from_gvariant
|
||||||
@@ -1535,11 +1538,13 @@ gtk_custom_filter_get_type
|
|||||||
<TITLE>GtkFilterListModel</TITLE>
|
<TITLE>GtkFilterListModel</TITLE>
|
||||||
GtkFilterListModel
|
GtkFilterListModel
|
||||||
gtk_filter_list_model_new
|
gtk_filter_list_model_new
|
||||||
gtk_filter_list_model_new_for_type
|
|
||||||
gtk_filter_list_model_set_model
|
gtk_filter_list_model_set_model
|
||||||
gtk_filter_list_model_get_model
|
gtk_filter_list_model_get_model
|
||||||
gtk_filter_list_model_set_filter
|
gtk_filter_list_model_set_filter
|
||||||
gtk_filter_list_model_get_filter
|
gtk_filter_list_model_get_filter
|
||||||
|
gtk_filter_list_model_set_incremental
|
||||||
|
gtk_filter_list_model_get_incremental
|
||||||
|
gtk_filter_list_model_get_pending
|
||||||
<SUBSECTION Standard>
|
<SUBSECTION Standard>
|
||||||
GTK_FILTER_LIST_MODEL
|
GTK_FILTER_LIST_MODEL
|
||||||
GTK_IS_FILTER_LIST_MODEL
|
GTK_IS_FILTER_LIST_MODEL
|
||||||
@@ -2694,7 +2699,6 @@ gtk_size_group_get_type
|
|||||||
<TITLE>GtkSliceListModel</TITLE>
|
<TITLE>GtkSliceListModel</TITLE>
|
||||||
GtkSliceListModel
|
GtkSliceListModel
|
||||||
gtk_slice_list_model_new
|
gtk_slice_list_model_new
|
||||||
gtk_slice_list_model_new_for_type
|
|
||||||
gtk_slice_list_model_set_model
|
gtk_slice_list_model_set_model
|
||||||
gtk_slice_list_model_get_model
|
gtk_slice_list_model_get_model
|
||||||
gtk_slice_list_model_set_offset
|
gtk_slice_list_model_set_offset
|
||||||
@@ -2826,7 +2830,6 @@ gtk_tree_list_row_sorter_get_type
|
|||||||
<TITLE>GtkSortListModel</TITLE>
|
<TITLE>GtkSortListModel</TITLE>
|
||||||
GtkSortListModel
|
GtkSortListModel
|
||||||
gtk_sort_list_model_new
|
gtk_sort_list_model_new
|
||||||
gtk_sort_list_model_new_for_type
|
|
||||||
gtk_sort_list_model_set_sorter
|
gtk_sort_list_model_set_sorter
|
||||||
gtk_sort_list_model_get_sorter
|
gtk_sort_list_model_get_sorter
|
||||||
gtk_sort_list_model_set_model
|
gtk_sort_list_model_set_model
|
||||||
@@ -7606,6 +7609,18 @@ gtk_string_list_take
|
|||||||
gtk_string_list_remove
|
gtk_string_list_remove
|
||||||
gtk_string_list_splice
|
gtk_string_list_splice
|
||||||
gtk_string_list_get_string
|
gtk_string_list_get_string
|
||||||
|
<SUBSECTION>
|
||||||
GtkStringObject
|
GtkStringObject
|
||||||
|
gtk_string_object_new
|
||||||
gtk_string_object_get_string
|
gtk_string_object_get_string
|
||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
||||||
|
<SECTION>
|
||||||
|
<FILE>gtkselectionfiltermodel</FILE>
|
||||||
|
<TITLE>GtkSelectionFilterModel</TITLE>
|
||||||
|
GtkSelectionFilterModel
|
||||||
|
gtk_selection_filter_model_new
|
||||||
|
gtk_selection_filter_model_new_for_type
|
||||||
|
gtk_selection_filter_model_set_model
|
||||||
|
gtk_selection_filter_model_get_model
|
||||||
|
</SECTION>
|
||||||
|
|||||||
@@ -184,6 +184,7 @@ gtk_scrollbar_get_type
|
|||||||
gtk_scrolled_window_get_type
|
gtk_scrolled_window_get_type
|
||||||
gtk_search_bar_get_type
|
gtk_search_bar_get_type
|
||||||
gtk_search_entry_get_type
|
gtk_search_entry_get_type
|
||||||
|
gtk_selection_filter_model_get_type
|
||||||
gtk_selection_model_get_type
|
gtk_selection_model_get_type
|
||||||
gtk_separator_get_type
|
gtk_separator_get_type
|
||||||
gtk_settings_get_type
|
gtk_settings_get_type
|
||||||
|
|||||||
@@ -411,6 +411,7 @@ and gtk_box_append(). You can also reorder box children as necessary.
|
|||||||
The gtk_header_bar_set_show_close_button() function has been renamed to
|
The gtk_header_bar_set_show_close_button() function has been renamed to
|
||||||
the more accurate name gtk_header_bar_set_show_title_buttons(). The
|
the more accurate name gtk_header_bar_set_show_title_buttons(). The
|
||||||
corresponding getter and the property itself have also been renamed.
|
corresponding getter and the property itself have also been renamed.
|
||||||
|
The default value of the property is now %TRUE instead of %FALSE.
|
||||||
|
|
||||||
The gtk_header_bar_set_custom_title() function has been renamed to
|
The gtk_header_bar_set_custom_title() function has been renamed to
|
||||||
the more accurate name gtk_header_bar_set_title_widget(). The
|
the more accurate name gtk_header_bar_set_title_widget(). The
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
<property name="default-height">400</property>
|
<property name="default-height">400</property>
|
||||||
<child type="titlebar">
|
<child type="titlebar">
|
||||||
<object class="GtkHeaderBar" id="header">
|
<object class="GtkHeaderBar" id="header">
|
||||||
<property name="show-title-buttons">1</property>
|
|
||||||
<child type="title">
|
<child type="title">
|
||||||
<object class="GtkStackSwitcher" id="tabs">
|
<object class="GtkStackSwitcher" id="tabs">
|
||||||
<property name="stack">stack</property>
|
<property name="stack">stack</property>
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
<property name="default-height">400</property>
|
<property name="default-height">400</property>
|
||||||
<child type="titlebar">
|
<child type="titlebar">
|
||||||
<object class="GtkHeaderBar" id="header">
|
<object class="GtkHeaderBar" id="header">
|
||||||
<property name="show-title-buttons">1</property>
|
|
||||||
<child type="title">
|
<child type="title">
|
||||||
<object class="GtkStackSwitcher" id="tabs">
|
<object class="GtkStackSwitcher" id="tabs">
|
||||||
<property name="stack">stack</property>
|
<property name="stack">stack</property>
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
<property name="default-height">400</property>
|
<property name="default-height">400</property>
|
||||||
<child type="titlebar">
|
<child type="titlebar">
|
||||||
<object class="GtkHeaderBar" id="header">
|
<object class="GtkHeaderBar" id="header">
|
||||||
<property name="show-title-buttons">1</property>
|
|
||||||
<child type="title">
|
<child type="title">
|
||||||
<object class="GtkStackSwitcher" id="tabs">
|
<object class="GtkStackSwitcher" id="tabs">
|
||||||
<property name="stack">stack</property>
|
<property name="stack">stack</property>
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
<property name="default-height">400</property>
|
<property name="default-height">400</property>
|
||||||
<child type="titlebar">
|
<child type="titlebar">
|
||||||
<object class="GtkHeaderBar" id="header">
|
<object class="GtkHeaderBar" id="header">
|
||||||
<property name="show-title-buttons">1</property>
|
|
||||||
<child type="title">
|
<child type="title">
|
||||||
<object class="GtkStackSwitcher" id="tabs">
|
<object class="GtkStackSwitcher" id="tabs">
|
||||||
<property name="stack">stack</property>
|
<property name="stack">stack</property>
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
<property name="default-height">400</property>
|
<property name="default-height">400</property>
|
||||||
<child type="titlebar">
|
<child type="titlebar">
|
||||||
<object class="GtkHeaderBar" id="header">
|
<object class="GtkHeaderBar" id="header">
|
||||||
<property name="show-title-buttons">1</property>
|
|
||||||
<child type="title">
|
<child type="title">
|
||||||
<object class="GtkStackSwitcher" id="tabs">
|
<object class="GtkStackSwitcher" id="tabs">
|
||||||
<property name="stack">stack</property>
|
<property name="stack">stack</property>
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
<property name="default-height">400</property>
|
<property name="default-height">400</property>
|
||||||
<child type="titlebar">
|
<child type="titlebar">
|
||||||
<object class="GtkHeaderBar" id="header">
|
<object class="GtkHeaderBar" id="header">
|
||||||
<property name="show-title-buttons">1</property>
|
|
||||||
<child type="title">
|
<child type="title">
|
||||||
<object class="GtkStackSwitcher" id="tabs">
|
<object class="GtkStackSwitcher" id="tabs">
|
||||||
<property name="stack">stack</property>
|
<property name="stack">stack</property>
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
<property name="default-height">400</property>
|
<property name="default-height">400</property>
|
||||||
<child type="titlebar">
|
<child type="titlebar">
|
||||||
<object class="GtkHeaderBar" id="header">
|
<object class="GtkHeaderBar" id="header">
|
||||||
<property name="show-title-buttons">1</property>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel" id="lines_label">
|
<object class="GtkLabel" id="lines_label">
|
||||||
<property name="visible">0</property>
|
<property name="visible">0</property>
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ new_window (GApplication *app,
|
|||||||
gtk_window_set_icon_name (GTK_WINDOW (window), "sunny");
|
gtk_window_set_icon_name (GTK_WINDOW (window), "sunny");
|
||||||
|
|
||||||
header = gtk_header_bar_new ();
|
header = gtk_header_bar_new ();
|
||||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
|
|
||||||
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
||||||
|
|
||||||
overlay = gtk_overlay_new ();
|
overlay = gtk_overlay_new ();
|
||||||
|
|||||||
@@ -1184,7 +1184,7 @@ _gdk_wm_protocols_filter (const XEvent *xevent,
|
|||||||
if (timings)
|
if (timings)
|
||||||
timings->drawn_time = frame_drawn_time;
|
timings->drawn_time = frame_drawn_time;
|
||||||
|
|
||||||
if (surface_impl->toplevel->frame_pending)
|
if (!surface_impl->toplevel->frame_still_painting && surface_impl->toplevel->frame_pending)
|
||||||
{
|
{
|
||||||
surface_impl->toplevel->frame_pending = FALSE;
|
surface_impl->toplevel->frame_pending = FALSE;
|
||||||
gdk_surface_thaw_updates (win);
|
gdk_surface_thaw_updates (win);
|
||||||
|
|||||||
+49
-10
@@ -582,6 +582,23 @@ create_legacy_context (GdkDisplay *display,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_XDAMAGE
|
#ifdef HAVE_XDAMAGE
|
||||||
|
static void
|
||||||
|
finish_frame (GdkGLContext *context)
|
||||||
|
{
|
||||||
|
GdkX11GLContext *context_x11 = GDK_X11_GL_CONTEXT (context);
|
||||||
|
GdkSurface *surface = gdk_gl_context_get_surface (context);
|
||||||
|
|
||||||
|
if (context_x11->xdamage == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (context_x11->frame_fence == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
glDeleteSync (context_x11->frame_fence);
|
||||||
|
context_x11->frame_fence = 0;
|
||||||
|
_gdk_x11_surface_set_frame_still_painting (surface, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
bind_context_for_frame_fence (GdkGLContext *context)
|
bind_context_for_frame_fence (GdkGLContext *context)
|
||||||
{
|
{
|
||||||
@@ -628,7 +645,6 @@ on_gl_surface_xevent (GdkGLContext *context,
|
|||||||
GdkX11Display *display_x11)
|
GdkX11Display *display_x11)
|
||||||
{
|
{
|
||||||
GdkX11GLContext *context_x11 = GDK_X11_GL_CONTEXT (context);
|
GdkX11GLContext *context_x11 = GDK_X11_GL_CONTEXT (context);
|
||||||
GdkSurface *surface = gdk_gl_context_get_surface (context);
|
|
||||||
XDamageNotifyEvent *damage_xevent;
|
XDamageNotifyEvent *damage_xevent;
|
||||||
|
|
||||||
if (!context_x11->is_attached)
|
if (!context_x11->is_attached)
|
||||||
@@ -675,9 +691,7 @@ on_gl_surface_xevent (GdkGLContext *context,
|
|||||||
case GL_WAIT_FAILED:
|
case GL_WAIT_FAILED:
|
||||||
if (wait_result == GL_WAIT_FAILED)
|
if (wait_result == GL_WAIT_FAILED)
|
||||||
g_warning ("failed to wait on GL fence associated with last swap buffers call");
|
g_warning ("failed to wait on GL fence associated with last swap buffers call");
|
||||||
glDeleteSync (context_x11->frame_fence);
|
finish_frame (context);
|
||||||
context_x11->frame_fence = 0;
|
|
||||||
_gdk_x11_surface_set_frame_still_painting (surface, FALSE);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* We assume that if the fence hasn't been signaled, that this
|
/* We assume that if the fence hasn't been signaled, that this
|
||||||
@@ -696,6 +710,21 @@ on_gl_surface_xevent (GdkGLContext *context,
|
|||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_surface_state_changed (GdkGLContext *context)
|
||||||
|
{
|
||||||
|
GdkSurface *surface = gdk_gl_context_get_surface (context);
|
||||||
|
|
||||||
|
if ((surface->state & GDK_SURFACE_STATE_WITHDRAWN) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* If we're about to withdraw the surface, then we don't care if the frame is
|
||||||
|
* still getting rendered by the GPU. The compositor is going to remove the surface
|
||||||
|
* from the scene anyway, so wrap up the frame.
|
||||||
|
*/
|
||||||
|
finish_frame (context);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@@ -878,13 +907,23 @@ gdk_x11_gl_context_realize (GdkGLContext *context,
|
|||||||
gdk_x11_surface_get_xid (surface),
|
gdk_x11_surface_get_xid (surface),
|
||||||
XDamageReportRawRectangles);
|
XDamageReportRawRectangles);
|
||||||
if (gdk_x11_display_error_trap_pop (display))
|
if (gdk_x11_display_error_trap_pop (display))
|
||||||
context_x11->xdamage = 0;
|
{
|
||||||
|
context_x11->xdamage = 0;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
g_signal_connect_object (G_OBJECT (display),
|
{
|
||||||
"xevent",
|
g_signal_connect_object (G_OBJECT (display),
|
||||||
G_CALLBACK (on_gl_surface_xevent),
|
"xevent",
|
||||||
context,
|
G_CALLBACK (on_gl_surface_xevent),
|
||||||
G_CONNECT_SWAPPED);
|
context,
|
||||||
|
G_CONNECT_SWAPPED);
|
||||||
|
g_signal_connect_object (G_OBJECT (surface),
|
||||||
|
"notify::state",
|
||||||
|
G_CALLBACK (on_surface_state_changed),
|
||||||
|
context,
|
||||||
|
G_CONNECT_SWAPPED);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
+16
-6
@@ -2241,12 +2241,23 @@ render_cross_fade_node (GskGLRenderer *self,
|
|||||||
{
|
{
|
||||||
GskRenderNode *start_node = gsk_cross_fade_node_get_start_child (node);
|
GskRenderNode *start_node = gsk_cross_fade_node_get_start_child (node);
|
||||||
GskRenderNode *end_node = gsk_cross_fade_node_get_end_child (node);
|
GskRenderNode *end_node = gsk_cross_fade_node_get_end_child (node);
|
||||||
float progress = gsk_cross_fade_node_get_progress (node);
|
const float progress = gsk_cross_fade_node_get_progress (node);
|
||||||
TextureRegion start_region;
|
TextureRegion start_region;
|
||||||
TextureRegion end_region;
|
TextureRegion end_region;
|
||||||
gboolean is_offscreen1, is_offscreen2;
|
gboolean is_offscreen1, is_offscreen2;
|
||||||
OpCrossFade *op;
|
OpCrossFade *op;
|
||||||
|
|
||||||
|
if (progress <= 0)
|
||||||
|
{
|
||||||
|
gsk_gl_renderer_add_render_ops (self, start_node, builder);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (progress >= 1)
|
||||||
|
{
|
||||||
|
gsk_gl_renderer_add_render_ops (self, end_node, builder);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO: We create 2 textures here as big as the cross-fade node, but both the
|
/* TODO: We create 2 textures here as big as the cross-fade node, but both the
|
||||||
* start and the end node might be a lot smaller than that. */
|
* start and the end node might be a lot smaller than that. */
|
||||||
|
|
||||||
@@ -2266,11 +2277,10 @@ render_cross_fade_node (GskGLRenderer *self,
|
|||||||
&end_region, &is_offscreen2,
|
&end_region, &is_offscreen2,
|
||||||
FORCE_OFFSCREEN | RESET_CLIP | RESET_OPACITY))
|
FORCE_OFFSCREEN | RESET_CLIP | RESET_OPACITY))
|
||||||
{
|
{
|
||||||
load_vertex_data_with_region (ops_draw (builder, NULL),
|
const float prev_opacity = ops_set_opacity (builder, builder->current_opacity * progress);
|
||||||
node,
|
gsk_gl_renderer_add_render_ops (self, start_node, builder);
|
||||||
builder,
|
ops_set_opacity (builder, prev_opacity);
|
||||||
&start_region,
|
|
||||||
TRUE);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -295,7 +295,6 @@ gtk_cell_accessible_action_do_action (AtkAction *action,
|
|||||||
GtkCellAccessible *cell = GTK_CELL_ACCESSIBLE (action);
|
GtkCellAccessible *cell = GTK_CELL_ACCESSIBLE (action);
|
||||||
GtkCellAccessibleParent *parent;
|
GtkCellAccessibleParent *parent;
|
||||||
|
|
||||||
cell = GTK_CELL_ACCESSIBLE (action);
|
|
||||||
if (gtk_accessible_get_widget (GTK_ACCESSIBLE (cell)) == NULL)
|
if (gtk_accessible_get_widget (GTK_ACCESSIBLE (cell)) == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ static gunichar
|
|||||||
gtk_password_entry_accessible_get_character_at_offset (AtkText *atk_text,
|
gtk_password_entry_accessible_get_character_at_offset (AtkText *atk_text,
|
||||||
gint offset)
|
gint offset)
|
||||||
{
|
{
|
||||||
GtkText *text = get_text_widget (GTK_ACCESSIBLE (atk_text));
|
GtkText *text;
|
||||||
char *contents, *index;
|
char *contents, *index;
|
||||||
gunichar result;
|
gunichar result;
|
||||||
|
|
||||||
|
|||||||
@@ -133,7 +133,6 @@
|
|||||||
#include <gtk/gtkfontchooserdialog.h>
|
#include <gtk/gtkfontchooserdialog.h>
|
||||||
#include <gtk/gtkfontchooserwidget.h>
|
#include <gtk/gtkfontchooserwidget.h>
|
||||||
#include <gtk/gtkframe.h>
|
#include <gtk/gtkframe.h>
|
||||||
#include <gtk/gtkfunctionslistitemfactory.h>
|
|
||||||
#include <gtk/gtkgesture.h>
|
#include <gtk/gtkgesture.h>
|
||||||
#include <gtk/gtkgestureclick.h>
|
#include <gtk/gtkgestureclick.h>
|
||||||
#include <gtk/gtkgesturedrag.h>
|
#include <gtk/gtkgesturedrag.h>
|
||||||
@@ -214,6 +213,7 @@
|
|||||||
#include <gtk/gtkscrolledwindow.h>
|
#include <gtk/gtkscrolledwindow.h>
|
||||||
#include <gtk/gtksearchbar.h>
|
#include <gtk/gtksearchbar.h>
|
||||||
#include <gtk/gtksearchentry.h>
|
#include <gtk/gtksearchentry.h>
|
||||||
|
#include <gtk/gtkselectionfiltermodel.h>
|
||||||
#include <gtk/gtkselectionmodel.h>
|
#include <gtk/gtkselectionmodel.h>
|
||||||
#include <gtk/gtkseparator.h>
|
#include <gtk/gtkseparator.h>
|
||||||
#include <gtk/gtksettings.h>
|
#include <gtk/gtksettings.h>
|
||||||
@@ -233,6 +233,10 @@
|
|||||||
#include <gtk/gtkslicelistmodel.h>
|
#include <gtk/gtkslicelistmodel.h>
|
||||||
#include <gtk/gtksnapshot.h>
|
#include <gtk/gtksnapshot.h>
|
||||||
#include <gtk/gtksorter.h>
|
#include <gtk/gtksorter.h>
|
||||||
|
#include <gtk/gtksor2listmodel.h>
|
||||||
|
#include <gtk/gtksor3listmodel.h>
|
||||||
|
#include <gtk/gtksor4listmodel.h>
|
||||||
|
#include <gtk/gtksor5listmodel.h>
|
||||||
#include <gtk/gtksortlistmodel.h>
|
#include <gtk/gtksortlistmodel.h>
|
||||||
#include <gtk/gtkstacksidebar.h>
|
#include <gtk/gtkstacksidebar.h>
|
||||||
#include <gtk/gtksizegroup.h>
|
#include <gtk/gtksizegroup.h>
|
||||||
|
|||||||
@@ -1,137 +0,0 @@
|
|||||||
#ifndef __GTK_ARRAY_IMPL_PRIVATE_H__
|
|
||||||
#define __GTK_ARRAY_IMPL_PRIVATE_H__
|
|
||||||
|
|
||||||
|
|
||||||
/* This is a dumbed-down GPtrArray, which takes some stack
|
|
||||||
* space to use. When using this, the general case should always
|
|
||||||
* be that the number of elements is lower than reserved_size.
|
|
||||||
* The GPtrArray should only be used in extreme cases.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
guint reserved_size;
|
|
||||||
guint len;
|
|
||||||
void **stack_space;
|
|
||||||
GPtrArray *ptr_array;
|
|
||||||
|
|
||||||
} GtkArray;
|
|
||||||
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gtk_array_init (GtkArray *self,
|
|
||||||
void **stack_space,
|
|
||||||
guint reserved_size)
|
|
||||||
{
|
|
||||||
self->reserved_size = reserved_size;
|
|
||||||
self->len = 0;
|
|
||||||
self->stack_space = stack_space;
|
|
||||||
self->ptr_array = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void *
|
|
||||||
gtk_array_index (const GtkArray *self,
|
|
||||||
guint index)
|
|
||||||
{
|
|
||||||
g_assert (index < self->len);
|
|
||||||
|
|
||||||
if (G_LIKELY (!self->ptr_array))
|
|
||||||
return self->stack_space[index];
|
|
||||||
|
|
||||||
return g_ptr_array_index (self->ptr_array, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gtk_array_add (GtkArray *self,
|
|
||||||
void *element)
|
|
||||||
{
|
|
||||||
if (G_LIKELY (self->len < self->reserved_size))
|
|
||||||
{
|
|
||||||
self->stack_space[self->len] = element;
|
|
||||||
self->len++;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Need to fall back to the GPtrArray */
|
|
||||||
if (G_UNLIKELY (!self->ptr_array))
|
|
||||||
{
|
|
||||||
self->ptr_array = g_ptr_array_new_full (self->len + 1, NULL);
|
|
||||||
memcpy (self->ptr_array->pdata, self->stack_space, sizeof (void *) * self->len);
|
|
||||||
self->ptr_array->len = self->len;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_ptr_array_add (self->ptr_array, element);
|
|
||||||
self->len++; /* We still count self->len */
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gtk_array_insert (GtkArray *self,
|
|
||||||
guint index,
|
|
||||||
void *element)
|
|
||||||
{
|
|
||||||
if (index >= self->len)
|
|
||||||
{
|
|
||||||
gtk_array_add (self, element);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (G_LIKELY (self->len < self->reserved_size))
|
|
||||||
{
|
|
||||||
memmove (self->stack_space + index + 1, self->stack_space + index,
|
|
||||||
sizeof (void *) * (self->len - index));
|
|
||||||
self->stack_space[index] = element;
|
|
||||||
self->len++;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (G_UNLIKELY (!self->ptr_array))
|
|
||||||
{
|
|
||||||
self->ptr_array = g_ptr_array_new_full (self->len + 1, NULL);
|
|
||||||
memcpy (self->ptr_array->pdata, self->stack_space, sizeof (void *) * self->len);
|
|
||||||
self->ptr_array->len = self->len;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_assert (self->ptr_array);
|
|
||||||
g_ptr_array_insert (self->ptr_array, index, element);
|
|
||||||
self->len++;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
gtk_array_free (GtkArray *self,
|
|
||||||
GDestroyNotify element_free_func)
|
|
||||||
{
|
|
||||||
guint i;
|
|
||||||
|
|
||||||
if (G_LIKELY (!self->ptr_array))
|
|
||||||
{
|
|
||||||
if (element_free_func)
|
|
||||||
{
|
|
||||||
for (i = 0; i < self->len; i++)
|
|
||||||
element_free_func (self->stack_space[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_assert (self->ptr_array);
|
|
||||||
|
|
||||||
if (element_free_func)
|
|
||||||
{
|
|
||||||
for (i = 0; i < self->ptr_array->len; i++)
|
|
||||||
element_free_func (g_ptr_array_index (self->ptr_array, i));
|
|
||||||
}
|
|
||||||
|
|
||||||
g_ptr_array_free (self->ptr_array, TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void **
|
|
||||||
gtk_array_get_data (GtkArray *self)
|
|
||||||
{
|
|
||||||
if (G_LIKELY (!self->ptr_array))
|
|
||||||
return self->stack_space;
|
|
||||||
|
|
||||||
return self->ptr_array->pdata;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
+99
-7
@@ -193,12 +193,82 @@ gtk_bitset_get_maximum (const GtkBitset *self)
|
|||||||
return roaring_bitmap_maximum (&self->roaring);
|
return roaring_bitmap_maximum (&self->roaring);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gtk_bitset_get_size:
|
||||||
|
* @self: a #GtkBitSet
|
||||||
|
*
|
||||||
|
* Gets the number of values that were added to the set.
|
||||||
|
* For example, if the set is empty, 0 is returned.
|
||||||
|
*
|
||||||
|
* Note that this function returns a #guint64, because when all values are
|
||||||
|
* set, the return value is #G_MAXUINT + 1. Unless you are sure this cannot
|
||||||
|
* happen (it can't with #GListModel), be sure to use a 64bit type.
|
||||||
|
*
|
||||||
|
* Returns: The number of values in the set.
|
||||||
|
**/
|
||||||
|
guint64
|
||||||
|
gtk_bitset_get_size (const GtkBitset *self)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (self != NULL, 0);
|
||||||
|
|
||||||
|
return roaring_bitmap_get_cardinality (&self->roaring);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gtk_bitset_get_size_in_range:
|
||||||
|
* @self: a #GtkBitSet
|
||||||
|
* @first: the first element to include
|
||||||
|
* @last: the last element to include
|
||||||
|
*
|
||||||
|
* Gets the number of values that are part of the set from @first to @last
|
||||||
|
* (inclusive).
|
||||||
|
*
|
||||||
|
* Note that this function returns a #guint64, because when all values are
|
||||||
|
* set, the return value is #G_MAXUINT + 1. Unless you are sure this cannot
|
||||||
|
* happen (it can't with #GListModel), be sure to use a 64bit type.
|
||||||
|
*
|
||||||
|
* Returns: The number of values in the set from @first to @last.
|
||||||
|
**/
|
||||||
|
guint64
|
||||||
|
gtk_bitset_get_size_in_range (const GtkBitset *self,
|
||||||
|
guint first,
|
||||||
|
guint last)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (self != NULL, 0);
|
||||||
|
g_return_val_if_fail (last >= first, 0);
|
||||||
|
|
||||||
|
return roaring_bitmap_range_cardinality (&self->roaring, first, ((uint64_t) last) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gtk_bitset_get_nth:
|
||||||
|
* @self: a #GtkBitset
|
||||||
|
* @nth: index of the item to get
|
||||||
|
*
|
||||||
|
* Returns the value of the @nth item in self.
|
||||||
|
*
|
||||||
|
* If @nth is >= the size of @self, 0 is returned.
|
||||||
|
*
|
||||||
|
* Returns: the value of the @nth item in @self
|
||||||
|
**/
|
||||||
|
guint
|
||||||
|
gtk_bitset_get_nth (const GtkBitset *self,
|
||||||
|
guint nth)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
if (!roaring_bitmap_select (&self->roaring, nth, &result))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gtk_bitset_new_empty:
|
* gtk_bitset_new_empty:
|
||||||
*
|
*
|
||||||
* Creates a new empty bitset.
|
* Creates a new empty bitset.
|
||||||
*
|
*
|
||||||
* Returns: A new empty bitset.
|
* Returns: A new empty bitset
|
||||||
**/
|
**/
|
||||||
GtkBitset *
|
GtkBitset *
|
||||||
gtk_bitset_new_empty (void)
|
gtk_bitset_new_empty (void)
|
||||||
@@ -214,6 +284,28 @@ gtk_bitset_new_empty (void)
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gtk_bitset_new_range:
|
||||||
|
* @start: first value to add
|
||||||
|
* @n_items: number of consecutive values to add
|
||||||
|
*
|
||||||
|
* Creates a bitset with the given range set.
|
||||||
|
*
|
||||||
|
* Returns: A new bitset
|
||||||
|
**/
|
||||||
|
GtkBitset *
|
||||||
|
gtk_bitset_new_range (guint start,
|
||||||
|
guint n_items)
|
||||||
|
{
|
||||||
|
GtkBitset *self;
|
||||||
|
|
||||||
|
self = gtk_bitset_new_empty ();
|
||||||
|
|
||||||
|
gtk_bitset_add_range (self, start, n_items);
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gtk_bitset_copy:
|
* gtk_bitset_copy:
|
||||||
* @self: a #GtkBitset
|
* @self: a #GtkBitset
|
||||||
@@ -615,7 +707,7 @@ gtk_bitset_shift_right (GtkBitset *self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gtk_bitset_slice:
|
* gtk_bitset_splice:
|
||||||
* @self: a #GtkBitset
|
* @self: a #GtkBitset
|
||||||
* @position: position at which to slice
|
* @position: position at which to slice
|
||||||
* @removed: number of values to remove
|
* @removed: number of values to remove
|
||||||
@@ -633,10 +725,10 @@ gtk_bitset_shift_right (GtkBitset *self,
|
|||||||
* up space that can then be filled.
|
* up space that can then be filled.
|
||||||
**/
|
**/
|
||||||
void
|
void
|
||||||
gtk_bitset_slice (GtkBitset *self,
|
gtk_bitset_splice (GtkBitset *self,
|
||||||
guint position,
|
guint position,
|
||||||
guint removed,
|
guint removed,
|
||||||
guint added)
|
guint added)
|
||||||
{
|
{
|
||||||
g_return_if_fail (self != NULL);
|
g_return_if_fail (self != NULL);
|
||||||
/* overflow */
|
/* overflow */
|
||||||
@@ -650,7 +742,7 @@ gtk_bitset_slice (GtkBitset *self,
|
|||||||
GtkBitset *shift = gtk_bitset_copy (self);
|
GtkBitset *shift = gtk_bitset_copy (self);
|
||||||
|
|
||||||
gtk_bitset_remove_range (shift, 0, position);
|
gtk_bitset_remove_range (shift, 0, position);
|
||||||
gtk_bitset_remove_range (self, position, G_MAXUINT - position + 1);
|
gtk_bitset_remove_range_closed (self, position, G_MAXUINT);
|
||||||
if (added > removed)
|
if (added > removed)
|
||||||
gtk_bitset_shift_right (shift, added - removed);
|
gtk_bitset_shift_right (shift, added - removed);
|
||||||
else
|
else
|
||||||
|
|||||||
+13
-1
@@ -48,6 +48,15 @@ GDK_AVAILABLE_IN_ALL
|
|||||||
gboolean gtk_bitset_equals (const GtkBitset *self,
|
gboolean gtk_bitset_equals (const GtkBitset *self,
|
||||||
const GtkBitset *other);
|
const GtkBitset *other);
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
|
guint64 gtk_bitset_get_size (const GtkBitset *self);
|
||||||
|
GDK_AVAILABLE_IN_ALL
|
||||||
|
guint64 gtk_bitset_get_size_in_range (const GtkBitset *self,
|
||||||
|
guint first,
|
||||||
|
guint last);
|
||||||
|
GDK_AVAILABLE_IN_ALL
|
||||||
|
guint gtk_bitset_get_nth (const GtkBitset *self,
|
||||||
|
guint nth);
|
||||||
|
GDK_AVAILABLE_IN_ALL
|
||||||
guint gtk_bitset_get_minimum (const GtkBitset *self);
|
guint gtk_bitset_get_minimum (const GtkBitset *self);
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
guint gtk_bitset_get_maximum (const GtkBitset *self);
|
guint gtk_bitset_get_maximum (const GtkBitset *self);
|
||||||
@@ -56,6 +65,9 @@ GDK_AVAILABLE_IN_ALL
|
|||||||
GtkBitset * gtk_bitset_new_empty (void);
|
GtkBitset * gtk_bitset_new_empty (void);
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
GtkBitset * gtk_bitset_copy (const GtkBitset *self);
|
GtkBitset * gtk_bitset_copy (const GtkBitset *self);
|
||||||
|
GDK_AVAILABLE_IN_ALL
|
||||||
|
GtkBitset * gtk_bitset_new_range (guint start,
|
||||||
|
guint n_items);
|
||||||
|
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
void gtk_bitset_remove_all (GtkBitset *self);
|
void gtk_bitset_remove_all (GtkBitset *self);
|
||||||
@@ -113,7 +125,7 @@ GDK_AVAILABLE_IN_ALL
|
|||||||
void gtk_bitset_shift_right (GtkBitset *self,
|
void gtk_bitset_shift_right (GtkBitset *self,
|
||||||
guint amount);
|
guint amount);
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
void gtk_bitset_slice (GtkBitset *self,
|
void gtk_bitset_splice (GtkBitset *self,
|
||||||
guint position,
|
guint position,
|
||||||
guint removed,
|
guint removed,
|
||||||
guint added);
|
guint added);
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION:gtkbuilderlistitemfactory
|
* SECTION:gtkbuilderlistitemfactory
|
||||||
* @Tiitle: GtkBuilderListItemFactory
|
* @Title: GtkBuilderListItemFactory
|
||||||
* @Short_description: A listitem factory using ui files
|
* @Short_description: A listitem factory using ui files
|
||||||
*
|
*
|
||||||
* #GtkBuilderListItemFactory is a #GtkListItemFactory that creates
|
* #GtkBuilderListItemFactory is a #GtkListItemFactory that creates
|
||||||
|
|||||||
+2
-2
@@ -940,7 +940,7 @@ header_drag_end (GtkGestureDrag *gesture,
|
|||||||
|
|
||||||
column = g_list_model_get_item (G_LIST_MODEL (self->columns), self->drag_pos);
|
column = g_list_model_get_item (G_LIST_MODEL (self->columns), self->drag_pos);
|
||||||
header = gtk_column_view_column_get_header (column);
|
header = gtk_column_view_column_get_header (column);
|
||||||
gtk_style_context_remove_class (gtk_widget_get_style_context (header), "dnd");
|
gtk_widget_remove_css_class (header, "dnd");
|
||||||
|
|
||||||
sequence = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture));
|
sequence = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture));
|
||||||
if (!gtk_gesture_handles_sequence (GTK_GESTURE (gesture), sequence))
|
if (!gtk_gesture_handles_sequence (GTK_GESTURE (gesture), sequence))
|
||||||
@@ -1027,7 +1027,7 @@ header_drag_update (GtkGestureDrag *gesture,
|
|||||||
header = gtk_column_view_column_get_header (column);
|
header = gtk_column_view_column_get_header (column);
|
||||||
|
|
||||||
gtk_widget_insert_after (header, self->header, gtk_widget_get_last_child (self->header));
|
gtk_widget_insert_after (header, self->header, gtk_widget_get_last_child (self->header));
|
||||||
gtk_style_context_add_class (gtk_widget_get_style_context (header), "dnd");
|
gtk_widget_add_css_class (header, "dnd");
|
||||||
|
|
||||||
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
|
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
|
||||||
if (!gtk_widget_has_focus (GTK_WIDGET (self)))
|
if (!gtk_widget_has_focus (GTK_WIDGET (self)))
|
||||||
|
|||||||
+13
-15
@@ -391,9 +391,9 @@ gtk_css_provider_init (GtkCssProvider *css_provider)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
verify_tree_match_results (GtkCssProvider *provider,
|
verify_tree_match_results (GtkCssProvider *provider,
|
||||||
GtkCssNode *node,
|
GtkCssNode *node,
|
||||||
GtkArray *tree_rules)
|
GtkCssSelectorMatches *tree_rules)
|
||||||
{
|
{
|
||||||
#ifdef VERIFY_TREE
|
#ifdef VERIFY_TREE
|
||||||
GtkCssProviderPrivate *priv = gtk_css_provider_get_instance_private (provider);
|
GtkCssProviderPrivate *priv = gtk_css_provider_get_instance_private (provider);
|
||||||
@@ -407,9 +407,9 @@ verify_tree_match_results (GtkCssProvider *provider,
|
|||||||
|
|
||||||
ruleset = &g_array_index (priv->rulesets, GtkCssRuleset, i);
|
ruleset = &g_array_index (priv->rulesets, GtkCssRuleset, i);
|
||||||
|
|
||||||
for (j = 0; j < tree_rules->len; j++)
|
for (j = 0; j < gtk_css_selector_matches_get_size (tree_rules); j++)
|
||||||
{
|
{
|
||||||
if (ruleset == gtk_array_index (tree_rules, j))
|
if (ruleset == gtk_css_selector_matches_get (tree_rules, j))
|
||||||
{
|
{
|
||||||
found = TRUE;
|
found = TRUE;
|
||||||
break;
|
break;
|
||||||
@@ -459,22 +459,21 @@ gtk_css_style_provider_lookup (GtkStyleProvider *provider,
|
|||||||
GtkCssRuleset *ruleset;
|
GtkCssRuleset *ruleset;
|
||||||
guint j;
|
guint j;
|
||||||
int i;
|
int i;
|
||||||
GtkArray tree_rules_array;
|
GtkCssSelectorMatches tree_rules;
|
||||||
GtkCssRuleset *rules_stack[32];
|
|
||||||
|
|
||||||
if (_gtk_css_selector_tree_is_empty (priv->tree))
|
if (_gtk_css_selector_tree_is_empty (priv->tree))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
gtk_array_init (&tree_rules_array, (void**)rules_stack, 32);
|
gtk_css_selector_matches_init (&tree_rules);
|
||||||
_gtk_css_selector_tree_match_all (priv->tree, filter, node, &tree_rules_array);
|
_gtk_css_selector_tree_match_all (priv->tree, filter, node, &tree_rules);
|
||||||
|
|
||||||
if (tree_rules_array.len > 0)
|
if (!gtk_css_selector_matches_is_empty (&tree_rules))
|
||||||
{
|
{
|
||||||
verify_tree_match_results (css_provider, node, &tree_rules_array);
|
verify_tree_match_results (css_provider, node, &tree_rules);
|
||||||
|
|
||||||
for (i = tree_rules_array.len - 1; i >= 0; i--)
|
for (i = gtk_css_selector_matches_get_size (&tree_rules) - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
ruleset = gtk_array_index (&tree_rules_array, i);
|
ruleset = gtk_css_selector_matches_get (&tree_rules, i);
|
||||||
|
|
||||||
if (ruleset->styles == NULL)
|
if (ruleset->styles == NULL)
|
||||||
continue;
|
continue;
|
||||||
@@ -493,9 +492,8 @@ gtk_css_style_provider_lookup (GtkStyleProvider *provider,
|
|||||||
ruleset->styles[j].value);
|
ruleset->styles[j].value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gtk_array_free (&tree_rules_array, NULL);
|
|
||||||
}
|
}
|
||||||
|
gtk_css_selector_matches_clear (&tree_rules);
|
||||||
|
|
||||||
if (change)
|
if (change)
|
||||||
*change = gtk_css_selector_tree_get_change_all (priv->tree, filter, node);
|
*change = gtk_css_selector_tree_get_change_all (priv->tree, filter, node);
|
||||||
|
|||||||
+17
-20
@@ -24,7 +24,6 @@
|
|||||||
|
|
||||||
#include "gtkcssprovider.h"
|
#include "gtkcssprovider.h"
|
||||||
#include "gtkstylecontextprivate.h"
|
#include "gtkstylecontextprivate.h"
|
||||||
#include "gtkarrayimplprivate.h"
|
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#if defined(_MSC_VER) && _MSC_VER >= 1500
|
#if defined(_MSC_VER) && _MSC_VER >= 1500
|
||||||
@@ -152,14 +151,14 @@ gtk_css_selector_tree_get_matches (const GtkCssSelectorTree *tree)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_array_insert_sorted (GtkArray *array,
|
gtk_css_selector_matches_insert_sorted (GtkCssSelectorMatches *matches,
|
||||||
gpointer data)
|
gpointer data)
|
||||||
{
|
{
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
for (i = 0; i < array->len; i++)
|
for (i = 0; i < gtk_css_selector_matches_get_size (matches); i++)
|
||||||
{
|
{
|
||||||
gpointer elem = gtk_array_index (array, i);
|
gpointer elem = gtk_css_selector_matches_get (matches, i);
|
||||||
|
|
||||||
if (data == elem)
|
if (data == elem)
|
||||||
return;
|
return;
|
||||||
@@ -168,7 +167,7 @@ gtk_array_insert_sorted (GtkArray *array,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
gtk_array_insert (array, i, data);
|
gtk_css_selector_matches_splice (matches, i, 0, (gpointer[1]) { data }, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline gboolean
|
static inline gboolean
|
||||||
@@ -1877,7 +1876,7 @@ gtk_css_selector_tree_get_change (const GtkCssSelectorTree *tree,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_css_selector_tree_found_match (const GtkCssSelectorTree *tree,
|
gtk_css_selector_tree_found_match (const GtkCssSelectorTree *tree,
|
||||||
GtkArray *results)
|
GtkCssSelectorMatches *results)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
gpointer *matches;
|
gpointer *matches;
|
||||||
@@ -1887,7 +1886,7 @@ gtk_css_selector_tree_found_match (const GtkCssSelectorTree *tree,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; matches[i] != NULL; i++)
|
for (i = 0; matches[i] != NULL; i++)
|
||||||
gtk_array_insert_sorted (results, matches[i]);
|
gtk_css_selector_matches_insert_sorted (results, matches[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@@ -1895,7 +1894,7 @@ gtk_css_selector_tree_match (const GtkCssSelectorTree *tree,
|
|||||||
const GtkCountingBloomFilter *filter,
|
const GtkCountingBloomFilter *filter,
|
||||||
gboolean match_filter,
|
gboolean match_filter,
|
||||||
GtkCssNode *node,
|
GtkCssNode *node,
|
||||||
GtkArray *results)
|
GtkCssSelectorMatches *results)
|
||||||
{
|
{
|
||||||
const GtkCssSelectorTree *prev;
|
const GtkCssSelectorTree *prev;
|
||||||
GtkCssNode *child;
|
GtkCssNode *child;
|
||||||
@@ -1932,7 +1931,7 @@ void
|
|||||||
_gtk_css_selector_tree_match_all (const GtkCssSelectorTree *tree,
|
_gtk_css_selector_tree_match_all (const GtkCssSelectorTree *tree,
|
||||||
const GtkCountingBloomFilter *filter,
|
const GtkCountingBloomFilter *filter,
|
||||||
GtkCssNode *node,
|
GtkCssNode *node,
|
||||||
GtkArray *out_tree_rules)
|
GtkCssSelectorMatches *out_tree_rules)
|
||||||
{
|
{
|
||||||
const GtkCssSelectorTree *iter;
|
const GtkCssSelectorTree *iter;
|
||||||
|
|
||||||
@@ -2117,8 +2116,7 @@ subdivide_infos (GByteArray *array,
|
|||||||
GHashTableIter iter;
|
GHashTableIter iter;
|
||||||
guint max_count;
|
guint max_count;
|
||||||
gpointer key, value;
|
gpointer key, value;
|
||||||
void *exact_matches_stack[8];
|
GtkCssSelectorMatches exact_matches;
|
||||||
GtkArray exact_matches_array;
|
|
||||||
gint32 res;
|
gint32 res;
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
@@ -2160,7 +2158,7 @@ subdivide_infos (GByteArray *array,
|
|||||||
matched_infos = g_alloca (sizeof (GtkCssSelectorRuleSetInfo *) * n_infos);
|
matched_infos = g_alloca (sizeof (GtkCssSelectorRuleSetInfo *) * n_infos);
|
||||||
remaining_infos = g_alloca (sizeof (GtkCssSelectorRuleSetInfo *) * n_infos);
|
remaining_infos = g_alloca (sizeof (GtkCssSelectorRuleSetInfo *) * n_infos);
|
||||||
|
|
||||||
gtk_array_init (&exact_matches_array, (void**)exact_matches_stack, 8);
|
gtk_css_selector_matches_init (&exact_matches);
|
||||||
for (i = 0; i < n_infos; i++)
|
for (i = 0; i < n_infos; i++)
|
||||||
{
|
{
|
||||||
GtkCssSelectorRuleSetInfo *info = infos[i];
|
GtkCssSelectorRuleSetInfo *info = infos[i];
|
||||||
@@ -2171,7 +2169,7 @@ subdivide_infos (GByteArray *array,
|
|||||||
if (info->current_selector == NULL)
|
if (info->current_selector == NULL)
|
||||||
{
|
{
|
||||||
/* Matches current node */
|
/* Matches current node */
|
||||||
gtk_array_add (&exact_matches_array, info->match);
|
gtk_css_selector_matches_append (&exact_matches, info->match);
|
||||||
if (info->selector_match != NULL)
|
if (info->selector_match != NULL)
|
||||||
*info->selector_match = GUINT_TO_POINTER (tree_offset);
|
*info->selector_match = GUINT_TO_POINTER (tree_offset);
|
||||||
}
|
}
|
||||||
@@ -2188,17 +2186,16 @@ subdivide_infos (GByteArray *array,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exact_matches_array.len > 0)
|
if (!gtk_css_selector_matches_is_empty (&exact_matches))
|
||||||
{
|
{
|
||||||
gtk_array_add (&exact_matches_array, NULL); /* Null terminate */
|
gtk_css_selector_matches_append (&exact_matches, NULL); /* Null terminate */
|
||||||
res = array->len;
|
res = array->len;
|
||||||
g_byte_array_append (array, (guint8 *)gtk_array_get_data (&exact_matches_array),
|
g_byte_array_append (array, (guint8 *) gtk_css_selector_matches_get_data (&exact_matches),
|
||||||
exact_matches_array.len * sizeof (gpointer));
|
gtk_css_selector_matches_get_size (&exact_matches) * sizeof (gpointer));
|
||||||
|
|
||||||
gtk_array_free (&exact_matches_array, NULL);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
res = GTK_CSS_SELECTOR_TREE_EMPTY_OFFSET;
|
res = GTK_CSS_SELECTOR_TREE_EMPTY_OFFSET;
|
||||||
|
gtk_css_selector_matches_clear (&exact_matches);
|
||||||
get_tree (array, tree_offset)->matches_offset = res;
|
get_tree (array, tree_offset)->matches_offset = res;
|
||||||
|
|
||||||
res = subdivide_infos (array, matched_infos, n_matched, tree_offset);
|
res = subdivide_infos (array, matched_infos, n_matched, tree_offset);
|
||||||
|
|||||||
@@ -21,7 +21,12 @@
|
|||||||
#include "gtk/gtkcountingbloomfilterprivate.h"
|
#include "gtk/gtkcountingbloomfilterprivate.h"
|
||||||
#include "gtk/gtkcsstypesprivate.h"
|
#include "gtk/gtkcsstypesprivate.h"
|
||||||
#include "gtk/gtkcssparserprivate.h"
|
#include "gtk/gtkcssparserprivate.h"
|
||||||
#include "gtk/gtkarrayimplprivate.h"
|
|
||||||
|
#define GTK_VECTOR_ELEMENT_TYPE gpointer
|
||||||
|
#define GTK_VECTOR_TYPE_NAME GtkCssSelectorMatches
|
||||||
|
#define GTK_VECTOR_NAME gtk_css_selector_matches
|
||||||
|
#define GTK_VECTOR_PREALLOC 32
|
||||||
|
#include "gtk/gtkvectorimpl.c"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
@@ -45,8 +50,8 @@ int _gtk_css_selector_compare (const GtkCssSelector *a,
|
|||||||
void _gtk_css_selector_tree_free (GtkCssSelectorTree *tree);
|
void _gtk_css_selector_tree_free (GtkCssSelectorTree *tree);
|
||||||
void _gtk_css_selector_tree_match_all (const GtkCssSelectorTree *tree,
|
void _gtk_css_selector_tree_match_all (const GtkCssSelectorTree *tree,
|
||||||
const GtkCountingBloomFilter *filter,
|
const GtkCountingBloomFilter *filter,
|
||||||
GtkCssNode *node,
|
GtkCssNode *node,
|
||||||
GtkArray *out_tree_rules);
|
GtkCssSelectorMatches *out_tree_rules);
|
||||||
GtkCssChange gtk_css_selector_tree_get_change_all (const GtkCssSelectorTree *tree,
|
GtkCssChange gtk_css_selector_tree_get_change_all (const GtkCssSelectorTree *tree,
|
||||||
const GtkCountingBloomFilter *filter,
|
const GtkCountingBloomFilter *filter,
|
||||||
GtkCssNode *node);
|
GtkCssNode *node);
|
||||||
|
|||||||
@@ -321,7 +321,7 @@ gtk_custom_paper_unix_dialog_init (GtkCustomPaperUnixDialog *dialog)
|
|||||||
g_list_store_append (printer_list_list, printer_list);
|
g_list_store_append (printer_list_list, printer_list);
|
||||||
g_object_unref (printer_list);
|
g_object_unref (printer_list);
|
||||||
|
|
||||||
full_list = G_LIST_MODEL (gtk_flatten_list_model_new (GTK_TYPE_PRINTER, G_LIST_MODEL (printer_list_list)));
|
full_list = G_LIST_MODEL (gtk_flatten_list_model_new (G_LIST_MODEL (printer_list_list)));
|
||||||
g_object_unref (printer_list_list);
|
g_object_unref (printer_list_list);
|
||||||
|
|
||||||
filter = gtk_custom_filter_new (match_func, NULL, NULL);
|
filter = gtk_custom_filter_new (match_func, NULL, NULL);
|
||||||
|
|||||||
@@ -224,7 +224,7 @@ gtk_drop_controller_motion_class_init (GtkDropControllerMotionClass *klass)
|
|||||||
props[PROP_CONTAINS_POINTER] =
|
props[PROP_CONTAINS_POINTER] =
|
||||||
g_param_spec_boolean ("contains-pointer",
|
g_param_spec_boolean ("contains-pointer",
|
||||||
P_("Contains Pointer"),
|
P_("Contains Pointer"),
|
||||||
P_("Whether the pointer is inthe controllers widget or a descendant"),
|
P_("Whether the pointer is in the controllers widget or a descendant"),
|
||||||
FALSE,
|
FALSE,
|
||||||
G_PARAM_READABLE);
|
G_PARAM_READABLE);
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -943,7 +943,7 @@ gtk_drop_down_set_from_strings (GtkDropDown *self,
|
|||||||
|
|
||||||
set_default_factory (self);
|
set_default_factory (self);
|
||||||
|
|
||||||
model = G_LIST_MODEL (gtk_string_list_new ((const char **)texts));
|
model = G_LIST_MODEL (gtk_string_list_new (texts));
|
||||||
gtk_drop_down_set_model (self, model);
|
gtk_drop_down_set_model (self, model);
|
||||||
g_object_unref (model);
|
g_object_unref (model);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -221,7 +221,7 @@ gtk_event_controller_motion_class_init (GtkEventControllerMotionClass *klass)
|
|||||||
props[PROP_CONTAINS_POINTER] =
|
props[PROP_CONTAINS_POINTER] =
|
||||||
g_param_spec_boolean ("contains-pointer",
|
g_param_spec_boolean ("contains-pointer",
|
||||||
P_("Contains Pointer"),
|
P_("Contains Pointer"),
|
||||||
P_("Whether the pointer is inthe controllers widget or a descendant"),
|
P_("Whether the pointer is in the controllers widget or a descendant"),
|
||||||
FALSE,
|
FALSE,
|
||||||
G_PARAM_READABLE);
|
G_PARAM_READABLE);
|
||||||
|
|
||||||
|
|||||||
+44
-11
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright © 2019 Benjamin Otte
|
* Copyright © 2019 Benjamin Otte
|
||||||
*
|
*
|
||||||
@@ -28,18 +29,50 @@
|
|||||||
* @Short_description: Expressions to values
|
* @Short_description: Expressions to values
|
||||||
* @Title: GtkExpression
|
* @Title: GtkExpression
|
||||||
*
|
*
|
||||||
* GtkExpression provides a way to describe references to #GValues.
|
* GtkExpression provides a way to describe references to values.
|
||||||
*
|
*
|
||||||
* An expression needs to be "evaluated" to obtain the value that it currently refers
|
* An important aspect of expressions is that the value can be obtained
|
||||||
* to. An evaluation always happens in the context of a current object called `this`
|
* from a source that is several steps away. For example, an expression
|
||||||
* (it mirrors the behavior of object-oriented languages), which may or may not
|
* may describe ‘the value of property A of @object1, which is itself the
|
||||||
* influence the result of the evaluation. Use gtk_expression_evaluate() for
|
* value of a property of @object2’. And @object1 may not even exist yet
|
||||||
* evaluating an expression.
|
* at the time that the expression is created. This is contrast to GObject
|
||||||
|
* property bindings, which can only create direct connections between
|
||||||
|
* the properties of two objects that must both exist for the duration
|
||||||
|
* of the binding.
|
||||||
|
*
|
||||||
|
* An expression needs to be "evaluated" to obtain the value that it currently
|
||||||
|
* refers to. An evaluation always happens in the context of a current object
|
||||||
|
* called `this` (it mirrors the behavior of object-oriented languages),
|
||||||
|
* which may or may not influence the result of the evaluation. Use
|
||||||
|
* gtk_expression_evaluate() for evaluating an expression.
|
||||||
*
|
*
|
||||||
* Various methods for defining expressions exist, from simple constants via
|
* Various methods for defining expressions exist, from simple constants via
|
||||||
* gtk_constant_expression_new() to looking up properties in a #GObject (even
|
* gtk_constant_expression_new() to looking up properties in a #GObject (even
|
||||||
* recursively) via gtk_property_expression_new() or providing custom functions to
|
* recursively) via gtk_property_expression_new() or providing custom functions
|
||||||
* transform and combine expressions via gtk_closure_expression_new().
|
* to transform and combine expressions via gtk_closure_expression_new().
|
||||||
|
*
|
||||||
|
* Here is an example of a complex expression:
|
||||||
|
* |[
|
||||||
|
* color_expr = gtk_property_expression_new (GTK_TYPE_LIST_ITEM,
|
||||||
|
* NULL, "item");
|
||||||
|
* expression = gtk_property_expression_new (GTK_TYPE_COLOR,
|
||||||
|
* color_expr,
|
||||||
|
* "name");
|
||||||
|
* ]|
|
||||||
|
* when evaluated with `this` being a GtkListItem, it will obtain the
|
||||||
|
* "item" property from the GtkListItem, and then obtain the "name" property
|
||||||
|
* from the resulting object (which is assumed to be of type GTK_TYPE_COLOR).
|
||||||
|
*
|
||||||
|
* A more concise way to describe this would be
|
||||||
|
* |[
|
||||||
|
* this->item->name
|
||||||
|
* ]|
|
||||||
|
*
|
||||||
|
* The most likely place where you will encounter expressions is in the context
|
||||||
|
* of list models and list widgets using them. For example, #GtkDropDown is
|
||||||
|
* evaluating a GtkExpression to obtain strings from the items in its model
|
||||||
|
* that it can then use to match against the contents of its search entry.
|
||||||
|
* #GtkStringFilter is using a GtkExpression for a similar reason.
|
||||||
*
|
*
|
||||||
* By default, expressions are not paying attention to changes and evaluation is
|
* By default, expressions are not paying attention to changes and evaluation is
|
||||||
* just a snapshot of the current state at a given time. To get informed about
|
* just a snapshot of the current state at a given time. To get informed about
|
||||||
@@ -1537,12 +1570,12 @@ GTK_DEFINE_EXPRESSION_TYPE (GtkCClosureExpression,
|
|||||||
/**
|
/**
|
||||||
* gtk_cclosure_expression_new:
|
* gtk_cclosure_expression_new:
|
||||||
* @value_type: the type of the value that this expression evaluates to
|
* @value_type: the type of the value that this expression evaluates to
|
||||||
* @marshal: (scope call): marshaller used for creating a closure
|
* @marshal: (scope call) (nullable): marshaller used for creating a closure
|
||||||
* @n_params: the number of params needed for evaluating @closure
|
* @n_params: the number of params needed for evaluating @closure
|
||||||
* @params: (array length=n_params) (transfer full): expressions for each parameter
|
* @params: (array length=n_params) (transfer full): expressions for each parameter
|
||||||
* @callback_func: (scope notified) (closure user_data) (destroy user_destroy): callback used for creating a closure
|
* @callback_func: (scope notified) (closure user_data) (destroy user_destroy): callback used for creating a closure
|
||||||
* @user_data: user data used for creating a closure
|
* @user_data: (nullable): user data used for creating a closure
|
||||||
* @user_destroy: destroy notify for @user_data
|
* @user_destroy: (nullable): destroy notify for @user_data
|
||||||
*
|
*
|
||||||
* This function is a variant of gtk_closure_expression_new() that
|
* This function is a variant of gtk_closure_expression_new() that
|
||||||
* creates a #GClosure by calling gtk_cclosure_new() with the given
|
* creates a #GClosure by calling gtk_cclosure_new() with the given
|
||||||
|
|||||||
+50
-15
@@ -168,6 +168,38 @@ gtk_file_chooser_default_init (GtkFileChooserInterface *iface)
|
|||||||
FALSE,
|
FALSE,
|
||||||
GTK_PARAM_READWRITE));
|
GTK_PARAM_READWRITE));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GtkFileChooser:filters:
|
||||||
|
*
|
||||||
|
* A #GListModel containing the filters that have been
|
||||||
|
* added with gtk_file_chooser_add_filter().
|
||||||
|
*
|
||||||
|
* The returned object should not be modified. It may
|
||||||
|
* or may not be updated for later changes.
|
||||||
|
*/
|
||||||
|
g_object_interface_install_property (iface,
|
||||||
|
g_param_spec_object ("filters",
|
||||||
|
P_("Filters"),
|
||||||
|
P_("List model of filters"),
|
||||||
|
G_TYPE_LIST_MODEL,
|
||||||
|
GTK_PARAM_READABLE));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GtkFileChooser:shortcut-folders:
|
||||||
|
*
|
||||||
|
* A #GListModel containing the shortcut folders that have been
|
||||||
|
* added with gtk_file_chooser_add_shortcut().
|
||||||
|
*
|
||||||
|
* The returned object should not be modified. It may
|
||||||
|
* or may not be updated for later changes.
|
||||||
|
*/
|
||||||
|
g_object_interface_install_property (iface,
|
||||||
|
g_param_spec_object ("shortcut-folders",
|
||||||
|
P_("Shortcut Folders"),
|
||||||
|
P_("List model of shortcut folders"),
|
||||||
|
G_TYPE_LIST_MODEL,
|
||||||
|
GTK_PARAM_READABLE));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GtkFileChooser:create-folders:
|
* GtkFileChooser:create-folders:
|
||||||
*
|
*
|
||||||
@@ -682,23 +714,24 @@ gtk_file_chooser_remove_filter (GtkFileChooser *chooser,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gtk_file_chooser_list_filters:
|
* gtk_file_chooser_get_filters:
|
||||||
* @chooser: a #GtkFileChooser
|
* @chooser: a #GtkFileChooser
|
||||||
*
|
*
|
||||||
* Lists the current set of user-selectable filters; see
|
* Gets the current set of user-selectable filters, as a list model; see
|
||||||
* gtk_file_chooser_add_filter(), gtk_file_chooser_remove_filter().
|
* gtk_file_chooser_add_filter(), gtk_file_chooser_remove_filter().
|
||||||
*
|
*
|
||||||
* Returns: (element-type GtkFileFilter) (transfer container): a
|
* You should not modify the returned list model. Future changes to
|
||||||
* #GSList containing the current set of user selectable filters. The
|
* @chooser may or may not affect the returned model.
|
||||||
* contents of the list are owned by GTK+, but you must free the list
|
*
|
||||||
* itself with g_slist_free() when you are done with it.
|
* Returns: (transfer full): a #GListModel containing the current set
|
||||||
|
* of user-selectable filters.
|
||||||
**/
|
**/
|
||||||
GSList *
|
GListModel *
|
||||||
gtk_file_chooser_list_filters (GtkFileChooser *chooser)
|
gtk_file_chooser_get_filters (GtkFileChooser *chooser)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
|
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
|
||||||
|
|
||||||
return GTK_FILE_CHOOSER_GET_IFACE (chooser)->list_filters (chooser);
|
return GTK_FILE_CHOOSER_GET_IFACE (chooser)->get_filters (chooser);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -750,21 +783,23 @@ gtk_file_chooser_get_filter (GtkFileChooser *chooser)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gtk_file_chooser_list_shortcut_folders:
|
* gtk_file_chooser_get_shortcut_folders:
|
||||||
* @chooser: a #GtkFileChooser
|
* @chooser: a #GtkFileChooser
|
||||||
*
|
*
|
||||||
* Queries the list of shortcut folders in the file chooser, as set by
|
* Queries the list of shortcut folders in the file chooser, as set by
|
||||||
* gtk_file_chooser_add_shortcut_folder().
|
* gtk_file_chooser_add_shortcut_folder().
|
||||||
*
|
*
|
||||||
* Returns: (nullable) (element-type Gio.File) (transfer full): A list
|
* You should not modify the returned list model. Future changes to
|
||||||
* of folder filenames, or %NULL if there are no shortcut folders.
|
* @chooser may or may not affect the returned model.
|
||||||
|
*
|
||||||
|
* Returns: (transfer full): A list model of #GFiles
|
||||||
*/
|
*/
|
||||||
GSList *
|
GListModel *
|
||||||
gtk_file_chooser_list_shortcut_folders (GtkFileChooser *chooser)
|
gtk_file_chooser_get_shortcut_folders (GtkFileChooser *chooser)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
|
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
|
||||||
|
|
||||||
return GTK_FILE_CHOOSER_GET_IFACE (chooser)->list_shortcut_folders (chooser);
|
return GTK_FILE_CHOOSER_GET_IFACE (chooser)->get_shortcut_folders (chooser);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -145,18 +145,18 @@ GFile * gtk_file_chooser_get_current_folder (GtkFileChooser *chooser);
|
|||||||
*/
|
*/
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
void gtk_file_chooser_add_filter (GtkFileChooser *chooser,
|
void gtk_file_chooser_add_filter (GtkFileChooser *chooser,
|
||||||
GtkFileFilter *filter);
|
GtkFileFilter *filter);
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
void gtk_file_chooser_remove_filter (GtkFileChooser *chooser,
|
void gtk_file_chooser_remove_filter (GtkFileChooser *chooser,
|
||||||
GtkFileFilter *filter);
|
GtkFileFilter *filter);
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
GSList *gtk_file_chooser_list_filters (GtkFileChooser *chooser);
|
GListModel *gtk_file_chooser_get_filters (GtkFileChooser *chooser);
|
||||||
|
|
||||||
/* Current filter
|
/* Current filter
|
||||||
*/
|
*/
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
void gtk_file_chooser_set_filter (GtkFileChooser *chooser,
|
void gtk_file_chooser_set_filter (GtkFileChooser *chooser,
|
||||||
GtkFileFilter *filter);
|
GtkFileFilter *filter);
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
GtkFileFilter *gtk_file_chooser_get_filter (GtkFileChooser *chooser);
|
GtkFileFilter *gtk_file_chooser_get_filter (GtkFileChooser *chooser);
|
||||||
|
|
||||||
@@ -164,14 +164,14 @@ GtkFileFilter *gtk_file_chooser_get_filter (GtkFileChooser *chooser);
|
|||||||
|
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
gboolean gtk_file_chooser_add_shortcut_folder (GtkFileChooser *chooser,
|
gboolean gtk_file_chooser_add_shortcut_folder (GtkFileChooser *chooser,
|
||||||
GFile *folder,
|
GFile *folder,
|
||||||
GError **error);
|
GError **error);
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
gboolean gtk_file_chooser_remove_shortcut_folder (GtkFileChooser *chooser,
|
gboolean gtk_file_chooser_remove_shortcut_folder (GtkFileChooser *chooser,
|
||||||
GFile *folder,
|
GFile *folder,
|
||||||
GError **error);
|
GError **error);
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
GSList *gtk_file_chooser_list_shortcut_folders (GtkFileChooser *chooser);
|
GListModel *gtk_file_chooser_get_shortcut_folders (GtkFileChooser *chooser);
|
||||||
|
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
void gtk_file_chooser_add_choice (GtkFileChooser *chooser,
|
void gtk_file_chooser_add_choice (GtkFileChooser *chooser,
|
||||||
|
|||||||
@@ -1035,6 +1035,8 @@ gtk_file_chooser_button_get_property (GObject *object,
|
|||||||
case GTK_FILE_CHOOSER_PROP_FILTER:
|
case GTK_FILE_CHOOSER_PROP_FILTER:
|
||||||
case GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE:
|
case GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE:
|
||||||
case GTK_FILE_CHOOSER_PROP_CREATE_FOLDERS:
|
case GTK_FILE_CHOOSER_PROP_CREATE_FOLDERS:
|
||||||
|
case GTK_FILE_CHOOSER_PROP_FILTERS:
|
||||||
|
case GTK_FILE_CHOOSER_PROP_SHORTCUT_FOLDERS:
|
||||||
g_object_get_property (G_OBJECT (button->chooser), pspec->name, value);
|
g_object_get_property (G_OBJECT (button->chooser), pspec->name, value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
#include "gtkintl.h"
|
#include "gtkintl.h"
|
||||||
#include "gtkmarshalers.h"
|
#include "gtkmarshalers.h"
|
||||||
#include "gtkfilefilterprivate.h"
|
#include "gtkfilefilterprivate.h"
|
||||||
|
#include "gtkfilter.h"
|
||||||
#include "gtkeventcontrollerfocus.h"
|
#include "gtkeventcontrollerfocus.h"
|
||||||
|
|
||||||
typedef struct _GtkFileChooserEntryClass GtkFileChooserEntryClass;
|
typedef struct _GtkFileChooserEntryClass GtkFileChooserEntryClass;
|
||||||
@@ -194,65 +195,22 @@ match_func (GtkEntryCompletion *compl,
|
|||||||
* current file filter (e.g. just jpg files) here. */
|
* current file filter (e.g. just jpg files) here. */
|
||||||
if (chooser_entry->current_filter != NULL)
|
if (chooser_entry->current_filter != NULL)
|
||||||
{
|
{
|
||||||
char *mime_type = NULL;
|
|
||||||
gboolean matches;
|
|
||||||
GFile *file;
|
GFile *file;
|
||||||
GFileInfo *file_info;
|
GFileInfo *info;
|
||||||
GtkFileFilterInfo filter_info;
|
|
||||||
GtkFileFilterFlags needed_flags;
|
|
||||||
|
|
||||||
file = _gtk_file_system_model_get_file (GTK_FILE_SYSTEM_MODEL (chooser_entry->completion_store),
|
file = _gtk_file_system_model_get_file (GTK_FILE_SYSTEM_MODEL (chooser_entry->completion_store),
|
||||||
iter);
|
iter);
|
||||||
file_info = _gtk_file_system_model_get_info (GTK_FILE_SYSTEM_MODEL (chooser_entry->completion_store),
|
info = _gtk_file_system_model_get_info (GTK_FILE_SYSTEM_MODEL (chooser_entry->completion_store),
|
||||||
iter);
|
iter);
|
||||||
|
|
||||||
/* We always allow navigating into subfolders, so don't ever filter directories */
|
/* We always allow navigating into subfolders, so don't ever filter directories */
|
||||||
if (g_file_info_get_file_type (file_info) != G_FILE_TYPE_REGULAR)
|
if (g_file_info_get_file_type (info) != G_FILE_TYPE_REGULAR)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
needed_flags = gtk_file_filter_get_needed (chooser_entry->current_filter);
|
if (!g_file_info_has_attribute (info, "standard::file"))
|
||||||
|
g_file_info_set_attribute_object (info, "standard::file", G_OBJECT (file));
|
||||||
|
|
||||||
filter_info.display_name = g_file_info_get_display_name (file_info);
|
return gtk_filter_match (GTK_FILTER (chooser_entry->current_filter), info);
|
||||||
filter_info.contains = GTK_FILE_FILTER_DISPLAY_NAME;
|
|
||||||
|
|
||||||
if (needed_flags & GTK_FILE_FILTER_MIME_TYPE)
|
|
||||||
{
|
|
||||||
const char *s = g_file_info_get_content_type (file_info);
|
|
||||||
if (s != NULL)
|
|
||||||
{
|
|
||||||
mime_type = g_content_type_get_mime_type (s);
|
|
||||||
if (mime_type != NULL)
|
|
||||||
{
|
|
||||||
filter_info.mime_type = mime_type;
|
|
||||||
filter_info.contains |= GTK_FILE_FILTER_MIME_TYPE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (needed_flags & GTK_FILE_FILTER_FILENAME)
|
|
||||||
{
|
|
||||||
const char *path = g_file_get_path (file);
|
|
||||||
if (path != NULL)
|
|
||||||
{
|
|
||||||
filter_info.filename = path;
|
|
||||||
filter_info.contains |= GTK_FILE_FILTER_FILENAME;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (needed_flags & GTK_FILE_FILTER_URI)
|
|
||||||
{
|
|
||||||
const char *uri = g_file_get_uri (file);
|
|
||||||
if (uri)
|
|
||||||
{
|
|
||||||
filter_info.uri = uri;
|
|
||||||
filter_info.contains |= GTK_FILE_FILTER_URI;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
matches = gtk_file_filter_filter (chooser_entry->current_filter, &filter_info);
|
|
||||||
|
|
||||||
g_free (mime_type);
|
|
||||||
return matches;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ response_cb (GDBusConnection *connection,
|
|||||||
if (current_filter)
|
if (current_filter)
|
||||||
{
|
{
|
||||||
GtkFileFilter *filter = gtk_file_filter_new_from_gvariant (current_filter);
|
GtkFileFilter *filter = gtk_file_filter_new_from_gvariant (current_filter);
|
||||||
const gchar *current_filter_name = gtk_file_filter_get_name (filter);
|
const char *current_filter_name = gtk_file_filter_get_name (filter);
|
||||||
|
|
||||||
/* Try to find the given filter in the list of filters.
|
/* Try to find the given filter in the list of filters.
|
||||||
* Since filters are compared by pointer value, using the passed
|
* Since filters are compared by pointer value, using the passed
|
||||||
@@ -137,18 +137,24 @@ response_cb (GDBusConnection *connection,
|
|||||||
* If there is no match, just set the filter as it was retrieved.
|
* If there is no match, just set the filter as it was retrieved.
|
||||||
*/
|
*/
|
||||||
GtkFileFilter *filter_to_select = filter;
|
GtkFileFilter *filter_to_select = filter;
|
||||||
GSList *filters = gtk_file_chooser_list_filters (GTK_FILE_CHOOSER (self));
|
GListModel *filters;
|
||||||
for (GSList *l = filters; l; l = l->next)
|
guint j, n;
|
||||||
|
|
||||||
|
filters = gtk_file_chooser_get_filters (GTK_FILE_CHOOSER (self));
|
||||||
|
n = g_list_model_get_n_items (filters);
|
||||||
|
for (j = 0; j < n; j++)
|
||||||
{
|
{
|
||||||
GtkFileFilter *f = l->data;
|
GtkFileFilter *f = g_list_model_get_item (filters, j);
|
||||||
if (g_strcmp0 (gtk_file_filter_get_name (f), current_filter_name) == 0)
|
if (g_strcmp0 (gtk_file_filter_get_name (f), current_filter_name) == 0)
|
||||||
{
|
{
|
||||||
filter_to_select = f;
|
filter_to_select = f;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
g_object_unref (f);
|
||||||
}
|
}
|
||||||
g_slist_free (filters);
|
g_object_unref (filters);
|
||||||
gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (self), filter_to_select);
|
gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (self), filter_to_select);
|
||||||
|
g_object_unref (filter_to_select);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_slist_free_full (self->custom_files, g_object_unref);
|
g_slist_free_full (self->custom_files, g_object_unref);
|
||||||
@@ -264,17 +270,20 @@ open_file_msg_cb (GObject *source_object,
|
|||||||
static GVariant *
|
static GVariant *
|
||||||
get_filters (GtkFileChooser *self)
|
get_filters (GtkFileChooser *self)
|
||||||
{
|
{
|
||||||
GSList *list, *l;
|
GListModel *filters;
|
||||||
|
guint n, i;
|
||||||
GVariantBuilder builder;
|
GVariantBuilder builder;
|
||||||
|
|
||||||
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(sa(us))"));
|
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(sa(us))"));
|
||||||
list = gtk_file_chooser_list_filters (self);
|
filters = gtk_file_chooser_get_filters (self);
|
||||||
for (l = list; l; l = l->next)
|
n = g_list_model_get_n_items (filters);
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
{
|
{
|
||||||
GtkFileFilter *filter = l->data;
|
GtkFileFilter *filter = g_list_model_get_item (filters, i);
|
||||||
g_variant_builder_add (&builder, "@(sa(us))", gtk_file_filter_to_gvariant (filter));
|
g_variant_builder_add (&builder, "@(sa(us))", gtk_file_filter_to_gvariant (filter));
|
||||||
|
g_object_unref (filter);
|
||||||
}
|
}
|
||||||
g_slist_free (list);
|
g_object_unref (filters);
|
||||||
|
|
||||||
return g_variant_builder_end (&builder);
|
return g_variant_builder_end (&builder);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,9 +99,10 @@ typedef struct {
|
|||||||
else
|
else
|
||||||
[data->panel setAllowedFileTypes:filter];
|
[data->panel setAllowedFileTypes:filter];
|
||||||
|
|
||||||
GSList *filters = gtk_file_chooser_list_filters (GTK_FILE_CHOOSER (data->self));
|
GListModel *filters = gtk_file_chooser_get_filters (GTK_FILE_CHOOSER (data->self));
|
||||||
data->self->current_filter = g_slist_nth_data (filters, selected_index);
|
data->self->current_filter = g_list_model_get_item (filters, selected_index);
|
||||||
g_slist_free (filters);
|
g_object_unref (data->self->current_filter);
|
||||||
|
g_object_unref (filters);
|
||||||
g_object_notify (G_OBJECT (data->self), "filter");
|
g_object_notify (G_OBJECT (data->self), "filter");
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
@@ -307,13 +308,28 @@ filechooser_quartz_launch (FileChooserQuartzData *data)
|
|||||||
|
|
||||||
if (data->self->current_filter)
|
if (data->self->current_filter)
|
||||||
{
|
{
|
||||||
GSList *filters = gtk_file_chooser_list_filters (GTK_FILE_CHOOSER (data->self));
|
GListModel *filters;
|
||||||
gint current_filter_index = g_slist_index (filters, data->self->current_filter);
|
guint i, n;
|
||||||
g_slist_free (filters);
|
guint current_filter_index = GTK_INVALID_LIST_POSITION;
|
||||||
|
|
||||||
if (current_filter_index >= 0)
|
filters = gtk_file_chooser_get_filters (GTK_FILE_CHOOSER (data->self));
|
||||||
|
n = g_list_model_get_n_items (filters);
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
gpointer item = g_list_model_get_item (filters, i);
|
||||||
|
if (item == data->self->current_filter)
|
||||||
|
{
|
||||||
|
g_object_unref (item);
|
||||||
|
current_filter_index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
g_object_unref (item);
|
||||||
|
}
|
||||||
|
g_object_unref (filters);
|
||||||
|
|
||||||
|
if (current_filter_index != GTK_INVALID_LIST_POSITION)
|
||||||
[data->filter_combo_box selectItemAtIndex:current_filter_index];
|
[data->filter_combo_box selectItemAtIndex:current_filter_index];
|
||||||
else
|
else
|
||||||
[data->filter_combo_box selectItemAtIndex:0];
|
[data->filter_combo_box selectItemAtIndex:0];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -437,15 +453,15 @@ gtk_file_chooser_native_quartz_show (GtkFileChooserNative *self)
|
|||||||
GtkWindow *transient_for;
|
GtkWindow *transient_for;
|
||||||
GtkFileChooserAction action;
|
GtkFileChooserAction action;
|
||||||
|
|
||||||
GSList *filters, *l;
|
GListModel *filters;
|
||||||
int n_filters, i;
|
guint n_filters, i;
|
||||||
char *message = NULL;
|
char *message = NULL;
|
||||||
|
|
||||||
data = g_new0 (FileChooserQuartzData, 1);
|
data = g_new0 (FileChooserQuartzData, 1);
|
||||||
|
|
||||||
// examine filters!
|
// examine filters!
|
||||||
filters = gtk_file_chooser_list_filters (GTK_FILE_CHOOSER (self));
|
filters = gtk_file_chooser_get_filters (GTK_FILE_CHOOSER (self));
|
||||||
n_filters = g_slist_length (filters);
|
n_filters = g_list_model_get_n_items (filters);
|
||||||
if (n_filters > 0)
|
if (n_filters > 0)
|
||||||
{
|
{
|
||||||
data->filters = [NSMutableArray arrayWithCapacity:n_filters];
|
data->filters = [NSMutableArray arrayWithCapacity:n_filters];
|
||||||
@@ -453,13 +469,17 @@ gtk_file_chooser_native_quartz_show (GtkFileChooserNative *self)
|
|||||||
data->filter_names = [NSMutableArray arrayWithCapacity:n_filters];
|
data->filter_names = [NSMutableArray arrayWithCapacity:n_filters];
|
||||||
[data->filter_names retain];
|
[data->filter_names retain];
|
||||||
|
|
||||||
for (l = filters, i = 0; l != NULL; l = l->next, i++)
|
for (i = 0; i < n; i++)
|
||||||
{
|
{
|
||||||
if (!file_filter_to_quartz (l->data, data->filters, data->filter_names))
|
GtkFileFilter *filter = g_list_model_get_item (filters, i);
|
||||||
|
if (!file_filter_to_quartz (filter, data->filters, data->filter_names))
|
||||||
{
|
{
|
||||||
filechooser_quartz_data_free (data);
|
filechooser_quartz_data_free (data);
|
||||||
|
g_object_unref (filter);
|
||||||
|
g_object_unref (filters);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
g_object_unref (filter);
|
||||||
}
|
}
|
||||||
self->current_filter = gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (self));
|
self->current_filter = gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (self));
|
||||||
}
|
}
|
||||||
@@ -467,6 +487,8 @@ gtk_file_chooser_native_quartz_show (GtkFileChooserNative *self)
|
|||||||
{
|
{
|
||||||
self->current_filter = NULL;
|
self->current_filter = NULL;
|
||||||
}
|
}
|
||||||
|
g_object_unref (filters);
|
||||||
|
|
||||||
self->mode_data = data;
|
self->mode_data = data;
|
||||||
data->self = g_object_ref (self);
|
data->self = g_object_ref (self);
|
||||||
|
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ typedef struct {
|
|||||||
char *cancel_label;
|
char *cancel_label;
|
||||||
char *title;
|
char *title;
|
||||||
|
|
||||||
GSList *shortcut_files;
|
GListModel *shortcut_files;
|
||||||
GArray *choices_selections;
|
GArray *choices_selections;
|
||||||
|
|
||||||
GFile *current_folder;
|
GFile *current_folder;
|
||||||
@@ -244,9 +244,11 @@ ifiledialogevents_OnTypeChange (IFileDialogEvents * self,
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
fileType--; // fileTypeIndex starts at 1
|
fileType--; // fileTypeIndex starts at 1
|
||||||
GSList *filters = gtk_file_chooser_list_filters (GTK_FILE_CHOOSER (events->data->self));
|
GListModel *filters = gtk_file_chooser_get_filters (GTK_FILE_CHOOSER (events->data->self));
|
||||||
events->data->self->current_filter = g_slist_nth_data (filters, fileType);
|
GtkFileFilter *filter = g_list_model_get_item (filters, fileType);
|
||||||
g_slist_free (filters);
|
events->data->self->current_filter = filter;
|
||||||
|
g_object_unref (filter);
|
||||||
|
g_object_unref (filters);
|
||||||
g_object_notify (G_OBJECT (events->data->self), "filter");
|
g_object_notify (G_OBJECT (events->data->self), "filter");
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
@@ -328,7 +330,7 @@ filechooser_win32_thread_data_free (FilechooserWin32ThreadData *data)
|
|||||||
g_array_free (data->choices_selections, TRUE);
|
g_array_free (data->choices_selections, TRUE);
|
||||||
data->choices_selections = NULL;
|
data->choices_selections = NULL;
|
||||||
}
|
}
|
||||||
g_slist_free_full (data->shortcut_files, g_object_unref);
|
g_object_unref (data->shortcut_files);
|
||||||
g_slist_free_full (data->files, g_object_unref);
|
g_slist_free_full (data->files, g_object_unref);
|
||||||
if (data->self)
|
if (data->self)
|
||||||
g_object_unref (data->self);
|
g_object_unref (data->self);
|
||||||
@@ -463,7 +465,7 @@ filechooser_win32_thread (gpointer _data)
|
|||||||
IFileDialog2 *pfd2 = NULL;
|
IFileDialog2 *pfd2 = NULL;
|
||||||
DWORD flags;
|
DWORD flags;
|
||||||
DWORD cookie;
|
DWORD cookie;
|
||||||
GSList *l;
|
guint j, n_items;
|
||||||
|
|
||||||
CoInitializeEx (NULL, COINIT_APARTMENTTHREADED);
|
CoInitializeEx (NULL, COINIT_APARTMENTTHREADED);
|
||||||
|
|
||||||
@@ -529,9 +531,11 @@ filechooser_win32_thread (gpointer _data)
|
|||||||
g_free (label);
|
g_free (label);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (l = data->shortcut_files; l != NULL; l = l->next)
|
n_items = g_list_model_get_n_items (data->shortcut_files);
|
||||||
|
for (j = 0; j < n_items; j++)
|
||||||
{
|
{
|
||||||
IShellItem *item = get_shell_item_for_file (l->data);
|
GFile *file = g_list_model_get_item (data->shortcut_files, j);
|
||||||
|
IShellItem *item = get_shell_item_for_file (file);
|
||||||
if (item)
|
if (item)
|
||||||
{
|
{
|
||||||
hr = IFileDialog_AddPlace (pfd, item, FDAP_BOTTOM);
|
hr = IFileDialog_AddPlace (pfd, item, FDAP_BOTTOM);
|
||||||
@@ -539,6 +543,7 @@ filechooser_win32_thread (gpointer _data)
|
|||||||
g_warning_hr ("Can't add dialog shortcut", hr);
|
g_warning_hr ("Can't add dialog shortcut", hr);
|
||||||
IShellItem_Release (item);
|
IShellItem_Release (item);
|
||||||
}
|
}
|
||||||
|
g_object_unref (file);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data->current_file)
|
if (data->current_file)
|
||||||
@@ -591,9 +596,23 @@ filechooser_win32_thread (gpointer _data)
|
|||||||
|
|
||||||
if (data->self->current_filter)
|
if (data->self->current_filter)
|
||||||
{
|
{
|
||||||
GSList *filters = gtk_file_chooser_list_filters (GTK_FILE_CHOOSER (data->self));
|
GListModel *filters;
|
||||||
gint current_filter_index = g_slist_index (filters, data->self->current_filter);
|
guint current_filter_index = GTK_INVALID_LIST_POSITION;
|
||||||
g_slist_free (filters);
|
|
||||||
|
filters = gtk_file_chooser_get_filters (GTK_FILE_CHOOSER (data->self));
|
||||||
|
n_items = g_list_model_get_n_items (filters);
|
||||||
|
for (j = 0; j < n_items; j++)
|
||||||
|
{
|
||||||
|
gpointer item = g_list_model_get_item (filters, j);
|
||||||
|
if (item == data->self->current_filter)
|
||||||
|
{
|
||||||
|
current_filter_index = j;
|
||||||
|
g_object_unref (item);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
g_object_unref (item);
|
||||||
|
}
|
||||||
|
g_object_unref (filters);
|
||||||
|
|
||||||
if (current_filter_index >= 0)
|
if (current_filter_index >= 0)
|
||||||
hr = IFileDialog_SetFileTypeIndex (pfd, current_filter_index + 1);
|
hr = IFileDialog_SetFileTypeIndex (pfd, current_filter_index + 1);
|
||||||
@@ -617,6 +636,8 @@ filechooser_win32_thread (gpointer _data)
|
|||||||
hr = IFileDialog_QueryInterface (pfd, &IID_IFileDialogCustomize, (LPVOID *) &pfdc);
|
hr = IFileDialog_QueryInterface (pfd, &IID_IFileDialogCustomize, (LPVOID *) &pfdc);
|
||||||
if (SUCCEEDED (hr))
|
if (SUCCEEDED (hr))
|
||||||
{
|
{
|
||||||
|
GSList *l;
|
||||||
|
|
||||||
for (l = data->self->choices; l; l = l->next, dialog_control_id++)
|
for (l = data->self->choices; l; l = l->next, dialog_control_id++)
|
||||||
{
|
{
|
||||||
GtkFileChooserNativeChoice *choice = (GtkFileChooserNativeChoice*) l->data;
|
GtkFileChooserNativeChoice *choice = (GtkFileChooserNativeChoice*) l->data;
|
||||||
@@ -742,6 +763,8 @@ filechooser_win32_thread (gpointer _data)
|
|||||||
hr = IFileDialog_QueryInterface (pfd, &IID_IFileDialogCustomize, (LPVOID *) &pfdc);
|
hr = IFileDialog_QueryInterface (pfd, &IID_IFileDialogCustomize, (LPVOID *) &pfdc);
|
||||||
if (SUCCEEDED (hr))
|
if (SUCCEEDED (hr))
|
||||||
{
|
{
|
||||||
|
GSList *l;
|
||||||
|
|
||||||
for (l = data->self->choices; l; l = l->next)
|
for (l = data->self->choices; l; l = l->next)
|
||||||
{
|
{
|
||||||
GtkFileChooserNativeChoice *choice = (GtkFileChooserNativeChoice*) l->data;
|
GtkFileChooserNativeChoice *choice = (GtkFileChooserNativeChoice*) l->data;
|
||||||
@@ -864,21 +887,24 @@ gtk_file_chooser_native_win32_show (GtkFileChooserNative *self)
|
|||||||
FilechooserWin32ThreadData *data;
|
FilechooserWin32ThreadData *data;
|
||||||
GtkWindow *transient_for;
|
GtkWindow *transient_for;
|
||||||
GtkFileChooserAction action;
|
GtkFileChooserAction action;
|
||||||
GSList *filters, *l;
|
GListModel *filters;
|
||||||
int n_filters, i;
|
guint n_filters, i;
|
||||||
|
|
||||||
data = g_new0 (FilechooserWin32ThreadData, 1);
|
data = g_new0 (FilechooserWin32ThreadData, 1);
|
||||||
|
|
||||||
filters = gtk_file_chooser_list_filters (GTK_FILE_CHOOSER (self));
|
filters = gtk_file_chooser_get_filters (GTK_FILE_CHOOSER (self));
|
||||||
n_filters = g_slist_length (filters);
|
n_filters = g_list_model_get_n_items (filters);
|
||||||
if (n_filters > 0)
|
if (n_filters > 0)
|
||||||
{
|
{
|
||||||
data->filters = g_new0 (COMDLG_FILTERSPEC, n_filters + 1);
|
data->filters = g_new0 (COMDLG_FILTERSPEC, n_filters + 1);
|
||||||
|
|
||||||
for (l = filters, i = 0; l != NULL; l = l->next, i++)
|
for (i = 0; i < n_filters; i++)
|
||||||
{
|
{
|
||||||
if (!file_filter_to_win32 (l->data, &data->filters[i]))
|
GtkFileFilter *filter = g_list_model_get_item (filters, i);
|
||||||
|
if (!file_filter_to_win32 (filter, &data->filters[i]))
|
||||||
{
|
{
|
||||||
|
g_object_unref (filter);
|
||||||
|
g_object_unref (filters);
|
||||||
filechooser_win32_thread_data_free (data);
|
filechooser_win32_thread_data_free (data);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -889,12 +915,13 @@ gtk_file_chooser_native_win32_show (GtkFileChooserNative *self)
|
|||||||
{
|
{
|
||||||
self->current_filter = NULL;
|
self->current_filter = NULL;
|
||||||
}
|
}
|
||||||
|
g_object_unref (filters);
|
||||||
|
|
||||||
self->mode_data = data;
|
self->mode_data = data;
|
||||||
data->self = g_object_ref (self);
|
data->self = g_object_ref (self);
|
||||||
|
|
||||||
data->shortcut_files =
|
data->shortcut_files =
|
||||||
gtk_file_chooser_list_shortcut_folders (GTK_FILE_CHOOSER (self->dialog));
|
gtk_file_chooser_get_shortcut_folders (GTK_FILE_CHOOSER (self->dialog));
|
||||||
|
|
||||||
data->accept_label = translate_mnemonics (self->accept_label);
|
data->accept_label = translate_mnemonics (self->accept_label);
|
||||||
data->cancel_label = translate_mnemonics (self->cancel_label);
|
data->cancel_label = translate_mnemonics (self->cancel_label);
|
||||||
|
|||||||
+25
-25
@@ -58,34 +58,34 @@ struct _GtkFileChooserIface
|
|||||||
|
|
||||||
/* Methods
|
/* Methods
|
||||||
*/
|
*/
|
||||||
gboolean (*set_current_folder) (GtkFileChooser *chooser,
|
gboolean (*set_current_folder) (GtkFileChooser *chooser,
|
||||||
GFile *file,
|
GFile *file,
|
||||||
GError **error);
|
GError **error);
|
||||||
GFile * (*get_current_folder) (GtkFileChooser *chooser);
|
GFile * (*get_current_folder) (GtkFileChooser *chooser);
|
||||||
void (*set_current_name) (GtkFileChooser *chooser,
|
void (*set_current_name) (GtkFileChooser *chooser,
|
||||||
const gchar *name);
|
const gchar *name);
|
||||||
gchar * (*get_current_name) (GtkFileChooser *chooser);
|
gchar * (*get_current_name) (GtkFileChooser *chooser);
|
||||||
gboolean (*select_file) (GtkFileChooser *chooser,
|
gboolean (*select_file) (GtkFileChooser *chooser,
|
||||||
GFile *file,
|
GFile *file,
|
||||||
GError **error);
|
GError **error);
|
||||||
void (*unselect_file) (GtkFileChooser *chooser,
|
void (*unselect_file) (GtkFileChooser *chooser,
|
||||||
GFile *file);
|
GFile *file);
|
||||||
void (*select_all) (GtkFileChooser *chooser);
|
void (*select_all) (GtkFileChooser *chooser);
|
||||||
void (*unselect_all) (GtkFileChooser *chooser);
|
void (*unselect_all) (GtkFileChooser *chooser);
|
||||||
GSList * (*get_files) (GtkFileChooser *chooser);
|
GSList * (*get_files) (GtkFileChooser *chooser);
|
||||||
GtkFileSystem *(*get_file_system) (GtkFileChooser *chooser);
|
GtkFileSystem *(*get_file_system) (GtkFileChooser *chooser);
|
||||||
void (*add_filter) (GtkFileChooser *chooser,
|
void (*add_filter) (GtkFileChooser *chooser,
|
||||||
GtkFileFilter *filter);
|
GtkFileFilter *filter);
|
||||||
void (*remove_filter) (GtkFileChooser *chooser,
|
void (*remove_filter) (GtkFileChooser *chooser,
|
||||||
GtkFileFilter *filter);
|
GtkFileFilter *filter);
|
||||||
GSList * (*list_filters) (GtkFileChooser *chooser);
|
GListModel * (*get_filters) (GtkFileChooser *chooser);
|
||||||
gboolean (*add_shortcut_folder) (GtkFileChooser *chooser,
|
gboolean (*add_shortcut_folder) (GtkFileChooser *chooser,
|
||||||
GFile *file,
|
GFile *file,
|
||||||
GError **error);
|
GError **error);
|
||||||
gboolean (*remove_shortcut_folder) (GtkFileChooser *chooser,
|
gboolean (*remove_shortcut_folder) (GtkFileChooser *chooser,
|
||||||
GFile *file,
|
GFile *file,
|
||||||
GError **error);
|
GError **error);
|
||||||
GSList * (*list_shortcut_folders) (GtkFileChooser *chooser);
|
GListModel * (*get_shortcut_folders) (GtkFileChooser *chooser);
|
||||||
|
|
||||||
/* Signals
|
/* Signals
|
||||||
*/
|
*/
|
||||||
|
|||||||
+24
-18
@@ -45,14 +45,14 @@ static void delegate_add_filter (GtkFileChooser *choose
|
|||||||
GtkFileFilter *filter);
|
GtkFileFilter *filter);
|
||||||
static void delegate_remove_filter (GtkFileChooser *chooser,
|
static void delegate_remove_filter (GtkFileChooser *chooser,
|
||||||
GtkFileFilter *filter);
|
GtkFileFilter *filter);
|
||||||
static GSList * delegate_list_filters (GtkFileChooser *chooser);
|
static GListModel * delegate_get_filters (GtkFileChooser *chooser);
|
||||||
static gboolean delegate_add_shortcut_folder (GtkFileChooser *chooser,
|
static gboolean delegate_add_shortcut_folder (GtkFileChooser *chooser,
|
||||||
GFile *file,
|
GFile *file,
|
||||||
GError **error);
|
GError **error);
|
||||||
static gboolean delegate_remove_shortcut_folder (GtkFileChooser *chooser,
|
static gboolean delegate_remove_shortcut_folder (GtkFileChooser *chooser,
|
||||||
GFile *file,
|
GFile *file,
|
||||||
GError **error);
|
GError **error);
|
||||||
static GSList * delegate_list_shortcut_folders (GtkFileChooser *chooser);
|
static GListModel * delegate_get_shortcut_folders (GtkFileChooser *chooser);
|
||||||
static void delegate_notify (GObject *object,
|
static void delegate_notify (GObject *object,
|
||||||
GParamSpec *pspec,
|
GParamSpec *pspec,
|
||||||
gpointer data);
|
gpointer data);
|
||||||
@@ -92,17 +92,23 @@ void
|
|||||||
_gtk_file_chooser_install_properties (GObjectClass *klass)
|
_gtk_file_chooser_install_properties (GObjectClass *klass)
|
||||||
{
|
{
|
||||||
g_object_class_override_property (klass,
|
g_object_class_override_property (klass,
|
||||||
GTK_FILE_CHOOSER_PROP_ACTION,
|
GTK_FILE_CHOOSER_PROP_ACTION,
|
||||||
"action");
|
"action");
|
||||||
g_object_class_override_property (klass,
|
g_object_class_override_property (klass,
|
||||||
GTK_FILE_CHOOSER_PROP_FILTER,
|
GTK_FILE_CHOOSER_PROP_FILTER,
|
||||||
"filter");
|
"filter");
|
||||||
g_object_class_override_property (klass,
|
g_object_class_override_property (klass,
|
||||||
GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE,
|
GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE,
|
||||||
"select-multiple");
|
"select-multiple");
|
||||||
g_object_class_override_property (klass,
|
g_object_class_override_property (klass,
|
||||||
GTK_FILE_CHOOSER_PROP_CREATE_FOLDERS,
|
GTK_FILE_CHOOSER_PROP_CREATE_FOLDERS,
|
||||||
"create-folders");
|
"create-folders");
|
||||||
|
g_object_class_override_property (klass,
|
||||||
|
GTK_FILE_CHOOSER_PROP_FILTERS,
|
||||||
|
"filters");
|
||||||
|
g_object_class_override_property (klass,
|
||||||
|
GTK_FILE_CHOOSER_PROP_SHORTCUT_FOLDERS,
|
||||||
|
"shortcut-folders");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -131,10 +137,10 @@ _gtk_file_chooser_delegate_iface_init (GtkFileChooserIface *iface)
|
|||||||
iface->get_file_system = delegate_get_file_system;
|
iface->get_file_system = delegate_get_file_system;
|
||||||
iface->add_filter = delegate_add_filter;
|
iface->add_filter = delegate_add_filter;
|
||||||
iface->remove_filter = delegate_remove_filter;
|
iface->remove_filter = delegate_remove_filter;
|
||||||
iface->list_filters = delegate_list_filters;
|
iface->get_filters = delegate_get_filters;
|
||||||
iface->add_shortcut_folder = delegate_add_shortcut_folder;
|
iface->add_shortcut_folder = delegate_add_shortcut_folder;
|
||||||
iface->remove_shortcut_folder = delegate_remove_shortcut_folder;
|
iface->remove_shortcut_folder = delegate_remove_shortcut_folder;
|
||||||
iface->list_shortcut_folders = delegate_list_shortcut_folders;
|
iface->get_shortcut_folders = delegate_get_shortcut_folders;
|
||||||
iface->add_choice = delegate_add_choice;
|
iface->add_choice = delegate_add_choice;
|
||||||
iface->remove_choice = delegate_remove_choice;
|
iface->remove_choice = delegate_remove_choice;
|
||||||
iface->set_choice = delegate_set_choice;
|
iface->set_choice = delegate_set_choice;
|
||||||
@@ -241,10 +247,10 @@ delegate_remove_filter (GtkFileChooser *chooser,
|
|||||||
gtk_file_chooser_remove_filter (get_delegate (chooser), filter);
|
gtk_file_chooser_remove_filter (get_delegate (chooser), filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GSList *
|
static GListModel *
|
||||||
delegate_list_filters (GtkFileChooser *chooser)
|
delegate_get_filters (GtkFileChooser *chooser)
|
||||||
{
|
{
|
||||||
return gtk_file_chooser_list_filters (get_delegate (chooser));
|
return gtk_file_chooser_get_filters (get_delegate (chooser));
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@@ -263,10 +269,10 @@ delegate_remove_shortcut_folder (GtkFileChooser *chooser,
|
|||||||
return gtk_file_chooser_remove_shortcut_folder (get_delegate (chooser), file, error);
|
return gtk_file_chooser_remove_shortcut_folder (get_delegate (chooser), file, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GSList *
|
static GListModel *
|
||||||
delegate_list_shortcut_folders (GtkFileChooser *chooser)
|
delegate_get_shortcut_folders (GtkFileChooser *chooser)
|
||||||
{
|
{
|
||||||
return gtk_file_chooser_list_shortcut_folders (get_delegate (chooser));
|
return gtk_file_chooser_get_shortcut_folders (get_delegate (chooser));
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
|||||||
@@ -32,7 +32,9 @@ typedef enum {
|
|||||||
GTK_FILE_CHOOSER_PROP_FILTER,
|
GTK_FILE_CHOOSER_PROP_FILTER,
|
||||||
GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE,
|
GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE,
|
||||||
GTK_FILE_CHOOSER_PROP_CREATE_FOLDERS,
|
GTK_FILE_CHOOSER_PROP_CREATE_FOLDERS,
|
||||||
GTK_FILE_CHOOSER_PROP_LAST = GTK_FILE_CHOOSER_PROP_CREATE_FOLDERS
|
GTK_FILE_CHOOSER_PROP_FILTERS,
|
||||||
|
GTK_FILE_CHOOSER_PROP_SHORTCUT_FOLDERS,
|
||||||
|
GTK_FILE_CHOOSER_PROP_LAST = GTK_FILE_CHOOSER_PROP_SHORTCUT_FOLDERS
|
||||||
} GtkFileChooserProp;
|
} GtkFileChooserProp;
|
||||||
|
|
||||||
void _gtk_file_chooser_install_properties (GObjectClass *klass);
|
void _gtk_file_chooser_install_properties (GObjectClass *klass);
|
||||||
|
|||||||
+39
-28
@@ -485,14 +485,14 @@ static void gtk_file_chooser_widget_add_filter (GtkF
|
|||||||
GtkFileFilter *filter);
|
GtkFileFilter *filter);
|
||||||
static void gtk_file_chooser_widget_remove_filter (GtkFileChooser *chooser,
|
static void gtk_file_chooser_widget_remove_filter (GtkFileChooser *chooser,
|
||||||
GtkFileFilter *filter);
|
GtkFileFilter *filter);
|
||||||
static GSList * gtk_file_chooser_widget_list_filters (GtkFileChooser *chooser);
|
static GListModel * gtk_file_chooser_widget_get_filters (GtkFileChooser *chooser);
|
||||||
static gboolean gtk_file_chooser_widget_add_shortcut_folder (GtkFileChooser *chooser,
|
static gboolean gtk_file_chooser_widget_add_shortcut_folder (GtkFileChooser *chooser,
|
||||||
GFile *file,
|
GFile *file,
|
||||||
GError **error);
|
GError **error);
|
||||||
static gboolean gtk_file_chooser_widget_remove_shortcut_folder (GtkFileChooser *chooser,
|
static gboolean gtk_file_chooser_widget_remove_shortcut_folder (GtkFileChooser *chooser,
|
||||||
GFile *file,
|
GFile *file,
|
||||||
GError **error);
|
GError **error);
|
||||||
static GSList * gtk_file_chooser_widget_list_shortcut_folders (GtkFileChooser *chooser);
|
static GListModel * gtk_file_chooser_widget_get_shortcut_folders (GtkFileChooser *chooser);
|
||||||
|
|
||||||
static gboolean gtk_file_chooser_widget_should_respond (GtkFileChooserEmbed *chooser_embed);
|
static gboolean gtk_file_chooser_widget_should_respond (GtkFileChooserEmbed *chooser_embed);
|
||||||
static void gtk_file_chooser_widget_initial_focus (GtkFileChooserEmbed *chooser_embed);
|
static void gtk_file_chooser_widget_initial_focus (GtkFileChooserEmbed *chooser_embed);
|
||||||
@@ -619,10 +619,10 @@ gtk_file_chooser_widget_iface_init (GtkFileChooserIface *iface)
|
|||||||
iface->get_current_name = gtk_file_chooser_widget_get_current_name;
|
iface->get_current_name = gtk_file_chooser_widget_get_current_name;
|
||||||
iface->add_filter = gtk_file_chooser_widget_add_filter;
|
iface->add_filter = gtk_file_chooser_widget_add_filter;
|
||||||
iface->remove_filter = gtk_file_chooser_widget_remove_filter;
|
iface->remove_filter = gtk_file_chooser_widget_remove_filter;
|
||||||
iface->list_filters = gtk_file_chooser_widget_list_filters;
|
iface->get_filters = gtk_file_chooser_widget_get_filters;
|
||||||
iface->add_shortcut_folder = gtk_file_chooser_widget_add_shortcut_folder;
|
iface->add_shortcut_folder = gtk_file_chooser_widget_add_shortcut_folder;
|
||||||
iface->remove_shortcut_folder = gtk_file_chooser_widget_remove_shortcut_folder;
|
iface->remove_shortcut_folder = gtk_file_chooser_widget_remove_shortcut_folder;
|
||||||
iface->list_shortcut_folders = gtk_file_chooser_widget_list_shortcut_folders;
|
iface->get_shortcut_folders = gtk_file_chooser_widget_get_shortcut_folders;
|
||||||
iface->add_choice = gtk_file_chooser_widget_add_choice;
|
iface->add_choice = gtk_file_chooser_widget_add_choice;
|
||||||
iface->remove_choice = gtk_file_chooser_widget_remove_choice;
|
iface->remove_choice = gtk_file_chooser_widget_remove_choice;
|
||||||
iface->set_choice = gtk_file_chooser_widget_set_choice;
|
iface->set_choice = gtk_file_chooser_widget_set_choice;
|
||||||
@@ -3072,6 +3072,14 @@ gtk_file_chooser_widget_get_property (GObject *object,
|
|||||||
g_value_set_boolean (value, impl->create_folders);
|
g_value_set_boolean (value, impl->create_folders);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GTK_FILE_CHOOSER_PROP_FILTERS:
|
||||||
|
g_value_set_object (value, impl->filters);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GTK_FILE_CHOOSER_PROP_SHORTCUT_FOLDERS:
|
||||||
|
g_value_take_object (value, gtk_file_chooser_get_shortcut_folders (GTK_FILE_CHOOSER (impl)));
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@@ -3429,25 +3437,27 @@ set_startup_mode (GtkFileChooserWidget *impl)
|
|||||||
static gboolean
|
static gboolean
|
||||||
shortcut_exists (GtkFileChooserWidget *impl, GFile *needle)
|
shortcut_exists (GtkFileChooserWidget *impl, GFile *needle)
|
||||||
{
|
{
|
||||||
GSList *haystack;
|
GListModel *haystack;
|
||||||
GSList *l;
|
guint n, i;
|
||||||
gboolean exists;
|
gboolean exists;
|
||||||
|
|
||||||
exists = FALSE;
|
exists = FALSE;
|
||||||
|
|
||||||
haystack = gtk_places_sidebar_list_shortcuts (GTK_PLACES_SIDEBAR (impl->places_sidebar));
|
haystack = gtk_places_sidebar_get_shortcuts (GTK_PLACES_SIDEBAR (impl->places_sidebar));
|
||||||
for (l = haystack; l; l = l->next)
|
n = g_list_model_get_n_items (haystack);
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
{
|
{
|
||||||
GFile *hay;
|
GFile *hay = g_list_model_get_item (haystack, i);
|
||||||
|
|
||||||
hay = G_FILE (l->data);
|
|
||||||
if (g_file_equal (hay, needle))
|
if (g_file_equal (hay, needle))
|
||||||
{
|
{
|
||||||
|
g_object_unref (hay);
|
||||||
exists = TRUE;
|
exists = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
g_object_unref (hay);
|
||||||
}
|
}
|
||||||
g_slist_free_full (haystack, g_object_unref);
|
g_object_unref (haystack);
|
||||||
|
|
||||||
return exists;
|
return exists;
|
||||||
}
|
}
|
||||||
@@ -5564,6 +5574,8 @@ gtk_file_chooser_widget_add_filter (GtkFileChooser *chooser,
|
|||||||
set_current_filter (impl, filter);
|
set_current_filter (impl, filter);
|
||||||
|
|
||||||
show_filters (impl, TRUE);
|
show_filters (impl, TRUE);
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (chooser), "filters");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -5597,25 +5609,16 @@ gtk_file_chooser_widget_remove_filter (GtkFileChooser *chooser,
|
|||||||
|
|
||||||
if (!impl->filters)
|
if (!impl->filters)
|
||||||
show_filters (impl, FALSE);
|
show_filters (impl, FALSE);
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (chooser), "filters");
|
||||||
}
|
}
|
||||||
|
|
||||||
static GSList *
|
static GListModel *
|
||||||
gtk_file_chooser_widget_list_filters (GtkFileChooser *chooser)
|
gtk_file_chooser_widget_get_filters (GtkFileChooser *chooser)
|
||||||
{
|
{
|
||||||
GtkFileChooserWidget *impl = GTK_FILE_CHOOSER_WIDGET (chooser);
|
GtkFileChooserWidget *impl = GTK_FILE_CHOOSER_WIDGET (chooser);
|
||||||
GSList *filters;
|
|
||||||
guint i;
|
|
||||||
|
|
||||||
filters = NULL;
|
return G_LIST_MODEL (g_object_ref (impl->filters));
|
||||||
|
|
||||||
for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (impl->filters)); i++)
|
|
||||||
{
|
|
||||||
GtkFileFilter *filter = g_list_model_get_item (G_LIST_MODEL (impl->filters), i);
|
|
||||||
filters = g_slist_append (filters, filter);
|
|
||||||
g_object_unref (filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
return filters;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@@ -5626,6 +5629,9 @@ gtk_file_chooser_widget_add_shortcut_folder (GtkFileChooser *chooser,
|
|||||||
GtkFileChooserWidget *impl = GTK_FILE_CHOOSER_WIDGET (chooser);
|
GtkFileChooserWidget *impl = GTK_FILE_CHOOSER_WIDGET (chooser);
|
||||||
|
|
||||||
gtk_places_sidebar_add_shortcut (GTK_PLACES_SIDEBAR (impl->places_sidebar), file);
|
gtk_places_sidebar_add_shortcut (GTK_PLACES_SIDEBAR (impl->places_sidebar), file);
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (chooser), "shortcut-folders");
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5637,15 +5643,18 @@ gtk_file_chooser_widget_remove_shortcut_folder (GtkFileChooser *chooser,
|
|||||||
GtkFileChooserWidget *impl = GTK_FILE_CHOOSER_WIDGET (chooser);
|
GtkFileChooserWidget *impl = GTK_FILE_CHOOSER_WIDGET (chooser);
|
||||||
|
|
||||||
gtk_places_sidebar_remove_shortcut (GTK_PLACES_SIDEBAR (impl->places_sidebar), file);
|
gtk_places_sidebar_remove_shortcut (GTK_PLACES_SIDEBAR (impl->places_sidebar), file);
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (chooser), "shortcut-folders");
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GSList *
|
static GListModel *
|
||||||
gtk_file_chooser_widget_list_shortcut_folders (GtkFileChooser *chooser)
|
gtk_file_chooser_widget_get_shortcut_folders (GtkFileChooser *chooser)
|
||||||
{
|
{
|
||||||
GtkFileChooserWidget *impl = GTK_FILE_CHOOSER_WIDGET (chooser);
|
GtkFileChooserWidget *impl = GTK_FILE_CHOOSER_WIDGET (chooser);
|
||||||
|
|
||||||
return gtk_places_sidebar_list_shortcuts (GTK_PLACES_SIDEBAR (impl->places_sidebar));
|
return gtk_places_sidebar_get_shortcuts (GTK_PLACES_SIDEBAR (impl->places_sidebar));
|
||||||
}
|
}
|
||||||
|
|
||||||
struct switch_folder_closure {
|
struct switch_folder_closure {
|
||||||
@@ -6933,6 +6942,8 @@ filter_combo_changed (GtkDropDown *dropdown,
|
|||||||
|
|
||||||
new_filter = gtk_drop_down_get_selected_item (dropdown);
|
new_filter = gtk_drop_down_get_selected_item (dropdown);
|
||||||
|
|
||||||
|
set_current_filter (impl, new_filter);
|
||||||
|
|
||||||
if (impl->location_entry != NULL)
|
if (impl->location_entry != NULL)
|
||||||
_gtk_file_chooser_entry_set_file_filter (GTK_FILE_CHOOSER_ENTRY (impl->location_entry),
|
_gtk_file_chooser_entry_set_file_filter (GTK_FILE_CHOOSER_ENTRY (impl->location_entry),
|
||||||
new_filter);
|
new_filter);
|
||||||
|
|||||||
+319
-356
@@ -18,15 +18,14 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION:gtkfilefilter
|
* SECTION:gtkfilefilter
|
||||||
* @Short_description: A filter for selecting a file subset
|
* @Short_description: Filtering files
|
||||||
* @Title: GtkFileFilter
|
* @Title: GtkFileFilter
|
||||||
* @see_also: #GtkFileChooser
|
* @see_also: #GtkFileChooser
|
||||||
*
|
*
|
||||||
* A GtkFileFilter can be used to restrict the files being shown in a
|
* A GtkFileFilter can be used to restrict the files being shown in a
|
||||||
* #GtkFileChooser. Files can be filtered based on their name (with
|
* #GtkFileChooser. Files can be filtered based on their name (with
|
||||||
* gtk_file_filter_add_pattern()), on their mime type (with
|
* gtk_file_filter_add_pattern()) or on their mime type (with
|
||||||
* gtk_file_filter_add_mime_type()), or by a custom filter function
|
* gtk_file_filter_add_mime_type()).
|
||||||
* (with gtk_file_filter_add_custom()).
|
|
||||||
*
|
*
|
||||||
* Filtering by mime types handles aliasing and subclassing of mime
|
* Filtering by mime types handles aliasing and subclassing of mime
|
||||||
* types; e.g. a filter for text/plain also matches a file with mime
|
* types; e.g. a filter for text/plain also matches a file with mime
|
||||||
@@ -34,16 +33,17 @@
|
|||||||
* text/plain. Note that #GtkFileFilter allows wildcards for the
|
* text/plain. Note that #GtkFileFilter allows wildcards for the
|
||||||
* subtype of a mime type, so you can e.g. filter for image/\*.
|
* subtype of a mime type, so you can e.g. filter for image/\*.
|
||||||
*
|
*
|
||||||
* Normally, filters are used by adding them to a #GtkFileChooser,
|
* Normally, file filters are used by adding them to a #GtkFileChooser
|
||||||
* see gtk_file_chooser_add_filter(), but it is also possible
|
* (see gtk_file_chooser_add_filter()), but it is also possible to
|
||||||
* to manually use a filter on a file with gtk_file_filter_filter().
|
* manually use a file filter on any #GtkFilterListModel containing
|
||||||
|
* #GFileInfo objects.
|
||||||
*
|
*
|
||||||
* # GtkFileFilter as GtkBuildable
|
* # GtkFileFilter as GtkBuildable
|
||||||
*
|
*
|
||||||
* The GtkFileFilter implementation of the GtkBuildable interface
|
* The GtkFileFilter implementation of the GtkBuildable interface
|
||||||
* supports adding rules using the <mime-types>, <patterns> and
|
* supports adding rules using the <mime-types> and <patterns>
|
||||||
* <applications> elements and listing the rules within. Specifying
|
* elements and listing the rules within. Specifying a <mime-type>
|
||||||
* a <mime-type> or <pattern> has the same effect as as calling
|
* or <pattern> has the same effect as as calling
|
||||||
* gtk_file_filter_add_mime_type() or gtk_file_filter_add_pattern().
|
* gtk_file_filter_add_mime_type() or gtk_file_filter_add_pattern().
|
||||||
*
|
*
|
||||||
* An example of a UI definition fragment specifying GtkFileFilter
|
* An example of a UI definition fragment specifying GtkFileFilter
|
||||||
@@ -73,6 +73,7 @@
|
|||||||
#include "gtkbuilderprivate.h"
|
#include "gtkbuilderprivate.h"
|
||||||
#include "gtkintl.h"
|
#include "gtkintl.h"
|
||||||
#include "gtkprivate.h"
|
#include "gtkprivate.h"
|
||||||
|
#include "gtkfilter.h"
|
||||||
|
|
||||||
typedef struct _GtkFileFilterClass GtkFileFilterClass;
|
typedef struct _GtkFileFilterClass GtkFileFilterClass;
|
||||||
typedef struct _FilterRule FilterRule;
|
typedef struct _FilterRule FilterRule;
|
||||||
@@ -84,39 +85,31 @@ typedef struct _FilterRule FilterRule;
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
FILTER_RULE_PATTERN,
|
FILTER_RULE_PATTERN,
|
||||||
FILTER_RULE_MIME_TYPE,
|
FILTER_RULE_MIME_TYPE,
|
||||||
FILTER_RULE_PIXBUF_FORMATS,
|
FILTER_RULE_PIXBUF_FORMATS
|
||||||
FILTER_RULE_CUSTOM
|
|
||||||
} FilterRuleType;
|
} FilterRuleType;
|
||||||
|
|
||||||
struct _GtkFileFilterClass
|
struct _GtkFileFilterClass
|
||||||
{
|
{
|
||||||
GInitiallyUnownedClass parent_class;
|
GtkFilterClass parent_class;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GtkFileFilter
|
struct _GtkFileFilter
|
||||||
{
|
{
|
||||||
GInitiallyUnowned parent_instance;
|
GtkFilter parent_instance;
|
||||||
|
|
||||||
gchar *name;
|
char *name;
|
||||||
GSList *rules;
|
GSList *rules;
|
||||||
|
|
||||||
GtkFileFilterFlags needed;
|
char **attributes;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _FilterRule
|
struct _FilterRule
|
||||||
{
|
{
|
||||||
FilterRuleType type;
|
FilterRuleType type;
|
||||||
GtkFileFilterFlags needed;
|
|
||||||
|
|
||||||
union {
|
union {
|
||||||
gchar *pattern;
|
char *pattern;
|
||||||
gchar *mime_type;
|
char **content_types;
|
||||||
GSList *pixbuf_formats;
|
|
||||||
struct {
|
|
||||||
GtkFileFilterFunc func;
|
|
||||||
gpointer data;
|
|
||||||
GDestroyNotify notify;
|
|
||||||
} custom;
|
|
||||||
} u;
|
} u;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -129,34 +122,14 @@ enum {
|
|||||||
static GParamSpec *props[NUM_PROPERTIES] = { NULL, };
|
static GParamSpec *props[NUM_PROPERTIES] = { NULL, };
|
||||||
|
|
||||||
|
|
||||||
static void gtk_file_filter_set_property (GObject *object,
|
static gboolean gtk_file_filter_match (GtkFilter *filter,
|
||||||
guint prop_id,
|
gpointer item);
|
||||||
const GValue *value,
|
static GtkFilterMatch gtk_file_filter_get_strictness (GtkFilter *filter);
|
||||||
GParamSpec *pspec);
|
|
||||||
static void gtk_file_filter_get_property (GObject *object,
|
static void gtk_file_filter_buildable_init (GtkBuildableIface *iface);
|
||||||
guint prop_id,
|
|
||||||
GValue *value,
|
|
||||||
GParamSpec *pspec);
|
|
||||||
|
|
||||||
|
|
||||||
static void gtk_file_filter_finalize (GObject *object);
|
G_DEFINE_TYPE_WITH_CODE (GtkFileFilter, gtk_file_filter, GTK_TYPE_FILTER,
|
||||||
|
|
||||||
|
|
||||||
static void gtk_file_filter_buildable_init (GtkBuildableIface *iface);
|
|
||||||
|
|
||||||
static gboolean gtk_file_filter_buildable_custom_tag_start (GtkBuildable *buildable,
|
|
||||||
GtkBuilder *builder,
|
|
||||||
GObject *child,
|
|
||||||
const gchar *tagname,
|
|
||||||
GtkBuildableParser *parser,
|
|
||||||
gpointer *data);
|
|
||||||
static void gtk_file_filter_buildable_custom_tag_end (GtkBuildable *buildable,
|
|
||||||
GtkBuilder *builder,
|
|
||||||
GObject *child,
|
|
||||||
const gchar *tagname,
|
|
||||||
gpointer data);
|
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_CODE (GtkFileFilter, gtk_file_filter, G_TYPE_INITIALLY_UNOWNED,
|
|
||||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
|
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
|
||||||
gtk_file_filter_buildable_init))
|
gtk_file_filter_buildable_init))
|
||||||
|
|
||||||
@@ -165,58 +138,6 @@ gtk_file_filter_init (GtkFileFilter *object)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
gtk_file_filter_class_init (GtkFileFilterClass *class)
|
|
||||||
{
|
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
|
|
||||||
|
|
||||||
gobject_class->set_property = gtk_file_filter_set_property;
|
|
||||||
gobject_class->get_property = gtk_file_filter_get_property;
|
|
||||||
gobject_class->finalize = gtk_file_filter_finalize;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GtkFileFilter:name:
|
|
||||||
*
|
|
||||||
* The human-readable name of the filter.
|
|
||||||
*
|
|
||||||
* This is the string that will be displayed in the file selector user
|
|
||||||
* interface if there is a selectable list of filters.
|
|
||||||
*/
|
|
||||||
props[PROP_NAME] =
|
|
||||||
g_param_spec_string ("name",
|
|
||||||
P_("Name"),
|
|
||||||
P_("The human-readable name for this filter"),
|
|
||||||
NULL,
|
|
||||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
|
|
||||||
|
|
||||||
g_object_class_install_properties (gobject_class, NUM_PROPERTIES, props);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
filter_rule_free (FilterRule *rule)
|
|
||||||
{
|
|
||||||
switch (rule->type)
|
|
||||||
{
|
|
||||||
case FILTER_RULE_MIME_TYPE:
|
|
||||||
g_free (rule->u.mime_type);
|
|
||||||
break;
|
|
||||||
case FILTER_RULE_PATTERN:
|
|
||||||
g_free (rule->u.pattern);
|
|
||||||
break;
|
|
||||||
case FILTER_RULE_CUSTOM:
|
|
||||||
if (rule->u.custom.notify)
|
|
||||||
rule->u.custom.notify (rule->u.custom.data);
|
|
||||||
break;
|
|
||||||
case FILTER_RULE_PIXBUF_FORMATS:
|
|
||||||
g_slist_free (rule->u.pixbuf_formats);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
g_assert_not_reached ();
|
|
||||||
}
|
|
||||||
|
|
||||||
g_slice_free (FilterRule, rule);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_file_filter_set_property (GObject *object,
|
gtk_file_filter_set_property (GObject *object,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
@@ -255,34 +176,80 @@ gtk_file_filter_get_property (GObject *object,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
filter_rule_free (FilterRule *rule)
|
||||||
|
{
|
||||||
|
switch (rule->type)
|
||||||
|
{
|
||||||
|
case FILTER_RULE_PATTERN:
|
||||||
|
g_free (rule->u.pattern);
|
||||||
|
break;
|
||||||
|
case FILTER_RULE_MIME_TYPE:
|
||||||
|
case FILTER_RULE_PIXBUF_FORMATS:
|
||||||
|
g_strfreev (rule->u.content_types);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
g_slice_free (FilterRule, rule);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_file_filter_finalize (GObject *object)
|
gtk_file_filter_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
GtkFileFilter *filter = GTK_FILE_FILTER (object);
|
GtkFileFilter *filter = GTK_FILE_FILTER (object);
|
||||||
|
|
||||||
g_slist_free_full (filter->rules, (GDestroyNotify)filter_rule_free);
|
g_slist_free_full (filter->rules, (GDestroyNotify)filter_rule_free);
|
||||||
|
g_strfreev (filter->attributes);
|
||||||
|
|
||||||
g_free (filter->name);
|
g_free (filter->name);
|
||||||
|
|
||||||
G_OBJECT_CLASS (gtk_file_filter_parent_class)->finalize (object);
|
G_OBJECT_CLASS (gtk_file_filter_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_file_filter_class_init (GtkFileFilterClass *class)
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
|
||||||
|
GtkFilterClass *filter_class = GTK_FILTER_CLASS (class);
|
||||||
|
|
||||||
|
gobject_class->set_property = gtk_file_filter_set_property;
|
||||||
|
gobject_class->get_property = gtk_file_filter_get_property;
|
||||||
|
gobject_class->finalize = gtk_file_filter_finalize;
|
||||||
|
|
||||||
|
filter_class->get_strictness = gtk_file_filter_get_strictness;
|
||||||
|
filter_class->match = gtk_file_filter_match;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GtkFileFilter:name:
|
||||||
|
*
|
||||||
|
* The human-readable name of the filter.
|
||||||
|
*
|
||||||
|
* This is the string that will be displayed in the file selector user
|
||||||
|
* interface if there is a selectable list of filters.
|
||||||
|
*/
|
||||||
|
props[PROP_NAME] =
|
||||||
|
g_param_spec_string ("name",
|
||||||
|
P_("Name"),
|
||||||
|
P_("The human-readable name for this filter"),
|
||||||
|
NULL,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
|
||||||
|
|
||||||
|
g_object_class_install_properties (gobject_class, NUM_PROPERTIES, props);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GtkBuildable implementation
|
* GtkBuildable implementation
|
||||||
*/
|
*/
|
||||||
static void
|
|
||||||
gtk_file_filter_buildable_init (GtkBuildableIface *iface)
|
|
||||||
{
|
|
||||||
iface->custom_tag_start = gtk_file_filter_buildable_custom_tag_start;
|
|
||||||
iface->custom_tag_end = gtk_file_filter_buildable_custom_tag_end;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum
|
||||||
|
{
|
||||||
PARSE_MIME_TYPES,
|
PARSE_MIME_TYPES,
|
||||||
PARSE_PATTERNS
|
PARSE_PATTERNS
|
||||||
} ParserType;
|
} ParserType;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct
|
||||||
|
{
|
||||||
GtkFileFilter *filter;
|
GtkFileFilter *filter;
|
||||||
GtkBuilder *builder;
|
GtkBuilder *builder;
|
||||||
ParserType type;
|
ParserType type;
|
||||||
@@ -292,9 +259,9 @@ typedef struct {
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
parser_start_element (GtkBuildableParseContext *context,
|
parser_start_element (GtkBuildableParseContext *context,
|
||||||
const gchar *element_name,
|
const char *element_name,
|
||||||
const gchar **names,
|
const char **names,
|
||||||
const gchar **values,
|
const char **values,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
@@ -337,11 +304,11 @@ parser_start_element (GtkBuildableParseContext *context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
parser_text_element (GtkBuildableParseContext *context,
|
parser_text_element (GtkBuildableParseContext *context,
|
||||||
const gchar *text,
|
const char *text,
|
||||||
gsize text_len,
|
gsize text_len,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
SubParserData *data = (SubParserData*)user_data;
|
SubParserData *data = (SubParserData*)user_data;
|
||||||
|
|
||||||
@@ -350,10 +317,10 @@ parser_text_element (GtkBuildableParseContext *context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
parser_end_element (GtkBuildableParseContext *context,
|
parser_end_element (GtkBuildableParseContext *context,
|
||||||
const gchar *element_name,
|
const char *element_name,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
SubParserData *data = (SubParserData*)user_data;
|
SubParserData *data = (SubParserData*)user_data;
|
||||||
|
|
||||||
@@ -387,7 +354,7 @@ static gboolean
|
|||||||
gtk_file_filter_buildable_custom_tag_start (GtkBuildable *buildable,
|
gtk_file_filter_buildable_custom_tag_start (GtkBuildable *buildable,
|
||||||
GtkBuilder *builder,
|
GtkBuilder *builder,
|
||||||
GObject *child,
|
GObject *child,
|
||||||
const gchar *tagname,
|
const char *tagname,
|
||||||
GtkBuildableParser *parser,
|
GtkBuildableParser *parser,
|
||||||
gpointer *parser_data)
|
gpointer *parser_data)
|
||||||
{
|
{
|
||||||
@@ -423,7 +390,7 @@ static void
|
|||||||
gtk_file_filter_buildable_custom_tag_end (GtkBuildable *buildable,
|
gtk_file_filter_buildable_custom_tag_end (GtkBuildable *buildable,
|
||||||
GtkBuilder *builder,
|
GtkBuilder *builder,
|
||||||
GObject *child,
|
GObject *child,
|
||||||
const gchar *tagname,
|
const char *tagname,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
if (strcmp (tagname, "mime-types") == 0 ||
|
if (strcmp (tagname, "mime-types") == 0 ||
|
||||||
@@ -436,16 +403,28 @@ gtk_file_filter_buildable_custom_tag_end (GtkBuildable *buildable,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_file_filter_buildable_init (GtkBuildableIface *iface)
|
||||||
|
{
|
||||||
|
iface->custom_tag_start = gtk_file_filter_buildable_custom_tag_start;
|
||||||
|
iface->custom_tag_end = gtk_file_filter_buildable_custom_tag_end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Public api
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gtk_file_filter_new:
|
* gtk_file_filter_new:
|
||||||
*
|
*
|
||||||
* Creates a new #GtkFileFilter with no rules added to it.
|
* Creates a new #GtkFileFilter with no rules added to it.
|
||||||
|
*
|
||||||
* Such a filter doesn’t accept any files, so is not
|
* Such a filter doesn’t accept any files, so is not
|
||||||
* particularly useful until you add rules with
|
* particularly useful until you add rules with
|
||||||
* gtk_file_filter_add_mime_type(), gtk_file_filter_add_pattern(),
|
* gtk_file_filter_add_mime_type(), gtk_file_filter_add_pattern(),
|
||||||
* or gtk_file_filter_add_custom(). To create a filter
|
* or gtk_file_filter_add_pixbuf_formats().
|
||||||
* that accepts any file, use:
|
*
|
||||||
|
* To create a filter that accepts any file, use:
|
||||||
* |[<!-- language="C" -->
|
* |[<!-- language="C" -->
|
||||||
* GtkFileFilter *filter = gtk_file_filter_new ();
|
* GtkFileFilter *filter = gtk_file_filter_new ();
|
||||||
* gtk_file_filter_add_pattern (filter, "*");
|
* gtk_file_filter_add_pattern (filter, "*");
|
||||||
@@ -465,13 +444,13 @@ gtk_file_filter_new (void)
|
|||||||
* @name: (allow-none): the human-readable-name for the filter, or %NULL
|
* @name: (allow-none): the human-readable-name for the filter, or %NULL
|
||||||
* to remove any existing name.
|
* to remove any existing name.
|
||||||
*
|
*
|
||||||
* Sets the human-readable name of the filter; this is the string
|
* Sets a human-readable name of the filter; this is the string
|
||||||
* that will be displayed in the file selector user interface if
|
* that will be displayed in the file chooser if there is a selectable
|
||||||
* there is a selectable list of filters.
|
* list of filters.
|
||||||
**/
|
**/
|
||||||
void
|
void
|
||||||
gtk_file_filter_set_name (GtkFileFilter *filter,
|
gtk_file_filter_set_name (GtkFileFilter *filter,
|
||||||
const gchar *name)
|
const char *name)
|
||||||
{
|
{
|
||||||
g_return_if_fail (GTK_IS_FILE_FILTER (filter));
|
g_return_if_fail (GTK_IS_FILE_FILTER (filter));
|
||||||
|
|
||||||
@@ -491,10 +470,10 @@ gtk_file_filter_set_name (GtkFileFilter *filter,
|
|||||||
* Gets the human-readable name for the filter. See gtk_file_filter_set_name().
|
* Gets the human-readable name for the filter. See gtk_file_filter_set_name().
|
||||||
*
|
*
|
||||||
* Returns: (nullable): The human-readable name of the filter,
|
* Returns: (nullable): The human-readable name of the filter,
|
||||||
* or %NULL. This value is owned by GTK+ and must not
|
* or %NULL. This value is owned by GTK and must not
|
||||||
* be modified or freed.
|
* be modified or freed.
|
||||||
**/
|
**/
|
||||||
const gchar *
|
const char *
|
||||||
gtk_file_filter_get_name (GtkFileFilter *filter)
|
gtk_file_filter_get_name (GtkFileFilter *filter)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (GTK_IS_FILE_FILTER (filter), NULL);
|
g_return_val_if_fail (GTK_IS_FILE_FILTER (filter), NULL);
|
||||||
@@ -504,10 +483,31 @@ gtk_file_filter_get_name (GtkFileFilter *filter)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
file_filter_add_rule (GtkFileFilter *filter,
|
file_filter_add_rule (GtkFileFilter *filter,
|
||||||
FilterRule *rule)
|
FilterRule *rule)
|
||||||
{
|
{
|
||||||
filter->needed |= rule->needed;
|
|
||||||
filter->rules = g_slist_append (filter->rules, rule);
|
filter->rules = g_slist_append (filter->rules, rule);
|
||||||
|
|
||||||
|
gtk_filter_changed (GTK_FILTER (filter), GTK_FILTER_CHANGE_LESS_STRICT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
file_filter_add_attribute (GtkFileFilter *filter,
|
||||||
|
const char *attribute)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (filter->attributes)
|
||||||
|
for (i = 0; filter->attributes[i]; i++)
|
||||||
|
{
|
||||||
|
if (strcmp (filter->attributes[i], attribute) == 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
filter->attributes = (char **)g_renew (char **, filter->attributes, i + 2);
|
||||||
|
filter->attributes[i] = g_strdup (attribute);
|
||||||
|
filter->attributes[i + 1] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -519,7 +519,7 @@ file_filter_add_rule (GtkFileFilter *filter,
|
|||||||
**/
|
**/
|
||||||
void
|
void
|
||||||
gtk_file_filter_add_mime_type (GtkFileFilter *filter,
|
gtk_file_filter_add_mime_type (GtkFileFilter *filter,
|
||||||
const gchar *mime_type)
|
const char *mime_type)
|
||||||
{
|
{
|
||||||
FilterRule *rule;
|
FilterRule *rule;
|
||||||
|
|
||||||
@@ -528,9 +528,10 @@ gtk_file_filter_add_mime_type (GtkFileFilter *filter,
|
|||||||
|
|
||||||
rule = g_slice_new (FilterRule);
|
rule = g_slice_new (FilterRule);
|
||||||
rule->type = FILTER_RULE_MIME_TYPE;
|
rule->type = FILTER_RULE_MIME_TYPE;
|
||||||
rule->needed = GTK_FILE_FILTER_MIME_TYPE;
|
rule->u.content_types = g_new0 (char *, 2);
|
||||||
rule->u.mime_type = g_strdup (mime_type);
|
rule->u.content_types[0] = g_content_type_from_mime_type (mime_type);
|
||||||
|
|
||||||
|
file_filter_add_attribute (filter, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE);
|
||||||
file_filter_add_rule (filter, rule);
|
file_filter_add_rule (filter, rule);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -543,7 +544,7 @@ gtk_file_filter_add_mime_type (GtkFileFilter *filter,
|
|||||||
**/
|
**/
|
||||||
void
|
void
|
||||||
gtk_file_filter_add_pattern (GtkFileFilter *filter,
|
gtk_file_filter_add_pattern (GtkFileFilter *filter,
|
||||||
const gchar *pattern)
|
const char *pattern)
|
||||||
{
|
{
|
||||||
FilterRule *rule;
|
FilterRule *rule;
|
||||||
|
|
||||||
@@ -552,9 +553,9 @@ gtk_file_filter_add_pattern (GtkFileFilter *filter,
|
|||||||
|
|
||||||
rule = g_slice_new (FilterRule);
|
rule = g_slice_new (FilterRule);
|
||||||
rule->type = FILTER_RULE_PATTERN;
|
rule->type = FILTER_RULE_PATTERN;
|
||||||
rule->needed = GTK_FILE_FILTER_DISPLAY_NAME;
|
|
||||||
rule->u.pattern = g_strdup (pattern);
|
rule->u.pattern = g_strdup (pattern);
|
||||||
|
|
||||||
|
file_filter_add_attribute (filter, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME);
|
||||||
file_filter_add_rule (filter, rule);
|
file_filter_add_rule (filter, rule);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -564,78 +565,64 @@ gtk_file_filter_add_pattern (GtkFileFilter *filter,
|
|||||||
*
|
*
|
||||||
* Adds a rule allowing image files in the formats supported
|
* Adds a rule allowing image files in the formats supported
|
||||||
* by GdkPixbuf.
|
* by GdkPixbuf.
|
||||||
|
*
|
||||||
|
* This is equivalent to calling gtk_file_filter_add_mime_type()
|
||||||
|
* for all the supported mime types.
|
||||||
**/
|
**/
|
||||||
void
|
void
|
||||||
gtk_file_filter_add_pixbuf_formats (GtkFileFilter *filter)
|
gtk_file_filter_add_pixbuf_formats (GtkFileFilter *filter)
|
||||||
{
|
{
|
||||||
FilterRule *rule;
|
FilterRule *rule;
|
||||||
|
GPtrArray *array;
|
||||||
|
GSList *formats, *l;
|
||||||
|
|
||||||
g_return_if_fail (GTK_IS_FILE_FILTER (filter));
|
g_return_if_fail (GTK_IS_FILE_FILTER (filter));
|
||||||
|
|
||||||
rule = g_slice_new (FilterRule);
|
rule = g_slice_new (FilterRule);
|
||||||
rule->type = FILTER_RULE_PIXBUF_FORMATS;
|
rule->type = FILTER_RULE_PIXBUF_FORMATS;
|
||||||
rule->needed = GTK_FILE_FILTER_MIME_TYPE;
|
|
||||||
rule->u.pixbuf_formats = gdk_pixbuf_get_formats ();
|
|
||||||
file_filter_add_rule (filter, rule);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
array = g_ptr_array_new ();
|
||||||
|
|
||||||
/**
|
formats = gdk_pixbuf_get_formats ();
|
||||||
* gtk_file_filter_add_custom:
|
for (l = formats; l; l = l->next)
|
||||||
* @filter: a #GtkFileFilter
|
{
|
||||||
* @needed: bitfield of flags indicating the information that the custom
|
int i;
|
||||||
* filter function needs.
|
char **mime_types;
|
||||||
* @func: callback function; if the function returns %TRUE, then
|
|
||||||
* the file will be displayed.
|
|
||||||
* @data: data to pass to @func
|
|
||||||
* @notify: function to call to free @data when it is no longer needed.
|
|
||||||
*
|
|
||||||
* Adds rule to a filter that allows files based on a custom callback
|
|
||||||
* function. The bitfield @needed which is passed in provides information
|
|
||||||
* about what sorts of information that the filter function needs;
|
|
||||||
* this allows GTK+ to avoid retrieving expensive information when
|
|
||||||
* it isn’t needed by the filter.
|
|
||||||
**/
|
|
||||||
void
|
|
||||||
gtk_file_filter_add_custom (GtkFileFilter *filter,
|
|
||||||
GtkFileFilterFlags needed,
|
|
||||||
GtkFileFilterFunc func,
|
|
||||||
gpointer data,
|
|
||||||
GDestroyNotify notify)
|
|
||||||
{
|
|
||||||
FilterRule *rule;
|
|
||||||
|
|
||||||
g_return_if_fail (GTK_IS_FILE_FILTER (filter));
|
mime_types = gdk_pixbuf_format_get_mime_types (l->data);
|
||||||
g_return_if_fail (func != NULL);
|
|
||||||
|
|
||||||
rule = g_slice_new (FilterRule);
|
for (i = 0; mime_types[i] != NULL; i++)
|
||||||
rule->type = FILTER_RULE_CUSTOM;
|
{
|
||||||
rule->needed = needed;
|
g_ptr_array_add (array, g_content_type_from_mime_type (mime_types[i]));
|
||||||
rule->u.custom.func = func;
|
}
|
||||||
rule->u.custom.data = data;
|
}
|
||||||
rule->u.custom.notify = notify;
|
g_slist_free (formats);
|
||||||
|
|
||||||
|
g_ptr_array_add (array, NULL);
|
||||||
|
|
||||||
|
rule->u.content_types = (char **)g_ptr_array_free (array, FALSE);
|
||||||
|
|
||||||
|
file_filter_add_attribute (filter, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE);
|
||||||
file_filter_add_rule (filter, rule);
|
file_filter_add_rule (filter, rule);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gtk_file_filter_get_needed:
|
* gtk_file_filter_get_attributes:
|
||||||
* @filter: a #GtkFileFilter
|
* @filter: a #GtkFileFilter
|
||||||
*
|
*
|
||||||
* Gets the fields that need to be filled in for the #GtkFileFilterInfo
|
* Gets the attributes that need to be filled in for the #GFileInfo
|
||||||
* passed to gtk_file_filter_filter()
|
* passed to gtk_file_filter_filter()
|
||||||
*
|
*
|
||||||
* This function will not typically be used by applications; it
|
* This function will not typically be used by applications;
|
||||||
* is intended principally for use in the implementation of
|
* it is intended principally for use in the implementation
|
||||||
* #GtkFileChooser.
|
* of #GtkFileChooser.
|
||||||
*
|
*
|
||||||
* Returns: bitfield of flags indicating needed fields when
|
* Returns: (transfer none): the attributes
|
||||||
* calling gtk_file_filter_filter()
|
|
||||||
**/
|
**/
|
||||||
GtkFileFilterFlags
|
const char **
|
||||||
gtk_file_filter_get_needed (GtkFileFilter *filter)
|
gtk_file_filter_get_attributes (GtkFileFilter *filter)
|
||||||
{
|
{
|
||||||
return filter->needed;
|
return (const char **)filter->attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef GDK_WINDOWING_QUARTZ
|
#ifdef GDK_WINDOWING_QUARTZ
|
||||||
@@ -652,72 +639,72 @@ NSArray * _gtk_file_filter_get_as_pattern_nsstrings (GtkFileFilter *filter)
|
|||||||
FilterRule *rule = tmp_list->data;
|
FilterRule *rule = tmp_list->data;
|
||||||
|
|
||||||
switch (rule->type)
|
switch (rule->type)
|
||||||
{
|
{
|
||||||
case FILTER_RULE_CUSTOM:
|
case FILTER_RULE_MIME_TYPE:
|
||||||
[array release];
|
{
|
||||||
return NULL;
|
// convert mime-types to UTI
|
||||||
break;
|
NSString *mime_type_nsstring = [NSString stringWithUTF8String: rule->u.content_types[0]];
|
||||||
case FILTER_RULE_MIME_TYPE:
|
NSString *uti_nsstring = (NSString *) UTTypeCreatePreferredIdentifierForTag (kUTTagClassMIMEType, (CFStringRef) mime_type_nsstring, NULL);
|
||||||
{
|
if (uti_nsstring == NULL)
|
||||||
// convert mime-types to UTI
|
{
|
||||||
NSString *mime_type_nsstring = [NSString stringWithUTF8String: rule->u.mime_type];
|
[array release];
|
||||||
NSString *uti_nsstring = (NSString *) UTTypeCreatePreferredIdentifierForTag (kUTTagClassMIMEType, (CFStringRef) mime_type_nsstring, NULL);
|
return NULL;
|
||||||
if (uti_nsstring == NULL)
|
}
|
||||||
{
|
[array addObject:uti_nsstring];
|
||||||
[array release];
|
}
|
||||||
return NULL;
|
break;
|
||||||
}
|
|
||||||
[array addObject:uti_nsstring];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case FILTER_RULE_PATTERN:
|
|
||||||
{
|
|
||||||
// patterns will need to be stripped of their leading *.
|
|
||||||
GString *pattern = g_string_new (rule->u.pattern);
|
|
||||||
if (strncmp (pattern->str, "*.", 2) == 0)
|
|
||||||
{
|
|
||||||
pattern = g_string_erase (pattern, 0, 2);
|
|
||||||
}
|
|
||||||
else if (strncmp (pattern->str, "*", 1) == 0)
|
|
||||||
{
|
|
||||||
pattern = g_string_erase (pattern, 0, 1);
|
|
||||||
}
|
|
||||||
gchar *pattern_c = g_string_free (pattern, FALSE);
|
|
||||||
NSString *pattern_nsstring = [NSString stringWithUTF8String:pattern_c];
|
|
||||||
g_free (pattern_c);
|
|
||||||
[pattern_nsstring retain];
|
|
||||||
[array addObject:pattern_nsstring];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case FILTER_RULE_PIXBUF_FORMATS:
|
|
||||||
{
|
|
||||||
GSList *list;
|
|
||||||
|
|
||||||
for (list = rule->u.pixbuf_formats; list; list = list->next)
|
case FILTER_RULE_PATTERN:
|
||||||
{
|
{
|
||||||
int i;
|
// patterns will need to be stripped of their leading *.
|
||||||
gchar **extensions;
|
GString *pattern = g_string_new (rule->u.pattern);
|
||||||
|
if (strncmp (pattern->str, "*.", 2) == 0)
|
||||||
|
{
|
||||||
|
pattern = g_string_erase (pattern, 0, 2);
|
||||||
|
}
|
||||||
|
else if (strncmp (pattern->str, "*", 1) == 0)
|
||||||
|
{
|
||||||
|
pattern = g_string_erase (pattern, 0, 1);
|
||||||
|
}
|
||||||
|
gchar *pattern_c = g_string_free (pattern, FALSE);
|
||||||
|
NSString *pattern_nsstring = [NSString stringWithUTF8String:pattern_c];
|
||||||
|
g_free (pattern_c);
|
||||||
|
[pattern_nsstring retain];
|
||||||
|
[array addObject:pattern_nsstring];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
extensions = gdk_pixbuf_format_get_extensions (list->data);
|
case FILTER_RULE_PIXBUF_FORMATS:
|
||||||
|
{
|
||||||
|
GSList *formats, *l;
|
||||||
|
|
||||||
for (i = 0; extensions[i] != NULL; i++)
|
formats = gdk_pixbuf_get_formats ();
|
||||||
{
|
for (l = formats; l; l = l->next)
|
||||||
NSString *extension = [NSString stringWithUTF8String: extensions[i]];
|
{
|
||||||
[extension retain];
|
int i;
|
||||||
[array addObject:extension];
|
gchar **extensions;
|
||||||
}
|
|
||||||
g_strfreev (extensions);
|
extensions = gdk_pixbuf_format_get_extensions (l->data);
|
||||||
}
|
|
||||||
break;
|
for (i = 0; extensions[i] != NULL; i++)
|
||||||
}
|
{
|
||||||
}
|
NSString *extension = [NSString stringWithUTF8String: extensions[i]];
|
||||||
|
[extension retain];
|
||||||
|
[array addObject:extension];
|
||||||
|
}
|
||||||
|
g_strfreev (extensions);
|
||||||
|
}
|
||||||
|
g_slist_free (formats);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
char **
|
char **
|
||||||
_gtk_file_filter_get_as_patterns (GtkFileFilter *filter)
|
_gtk_file_filter_get_as_patterns (GtkFileFilter *filter)
|
||||||
{
|
{
|
||||||
GPtrArray *array;
|
GPtrArray *array;
|
||||||
GSList *tmp_list;
|
GSList *tmp_list;
|
||||||
@@ -729,131 +716,120 @@ _gtk_file_filter_get_as_patterns (GtkFileFilter *filter)
|
|||||||
FilterRule *rule = tmp_list->data;
|
FilterRule *rule = tmp_list->data;
|
||||||
|
|
||||||
switch (rule->type)
|
switch (rule->type)
|
||||||
{
|
{
|
||||||
case FILTER_RULE_CUSTOM:
|
case FILTER_RULE_MIME_TYPE:
|
||||||
case FILTER_RULE_MIME_TYPE:
|
|
||||||
g_ptr_array_free (array, TRUE);
|
g_ptr_array_free (array, TRUE);
|
||||||
return NULL;
|
return NULL;
|
||||||
break;
|
break;
|
||||||
case FILTER_RULE_PATTERN:
|
|
||||||
|
case FILTER_RULE_PATTERN:
|
||||||
g_ptr_array_add (array, g_strdup (rule->u.pattern));
|
g_ptr_array_add (array, g_strdup (rule->u.pattern));
|
||||||
break;
|
break;
|
||||||
case FILTER_RULE_PIXBUF_FORMATS:
|
|
||||||
{
|
|
||||||
GSList *list;
|
|
||||||
|
|
||||||
for (list = rule->u.pixbuf_formats; list; list = list->next)
|
case FILTER_RULE_PIXBUF_FORMATS:
|
||||||
{
|
{
|
||||||
int i;
|
GSList *formats, *l;
|
||||||
gchar **extensions;
|
|
||||||
|
|
||||||
extensions = gdk_pixbuf_format_get_extensions (list->data);
|
formats = gdk_pixbuf_get_formats ();
|
||||||
|
for (l = formats; l; l = l->next)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char **extensions;
|
||||||
|
|
||||||
for (i = 0; extensions[i] != NULL; i++)
|
extensions = gdk_pixbuf_format_get_extensions (l->data);
|
||||||
|
|
||||||
|
for (i = 0; extensions[i] != NULL; i++)
|
||||||
g_ptr_array_add (array, g_strdup_printf ("*.%s", extensions[i]));
|
g_ptr_array_add (array, g_strdup_printf ("*.%s", extensions[i]));
|
||||||
|
|
||||||
g_strfreev (extensions);
|
g_strfreev (extensions);
|
||||||
}
|
}
|
||||||
break;
|
g_slist_free (formats);
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_ptr_array_add (array, NULL); /* Null terminate */
|
g_ptr_array_add (array, NULL); /* Null terminate */
|
||||||
return (char **)g_ptr_array_free (array, FALSE);
|
return (char **)g_ptr_array_free (array, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static GtkFilterMatch
|
||||||
* gtk_file_filter_filter:
|
gtk_file_filter_get_strictness (GtkFilter *filter)
|
||||||
* @filter: a #GtkFileFilter
|
|
||||||
* @filter_info: a #GtkFileFilterInfo containing information
|
|
||||||
* about a file.
|
|
||||||
*
|
|
||||||
* Tests whether a file should be displayed according to @filter.
|
|
||||||
* The #GtkFileFilterInfo @filter_info should include
|
|
||||||
* the fields returned from gtk_file_filter_get_needed().
|
|
||||||
*
|
|
||||||
* This function will not typically be used by applications; it
|
|
||||||
* is intended principally for use in the implementation of
|
|
||||||
* #GtkFileChooser.
|
|
||||||
*
|
|
||||||
* Returns: %TRUE if the file should be displayed
|
|
||||||
**/
|
|
||||||
gboolean
|
|
||||||
gtk_file_filter_filter (GtkFileFilter *filter,
|
|
||||||
const GtkFileFilterInfo *filter_info)
|
|
||||||
{
|
{
|
||||||
|
GtkFileFilter *file_filter = GTK_FILE_FILTER (filter);
|
||||||
|
|
||||||
|
/* Handle only the documented cases for 'match all'
|
||||||
|
* and match none. There are of course other ways to
|
||||||
|
* make filters that do this.
|
||||||
|
*/
|
||||||
|
if (file_filter->rules == NULL)
|
||||||
|
return GTK_FILTER_MATCH_NONE;
|
||||||
|
|
||||||
|
if (file_filter->rules->next == NULL)
|
||||||
|
{
|
||||||
|
FilterRule *rule = file_filter->rules->data;
|
||||||
|
if (rule->type == FILTER_RULE_PATTERN &&
|
||||||
|
strcmp (rule->u.pattern, "*") == 0)
|
||||||
|
return GTK_FILTER_MATCH_ALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GTK_FILTER_MATCH_SOME;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gtk_file_filter_match (GtkFilter *filter,
|
||||||
|
gpointer item)
|
||||||
|
{
|
||||||
|
GtkFileFilter *file_filter = GTK_FILE_FILTER (filter);
|
||||||
|
GFileInfo *info = item;
|
||||||
GSList *tmp_list;
|
GSList *tmp_list;
|
||||||
|
|
||||||
for (tmp_list = filter->rules; tmp_list; tmp_list = tmp_list->next)
|
if (!G_IS_FILE_INFO (item))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
for (tmp_list = file_filter->rules; tmp_list; tmp_list = tmp_list->next)
|
||||||
{
|
{
|
||||||
FilterRule *rule = tmp_list->data;
|
FilterRule *rule = tmp_list->data;
|
||||||
|
|
||||||
if ((filter_info->contains & rule->needed) != rule->needed)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
switch (rule->type)
|
switch (rule->type)
|
||||||
{
|
{
|
||||||
case FILTER_RULE_MIME_TYPE:
|
case FILTER_RULE_PATTERN:
|
||||||
if (filter_info->mime_type != NULL)
|
{
|
||||||
{
|
const char *display_name;
|
||||||
gchar *filter_content_type, *rule_content_type;
|
|
||||||
gboolean match;
|
|
||||||
|
|
||||||
filter_content_type = g_content_type_from_mime_type (filter_info->mime_type);
|
display_name = g_file_info_get_display_name (info);
|
||||||
rule_content_type = g_content_type_from_mime_type (rule->u.mime_type);
|
if (display_name)
|
||||||
match = filter_content_type != NULL &&
|
{
|
||||||
rule_content_type != NULL &&
|
if (_gtk_fnmatch (rule->u.pattern, display_name, FALSE))
|
||||||
g_content_type_is_a (filter_content_type, rule_content_type);
|
return TRUE;
|
||||||
g_free (filter_content_type);
|
}
|
||||||
g_free (rule_content_type);
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
if (match)
|
case FILTER_RULE_MIME_TYPE:
|
||||||
return TRUE;
|
case FILTER_RULE_PIXBUF_FORMATS:
|
||||||
}
|
{
|
||||||
break;
|
const char *filter_content_type;
|
||||||
case FILTER_RULE_PATTERN:
|
|
||||||
if (filter_info->display_name != NULL &&
|
|
||||||
_gtk_fnmatch (rule->u.pattern, filter_info->display_name, FALSE))
|
|
||||||
return TRUE;
|
|
||||||
break;
|
|
||||||
case FILTER_RULE_PIXBUF_FORMATS:
|
|
||||||
{
|
|
||||||
GSList *list;
|
|
||||||
|
|
||||||
if (!filter_info->mime_type)
|
filter_content_type = g_file_info_get_content_type (info);
|
||||||
break;
|
if (filter_content_type)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
for (list = rule->u.pixbuf_formats; list; list = list->next)
|
for (i = 0; rule->u.content_types[i]; i++)
|
||||||
{
|
{
|
||||||
int i;
|
if (g_content_type_is_a (filter_content_type, rule->u.content_types[i]))
|
||||||
gchar **mime_types;
|
return TRUE;
|
||||||
|
}
|
||||||
mime_types = gdk_pixbuf_format_get_mime_types (list->data);
|
}
|
||||||
|
}
|
||||||
for (i = 0; mime_types[i] != NULL; i++)
|
break;
|
||||||
{
|
|
||||||
if (strcmp (mime_types[i], filter_info->mime_type) == 0)
|
|
||||||
{
|
|
||||||
g_strfreev (mime_types);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
g_strfreev (mime_types);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case FILTER_RULE_CUSTOM:
|
|
||||||
if (rule->u.custom.func (filter_info, rule->u.custom.data))
|
|
||||||
return TRUE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -877,33 +853,20 @@ gtk_file_filter_to_gvariant (GtkFileFilter *filter)
|
|||||||
for (l = filter->rules; l; l = l->next)
|
for (l = filter->rules; l; l = l->next)
|
||||||
{
|
{
|
||||||
FilterRule *rule = l->data;
|
FilterRule *rule = l->data;
|
||||||
|
int i;
|
||||||
|
|
||||||
switch (rule->type)
|
switch (rule->type)
|
||||||
{
|
{
|
||||||
case FILTER_RULE_PATTERN:
|
case FILTER_RULE_PATTERN:
|
||||||
g_variant_builder_add (&builder, "(us)", 0, rule->u.pattern);
|
g_variant_builder_add (&builder, "(us)", 0, rule->u.pattern);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FILTER_RULE_MIME_TYPE:
|
case FILTER_RULE_MIME_TYPE:
|
||||||
g_variant_builder_add (&builder, "(us)", 1, rule->u.mime_type);
|
|
||||||
break;
|
|
||||||
case FILTER_RULE_PIXBUF_FORMATS:
|
case FILTER_RULE_PIXBUF_FORMATS:
|
||||||
{
|
for (i = 0; rule->u.content_types[i]; i++)
|
||||||
GSList *f;
|
g_variant_builder_add (&builder, "(us)", 1, rule->u.content_types[i]);
|
||||||
|
|
||||||
for (f = rule->u.pixbuf_formats; f; f = f->next)
|
|
||||||
{
|
|
||||||
GdkPixbufFormat *fmt = f->data;
|
|
||||||
gchar **mime_types;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
mime_types = gdk_pixbuf_format_get_mime_types (fmt);
|
|
||||||
for (i = 0; mime_types[i]; i++)
|
|
||||||
g_variant_builder_add (&builder, "(us)", 1, mime_types[i]);
|
|
||||||
g_strfreev (mime_types);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case FILTER_RULE_CUSTOM:
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-78
@@ -33,99 +33,34 @@ G_BEGIN_DECLS
|
|||||||
#define GTK_IS_FILE_FILTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_FILE_FILTER))
|
#define GTK_IS_FILE_FILTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_FILE_FILTER))
|
||||||
|
|
||||||
typedef struct _GtkFileFilter GtkFileFilter;
|
typedef struct _GtkFileFilter GtkFileFilter;
|
||||||
typedef struct _GtkFileFilterInfo GtkFileFilterInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GtkFileFilterFlags:
|
|
||||||
* @GTK_FILE_FILTER_FILENAME: the filename of the file being tested
|
|
||||||
* @GTK_FILE_FILTER_URI: the URI for the file being tested
|
|
||||||
* @GTK_FILE_FILTER_DISPLAY_NAME: the string that will be used to
|
|
||||||
* display the file in the file chooser
|
|
||||||
* @GTK_FILE_FILTER_MIME_TYPE: the mime type of the file
|
|
||||||
*
|
|
||||||
* These flags indicate what parts of a #GtkFileFilterInfo struct
|
|
||||||
* are filled or need to be filled.
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
GTK_FILE_FILTER_FILENAME = 1 << 0,
|
|
||||||
GTK_FILE_FILTER_URI = 1 << 1,
|
|
||||||
GTK_FILE_FILTER_DISPLAY_NAME = 1 << 2,
|
|
||||||
GTK_FILE_FILTER_MIME_TYPE = 1 << 3
|
|
||||||
} GtkFileFilterFlags;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GtkFileFilterFunc:
|
|
||||||
* @filter_info: a #GtkFileFilterInfo that is filled according
|
|
||||||
* to the @needed flags passed to gtk_file_filter_add_custom()
|
|
||||||
* @data: (closure): user data passed to gtk_file_filter_add_custom()
|
|
||||||
*
|
|
||||||
* The type of function that is used with custom filters, see
|
|
||||||
* gtk_file_filter_add_custom().
|
|
||||||
*
|
|
||||||
* Returns: %TRUE if the file should be displayed
|
|
||||||
*/
|
|
||||||
typedef gboolean (*GtkFileFilterFunc) (const GtkFileFilterInfo *filter_info,
|
|
||||||
gpointer data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GtkFileFilterInfo:
|
|
||||||
* @contains: Flags indicating which of the following fields need
|
|
||||||
* are filled
|
|
||||||
* @filename: the filename of the file being tested
|
|
||||||
* @uri: the URI for the file being tested
|
|
||||||
* @display_name: the string that will be used to display the file
|
|
||||||
* in the file chooser
|
|
||||||
* @mime_type: the mime type of the file
|
|
||||||
*
|
|
||||||
* A #GtkFileFilterInfo is used to pass information about the
|
|
||||||
* tested file to gtk_file_filter_filter().
|
|
||||||
*/
|
|
||||||
struct _GtkFileFilterInfo
|
|
||||||
{
|
|
||||||
GtkFileFilterFlags contains;
|
|
||||||
|
|
||||||
const gchar *filename;
|
|
||||||
const gchar *uri;
|
|
||||||
const gchar *display_name;
|
|
||||||
const gchar *mime_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
GType gtk_file_filter_get_type (void) G_GNUC_CONST;
|
GType gtk_file_filter_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
GtkFileFilter * gtk_file_filter_new (void);
|
GtkFileFilter * gtk_file_filter_new (void);
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
void gtk_file_filter_set_name (GtkFileFilter *filter,
|
void gtk_file_filter_set_name (GtkFileFilter *filter,
|
||||||
const gchar *name);
|
const char *name);
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
const gchar * gtk_file_filter_get_name (GtkFileFilter *filter);
|
const char * gtk_file_filter_get_name (GtkFileFilter *filter);
|
||||||
|
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
void gtk_file_filter_add_mime_type (GtkFileFilter *filter,
|
void gtk_file_filter_add_mime_type (GtkFileFilter *filter,
|
||||||
const gchar *mime_type);
|
const char *mime_type);
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
void gtk_file_filter_add_pattern (GtkFileFilter *filter,
|
void gtk_file_filter_add_pattern (GtkFileFilter *filter,
|
||||||
const gchar *pattern);
|
const char *pattern);
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
void gtk_file_filter_add_pixbuf_formats (GtkFileFilter *filter);
|
void gtk_file_filter_add_pixbuf_formats (GtkFileFilter *filter);
|
||||||
GDK_AVAILABLE_IN_ALL
|
|
||||||
void gtk_file_filter_add_custom (GtkFileFilter *filter,
|
|
||||||
GtkFileFilterFlags needed,
|
|
||||||
GtkFileFilterFunc func,
|
|
||||||
gpointer data,
|
|
||||||
GDestroyNotify notify);
|
|
||||||
|
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
GtkFileFilterFlags gtk_file_filter_get_needed (GtkFileFilter *filter);
|
const char ** gtk_file_filter_get_attributes (GtkFileFilter *filter);
|
||||||
GDK_AVAILABLE_IN_ALL
|
|
||||||
gboolean gtk_file_filter_filter (GtkFileFilter *filter,
|
|
||||||
const GtkFileFilterInfo *filter_info);
|
|
||||||
|
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
GVariant *gtk_file_filter_to_gvariant (GtkFileFilter *filter);
|
GVariant * gtk_file_filter_to_gvariant (GtkFileFilter *filter);
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
GtkFileFilter *gtk_file_filter_new_from_gvariant (GVariant *variant);
|
GtkFileFilter * gtk_file_filter_new_from_gvariant (GVariant *variant);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#include "gtktreedatalist.h"
|
#include "gtktreedatalist.h"
|
||||||
#include "gtktreednd.h"
|
#include "gtktreednd.h"
|
||||||
#include "gtktreemodel.h"
|
#include "gtktreemodel.h"
|
||||||
|
#include "gtkfilter.h"
|
||||||
|
|
||||||
/*** Structure: how GtkFileSystemModel works
|
/*** Structure: how GtkFileSystemModel works
|
||||||
*
|
*
|
||||||
@@ -375,12 +376,6 @@ static gboolean
|
|||||||
node_should_be_filtered_out (GtkFileSystemModel *model, guint id)
|
node_should_be_filtered_out (GtkFileSystemModel *model, guint id)
|
||||||
{
|
{
|
||||||
FileModelNode *node = get_node (model, id);
|
FileModelNode *node = get_node (model, id);
|
||||||
GtkFileFilterInfo filter_info = { 0, };
|
|
||||||
GtkFileFilterFlags required;
|
|
||||||
gboolean result;
|
|
||||||
char *mime_type = NULL;
|
|
||||||
char *filename = NULL;
|
|
||||||
char *uri = NULL;
|
|
||||||
|
|
||||||
if (node->info == NULL)
|
if (node->info == NULL)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@@ -388,57 +383,10 @@ node_should_be_filtered_out (GtkFileSystemModel *model, guint id)
|
|||||||
if (model->filter == NULL)
|
if (model->filter == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* fill info */
|
if (!g_file_info_has_attribute (node->info, "standard::file"))
|
||||||
required = gtk_file_filter_get_needed (model->filter);
|
g_file_info_set_attribute_object (node->info, "standard::file", G_OBJECT (node->file));
|
||||||
|
|
||||||
filter_info.contains = GTK_FILE_FILTER_DISPLAY_NAME;
|
return !gtk_filter_match (GTK_FILTER (model->filter), node->info);
|
||||||
filter_info.display_name = g_file_info_get_display_name (node->info);
|
|
||||||
|
|
||||||
if (required & GTK_FILE_FILTER_MIME_TYPE)
|
|
||||||
{
|
|
||||||
const char *s = g_file_info_get_content_type (node->info);
|
|
||||||
|
|
||||||
if (!s)
|
|
||||||
s = g_file_info_get_attribute_string (node->info, G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE);
|
|
||||||
|
|
||||||
if (s)
|
|
||||||
{
|
|
||||||
mime_type = g_content_type_get_mime_type (s);
|
|
||||||
if (mime_type)
|
|
||||||
{
|
|
||||||
filter_info.mime_type = mime_type;
|
|
||||||
filter_info.contains |= GTK_FILE_FILTER_MIME_TYPE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (required & GTK_FILE_FILTER_FILENAME)
|
|
||||||
{
|
|
||||||
filename = g_file_get_path (node->file);
|
|
||||||
if (filename)
|
|
||||||
{
|
|
||||||
filter_info.filename = filename;
|
|
||||||
filter_info.contains |= GTK_FILE_FILTER_FILENAME;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (required & GTK_FILE_FILTER_URI)
|
|
||||||
{
|
|
||||||
uri = g_file_get_uri (node->file);
|
|
||||||
if (uri)
|
|
||||||
{
|
|
||||||
filter_info.uri = uri;
|
|
||||||
filter_info.contains |= GTK_FILE_FILTER_URI;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result = !gtk_file_filter_filter (model->filter, &filter_info);
|
|
||||||
|
|
||||||
g_free (mime_type);
|
|
||||||
g_free (filename);
|
|
||||||
g_free (uri);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
|||||||
+329
-392
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
#include "gtkfilterlistmodel.h"
|
#include "gtkfilterlistmodel.h"
|
||||||
|
|
||||||
#include "gtkrbtreeprivate.h"
|
#include "gtkbitset.h"
|
||||||
#include "gtkintl.h"
|
#include "gtkintl.h"
|
||||||
#include "gtkprivate.h"
|
#include "gtkprivate.h"
|
||||||
|
|
||||||
@@ -35,40 +35,33 @@
|
|||||||
* listmodel.
|
* listmodel.
|
||||||
* It hides some elements from the other model according to
|
* It hides some elements from the other model according to
|
||||||
* criteria given by a #GtkFilter.
|
* criteria given by a #GtkFilter.
|
||||||
|
*
|
||||||
|
* The model can be set up to do incremental searching, so that
|
||||||
|
* filtering long lists doesn't block the UI. See
|
||||||
|
* gtk_filter_list_model_set_incremental() for details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_FILTER,
|
PROP_FILTER,
|
||||||
PROP_ITEM_TYPE,
|
PROP_INCREMENTAL,
|
||||||
PROP_MODEL,
|
PROP_MODEL,
|
||||||
|
PROP_PENDING,
|
||||||
NUM_PROPERTIES
|
NUM_PROPERTIES
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _FilterNode FilterNode;
|
|
||||||
typedef struct _FilterAugment FilterAugment;
|
|
||||||
|
|
||||||
struct _FilterNode
|
|
||||||
{
|
|
||||||
guint visible : 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _FilterAugment
|
|
||||||
{
|
|
||||||
guint n_items;
|
|
||||||
guint n_visible;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _GtkFilterListModel
|
struct _GtkFilterListModel
|
||||||
{
|
{
|
||||||
GObject parent_instance;
|
GObject parent_instance;
|
||||||
|
|
||||||
GType item_type;
|
|
||||||
GListModel *model;
|
GListModel *model;
|
||||||
GtkFilter *filter;
|
GtkFilter *filter;
|
||||||
GtkFilterMatch strictness;
|
GtkFilterMatch strictness;
|
||||||
|
gboolean incremental;
|
||||||
|
|
||||||
GtkRbTree *items; /* NULL if strictness != GTK_FILTER_MATCH_SOME */
|
GtkBitset *matches; /* NULL if strictness != GTK_FILTER_MATCH_SOME */
|
||||||
|
GtkBitset *pending; /* not yet filtered items or NULL if all filtered */
|
||||||
|
guint pending_cb; /* idle callback handle */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GtkFilterListModelClass
|
struct _GtkFilterListModelClass
|
||||||
@@ -78,133 +71,16 @@ struct _GtkFilterListModelClass
|
|||||||
|
|
||||||
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
|
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
|
||||||
|
|
||||||
static void
|
|
||||||
gtk_filter_list_model_augment (GtkRbTree *filter,
|
|
||||||
gpointer _aug,
|
|
||||||
gpointer _node,
|
|
||||||
gpointer left,
|
|
||||||
gpointer right)
|
|
||||||
{
|
|
||||||
FilterNode *node = _node;
|
|
||||||
FilterAugment *aug = _aug;
|
|
||||||
|
|
||||||
aug->n_items = 1;
|
|
||||||
aug->n_visible = node->visible ? 1 : 0;
|
|
||||||
|
|
||||||
if (left)
|
|
||||||
{
|
|
||||||
FilterAugment *left_aug = gtk_rb_tree_get_augment (filter, left);
|
|
||||||
aug->n_items += left_aug->n_items;
|
|
||||||
aug->n_visible += left_aug->n_visible;
|
|
||||||
}
|
|
||||||
if (right)
|
|
||||||
{
|
|
||||||
FilterAugment *right_aug = gtk_rb_tree_get_augment (filter, right);
|
|
||||||
aug->n_items += right_aug->n_items;
|
|
||||||
aug->n_visible += right_aug->n_visible;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static FilterNode *
|
|
||||||
gtk_filter_list_model_get_nth_filtered (GtkRbTree *tree,
|
|
||||||
guint position,
|
|
||||||
guint *out_unfiltered)
|
|
||||||
{
|
|
||||||
FilterNode *node, *tmp;
|
|
||||||
guint unfiltered;
|
|
||||||
|
|
||||||
node = gtk_rb_tree_get_root (tree);
|
|
||||||
unfiltered = 0;
|
|
||||||
|
|
||||||
while (node)
|
|
||||||
{
|
|
||||||
tmp = gtk_rb_tree_node_get_left (node);
|
|
||||||
if (tmp)
|
|
||||||
{
|
|
||||||
FilterAugment *aug = gtk_rb_tree_get_augment (tree, tmp);
|
|
||||||
if (position < aug->n_visible)
|
|
||||||
{
|
|
||||||
node = tmp;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
position -= aug->n_visible;
|
|
||||||
unfiltered += aug->n_items;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (node->visible)
|
|
||||||
{
|
|
||||||
if (position == 0)
|
|
||||||
break;
|
|
||||||
position--;
|
|
||||||
}
|
|
||||||
|
|
||||||
unfiltered++;
|
|
||||||
|
|
||||||
node = gtk_rb_tree_node_get_right (node);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (out_unfiltered)
|
|
||||||
*out_unfiltered = unfiltered;
|
|
||||||
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
static FilterNode *
|
|
||||||
gtk_filter_list_model_get_nth (GtkRbTree *tree,
|
|
||||||
guint position,
|
|
||||||
guint *out_filtered)
|
|
||||||
{
|
|
||||||
FilterNode *node, *tmp;
|
|
||||||
guint filtered;
|
|
||||||
|
|
||||||
node = gtk_rb_tree_get_root (tree);
|
|
||||||
filtered = 0;
|
|
||||||
|
|
||||||
while (node)
|
|
||||||
{
|
|
||||||
tmp = gtk_rb_tree_node_get_left (node);
|
|
||||||
if (tmp)
|
|
||||||
{
|
|
||||||
FilterAugment *aug = gtk_rb_tree_get_augment (tree, tmp);
|
|
||||||
if (position < aug->n_items)
|
|
||||||
{
|
|
||||||
node = tmp;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
position -= aug->n_items;
|
|
||||||
filtered += aug->n_visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (position == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
position--;
|
|
||||||
if (node->visible)
|
|
||||||
filtered++;
|
|
||||||
|
|
||||||
node = gtk_rb_tree_node_get_right (node);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (out_filtered)
|
|
||||||
*out_filtered = filtered;
|
|
||||||
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
static GType
|
static GType
|
||||||
gtk_filter_list_model_get_item_type (GListModel *list)
|
gtk_filter_list_model_get_item_type (GListModel *list)
|
||||||
{
|
{
|
||||||
GtkFilterListModel *self = GTK_FILTER_LIST_MODEL (list);
|
return G_TYPE_OBJECT;
|
||||||
|
|
||||||
return self->item_type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static guint
|
static guint
|
||||||
gtk_filter_list_model_get_n_items (GListModel *list)
|
gtk_filter_list_model_get_n_items (GListModel *list)
|
||||||
{
|
{
|
||||||
GtkFilterListModel *self = GTK_FILTER_LIST_MODEL (list);
|
GtkFilterListModel *self = GTK_FILTER_LIST_MODEL (list);
|
||||||
FilterAugment *aug;
|
|
||||||
FilterNode *node;
|
|
||||||
|
|
||||||
switch (self->strictness)
|
switch (self->strictness)
|
||||||
{
|
{
|
||||||
@@ -215,18 +91,12 @@ gtk_filter_list_model_get_n_items (GListModel *list)
|
|||||||
return g_list_model_get_n_items (self->model);
|
return g_list_model_get_n_items (self->model);
|
||||||
|
|
||||||
case GTK_FILTER_MATCH_SOME:
|
case GTK_FILTER_MATCH_SOME:
|
||||||
break;
|
return gtk_bitset_get_size (self->matches);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
node = gtk_rb_tree_get_root (self->items);
|
|
||||||
if (node == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
aug = gtk_rb_tree_get_augment (self->items, node);
|
|
||||||
return aug->n_visible;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gpointer
|
static gpointer
|
||||||
@@ -246,7 +116,9 @@ gtk_filter_list_model_get_item (GListModel *list,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case GTK_FILTER_MATCH_SOME:
|
case GTK_FILTER_MATCH_SOME:
|
||||||
gtk_filter_list_model_get_nth_filtered (self->items, position, &unfiltered);
|
unfiltered = gtk_bitset_get_nth (self->matches, position);
|
||||||
|
if (unfiltered == 0 && position >= gtk_bitset_get_size (self->matches))
|
||||||
|
return NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -268,8 +140,8 @@ G_DEFINE_TYPE_WITH_CODE (GtkFilterListModel, gtk_filter_list_model, G_TYPE_OBJEC
|
|||||||
G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, gtk_filter_list_model_model_init))
|
G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, gtk_filter_list_model_model_init))
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gtk_filter_list_model_run_filter (GtkFilterListModel *self,
|
gtk_filter_list_model_run_filter_on_item (GtkFilterListModel *self,
|
||||||
guint position)
|
guint position)
|
||||||
{
|
{
|
||||||
gpointer item;
|
gpointer item;
|
||||||
gboolean visible;
|
gboolean visible;
|
||||||
@@ -284,26 +156,120 @@ gtk_filter_list_model_run_filter (GtkFilterListModel *self,
|
|||||||
return visible;
|
return visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
static guint
|
static void
|
||||||
gtk_filter_list_model_add_items (GtkFilterListModel *self,
|
gtk_filter_list_model_run_filter (GtkFilterListModel *self,
|
||||||
FilterNode *after,
|
guint n_steps)
|
||||||
guint position,
|
|
||||||
guint n_items)
|
|
||||||
{
|
{
|
||||||
FilterNode *node;
|
GtkBitsetIter iter;
|
||||||
guint i, n_visible;
|
guint i, pos;
|
||||||
|
gboolean more;
|
||||||
|
|
||||||
n_visible = 0;
|
g_return_if_fail (GTK_IS_FILTER_LIST_MODEL (self));
|
||||||
|
|
||||||
for (i = 0; i < n_items; i++)
|
if (self->pending == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0, more = gtk_bitset_iter_init_first (&iter, self->pending, &pos);
|
||||||
|
i < n_steps && more;
|
||||||
|
i++, more = gtk_bitset_iter_next (&iter, &pos))
|
||||||
{
|
{
|
||||||
node = gtk_rb_tree_insert_before (self->items, after);
|
if (gtk_filter_list_model_run_filter_on_item (self, pos))
|
||||||
node->visible = gtk_filter_list_model_run_filter (self, position + i);
|
gtk_bitset_add (self->matches, pos);
|
||||||
if (node->visible)
|
|
||||||
n_visible++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return n_visible;
|
if (more)
|
||||||
|
gtk_bitset_remove_range_closed (self->pending, 0, pos);
|
||||||
|
else
|
||||||
|
g_clear_pointer (&self->pending, gtk_bitset_unref);
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_PENDING]);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_filter_list_model_stop_filtering (GtkFilterListModel *self)
|
||||||
|
{
|
||||||
|
gboolean notify_pending = self->pending != NULL;
|
||||||
|
|
||||||
|
g_clear_pointer (&self->pending, gtk_bitset_unref);
|
||||||
|
g_clear_handle_id (&self->pending_cb, g_source_remove);
|
||||||
|
|
||||||
|
if (notify_pending)
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_PENDING]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_filter_list_model_emit_items_changed_for_changes (GtkFilterListModel *self,
|
||||||
|
GtkBitset *old)
|
||||||
|
{
|
||||||
|
GtkBitset *changes;
|
||||||
|
|
||||||
|
changes = gtk_bitset_copy (self->matches);
|
||||||
|
gtk_bitset_difference (changes, old);
|
||||||
|
if (!gtk_bitset_is_empty (changes))
|
||||||
|
{
|
||||||
|
guint min, max;
|
||||||
|
|
||||||
|
min = gtk_bitset_get_minimum (changes);
|
||||||
|
max = gtk_bitset_get_maximum (changes);
|
||||||
|
g_list_model_items_changed (G_LIST_MODEL (self),
|
||||||
|
min > 0 ? gtk_bitset_get_size_in_range (self->matches, 0, min - 1) : 0,
|
||||||
|
gtk_bitset_get_size_in_range (old, min, max),
|
||||||
|
gtk_bitset_get_size_in_range (self->matches, min, max));
|
||||||
|
}
|
||||||
|
gtk_bitset_unref (changes);
|
||||||
|
gtk_bitset_unref (old);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gtk_filter_list_model_run_filter_cb (gpointer data)
|
||||||
|
{
|
||||||
|
GtkFilterListModel *self = data;
|
||||||
|
GtkBitset *old;
|
||||||
|
|
||||||
|
old = gtk_bitset_copy (self->matches);
|
||||||
|
gtk_filter_list_model_run_filter (self, 512);
|
||||||
|
|
||||||
|
if (self->pending == NULL)
|
||||||
|
gtk_filter_list_model_stop_filtering (self);
|
||||||
|
|
||||||
|
gtk_filter_list_model_emit_items_changed_for_changes (self, old);
|
||||||
|
|
||||||
|
return G_SOURCE_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NB: bitset is (transfer full) */
|
||||||
|
static void
|
||||||
|
gtk_filter_list_model_start_filtering (GtkFilterListModel *self,
|
||||||
|
GtkBitset *items)
|
||||||
|
{
|
||||||
|
if (self->pending)
|
||||||
|
{
|
||||||
|
gtk_bitset_union (self->pending, items);
|
||||||
|
gtk_bitset_unref (items);
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_PENDING]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gtk_bitset_is_empty (items))
|
||||||
|
{
|
||||||
|
gtk_bitset_unref (items);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self->pending = items;
|
||||||
|
|
||||||
|
if (!self->incremental)
|
||||||
|
{
|
||||||
|
gtk_filter_list_model_run_filter (self, G_MAXUINT);
|
||||||
|
g_assert (self->pending == NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_PENDING]);
|
||||||
|
g_assert (self->pending_cb == 0);
|
||||||
|
self->pending_cb = g_idle_add (gtk_filter_list_model_run_filter_cb, self);
|
||||||
|
g_source_set_name_by_id (self->pending_cb, "[gtk] gtk_filter_list_model_run_filter_cb");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -313,8 +279,7 @@ gtk_filter_list_model_items_changed_cb (GListModel *model,
|
|||||||
guint added,
|
guint added,
|
||||||
GtkFilterListModel *self)
|
GtkFilterListModel *self)
|
||||||
{
|
{
|
||||||
FilterNode *node;
|
guint filter_removed, filter_added;
|
||||||
guint i, filter_position, filter_removed, filter_added;
|
|
||||||
|
|
||||||
switch (self->strictness)
|
switch (self->strictness)
|
||||||
{
|
{
|
||||||
@@ -332,22 +297,27 @@ gtk_filter_list_model_items_changed_cb (GListModel *model,
|
|||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
}
|
}
|
||||||
|
|
||||||
node = gtk_filter_list_model_get_nth (self->items, position, &filter_position);
|
if (removed > 0)
|
||||||
|
filter_removed = gtk_bitset_get_size_in_range (self->matches, position, position + removed - 1);
|
||||||
|
else
|
||||||
|
filter_removed = 0;
|
||||||
|
|
||||||
filter_removed = 0;
|
gtk_bitset_splice (self->matches, position, removed, added);
|
||||||
for (i = 0; i < removed; i++)
|
if (self->pending)
|
||||||
|
gtk_bitset_splice (self->pending, position, removed, added);
|
||||||
|
|
||||||
|
if (added > 0)
|
||||||
{
|
{
|
||||||
FilterNode *next = gtk_rb_tree_node_get_next (node);
|
gtk_filter_list_model_start_filtering (self, gtk_bitset_new_range (position, added));
|
||||||
if (node->visible)
|
filter_added = gtk_bitset_get_size_in_range (self->matches, position, position + added - 1);
|
||||||
filter_removed++;
|
|
||||||
gtk_rb_tree_remove (self->items, node);
|
|
||||||
node = next;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
filter_added = gtk_filter_list_model_add_items (self, node, position, added);
|
filter_added = 0;
|
||||||
|
|
||||||
if (filter_removed > 0 || filter_added > 0)
|
if (filter_removed > 0 || filter_added > 0)
|
||||||
g_list_model_items_changed (G_LIST_MODEL (self), filter_position, filter_removed, filter_added);
|
g_list_model_items_changed (G_LIST_MODEL (self),
|
||||||
|
position > 0 ? gtk_bitset_get_size_in_range (self->matches, 0, position - 1) : 0,
|
||||||
|
filter_removed, filter_added);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -364,8 +334,8 @@ gtk_filter_list_model_set_property (GObject *object,
|
|||||||
gtk_filter_list_model_set_filter (self, g_value_get_object (value));
|
gtk_filter_list_model_set_filter (self, g_value_get_object (value));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_ITEM_TYPE:
|
case PROP_INCREMENTAL:
|
||||||
self->item_type = g_value_get_gtype (value);
|
gtk_filter_list_model_set_incremental (self, g_value_get_boolean (value));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_MODEL:
|
case PROP_MODEL:
|
||||||
@@ -392,14 +362,18 @@ gtk_filter_list_model_get_property (GObject *object,
|
|||||||
g_value_set_object (value, self->filter);
|
g_value_set_object (value, self->filter);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_ITEM_TYPE:
|
case PROP_INCREMENTAL:
|
||||||
g_value_set_gtype (value, self->item_type);
|
g_value_set_boolean (value, self->incremental);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_MODEL:
|
case PROP_MODEL:
|
||||||
g_value_set_object (value, self->model);
|
g_value_set_object (value, self->model);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_PENDING:
|
||||||
|
g_value_set_uint (value, gtk_filter_list_model_get_pending (self));
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@@ -412,109 +386,16 @@ gtk_filter_list_model_clear_model (GtkFilterListModel *self)
|
|||||||
if (self->model == NULL)
|
if (self->model == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
gtk_filter_list_model_stop_filtering (self);
|
||||||
g_signal_handlers_disconnect_by_func (self->model, gtk_filter_list_model_items_changed_cb, self);
|
g_signal_handlers_disconnect_by_func (self->model, gtk_filter_list_model_items_changed_cb, self);
|
||||||
g_clear_object (&self->model);
|
g_clear_object (&self->model);
|
||||||
if (self->items)
|
if (self->matches)
|
||||||
gtk_rb_tree_remove_all (self->items);
|
gtk_bitset_remove_all (self->matches);
|
||||||
}
|
|
||||||
|
|
||||||
/*<private>
|
|
||||||
* gtk_filter_list_model_find_filtered:
|
|
||||||
* @self: a #GtkFilterListModel
|
|
||||||
* @start: (out) (caller-allocates): number of unfiltered items
|
|
||||||
* at start of list
|
|
||||||
* @end: (out) (caller-allocates): number of unfiltered items
|
|
||||||
* at end of list
|
|
||||||
* @n_items: (out) (caller-allocates): number of unfiltered items in
|
|
||||||
* list
|
|
||||||
*
|
|
||||||
* Checks if elements in self->items are filtered out and returns
|
|
||||||
* the range that they occupy.
|
|
||||||
* This function is intended to be used for GListModel::items-changed
|
|
||||||
* emissions, so it is called in an intermediate state for @self.
|
|
||||||
*
|
|
||||||
* Returns: %TRUE if elements are filtered out, %FALSE if none are
|
|
||||||
**/
|
|
||||||
static gboolean
|
|
||||||
gtk_filter_list_model_find_filtered (GtkFilterListModel *self,
|
|
||||||
guint *start,
|
|
||||||
guint *end,
|
|
||||||
guint *n_items)
|
|
||||||
{
|
|
||||||
FilterNode *root, *node, *tmp;
|
|
||||||
FilterAugment *aug;
|
|
||||||
|
|
||||||
if (self->items == NULL || self->model == NULL)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
root = gtk_rb_tree_get_root (self->items);
|
|
||||||
if (root == NULL)
|
|
||||||
return FALSE; /* empty parent model */
|
|
||||||
|
|
||||||
aug = gtk_rb_tree_get_augment (self->items, root);
|
|
||||||
if (aug->n_items == aug->n_visible)
|
|
||||||
return FALSE; /* all items visible */
|
|
||||||
|
|
||||||
/* find first filtered */
|
|
||||||
*start = 0;
|
|
||||||
*end = 0;
|
|
||||||
*n_items = aug->n_visible;
|
|
||||||
|
|
||||||
node = root;
|
|
||||||
while (node)
|
|
||||||
{
|
|
||||||
tmp = gtk_rb_tree_node_get_left (node);
|
|
||||||
if (tmp)
|
|
||||||
{
|
|
||||||
aug = gtk_rb_tree_get_augment (self->items, tmp);
|
|
||||||
if (aug->n_visible < aug->n_items)
|
|
||||||
{
|
|
||||||
node = tmp;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
*start += aug->n_items;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!node->visible)
|
|
||||||
break;
|
|
||||||
|
|
||||||
(*start)++;
|
|
||||||
|
|
||||||
node = gtk_rb_tree_node_get_right (node);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* find last filtered by doing everything the opposite way */
|
|
||||||
node = root;
|
|
||||||
while (node)
|
|
||||||
{
|
|
||||||
tmp = gtk_rb_tree_node_get_right (node);
|
|
||||||
if (tmp)
|
|
||||||
{
|
|
||||||
aug = gtk_rb_tree_get_augment (self->items, tmp);
|
|
||||||
if (aug->n_visible < aug->n_items)
|
|
||||||
{
|
|
||||||
node = tmp;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
*end += aug->n_items;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!node->visible)
|
|
||||||
break;
|
|
||||||
|
|
||||||
(*end)++;
|
|
||||||
|
|
||||||
node = gtk_rb_tree_node_get_left (node);
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_filter_list_model_refilter (GtkFilterListModel *self);
|
gtk_filter_list_model_refilter (GtkFilterListModel *self,
|
||||||
|
GtkFilterChange change)
|
||||||
static void
|
|
||||||
gtk_filter_list_model_update_strictness_and_refilter (GtkFilterListModel *self)
|
|
||||||
{
|
{
|
||||||
GtkFilterMatch new_strictness;
|
GtkFilterMatch new_strictness;
|
||||||
|
|
||||||
@@ -532,8 +413,9 @@ gtk_filter_list_model_update_strictness_and_refilter (GtkFilterListModel *self)
|
|||||||
case GTK_FILTER_MATCH_NONE:
|
case GTK_FILTER_MATCH_NONE:
|
||||||
{
|
{
|
||||||
guint n_before = g_list_model_get_n_items (G_LIST_MODEL (self));
|
guint n_before = g_list_model_get_n_items (G_LIST_MODEL (self));
|
||||||
g_clear_pointer (&self->items, gtk_rb_tree_unref);
|
g_clear_pointer (&self->matches, gtk_bitset_unref);
|
||||||
self->strictness = new_strictness;
|
self->strictness = new_strictness;
|
||||||
|
gtk_filter_list_model_stop_filtering (self);
|
||||||
if (n_before > 0)
|
if (n_before > 0)
|
||||||
g_list_model_items_changed (G_LIST_MODEL (self), 0, n_before, 0);
|
g_list_model_items_changed (G_LIST_MODEL (self), 0, n_before, 0);
|
||||||
}
|
}
|
||||||
@@ -553,16 +435,35 @@ gtk_filter_list_model_update_strictness_and_refilter (GtkFilterListModel *self)
|
|||||||
case GTK_FILTER_MATCH_SOME:
|
case GTK_FILTER_MATCH_SOME:
|
||||||
{
|
{
|
||||||
guint start, end, n_before, n_after;
|
guint start, end, n_before, n_after;
|
||||||
|
|
||||||
|
gtk_filter_list_model_stop_filtering (self);
|
||||||
self->strictness = new_strictness;
|
self->strictness = new_strictness;
|
||||||
if (gtk_filter_list_model_find_filtered (self, &start, &end, &n_before))
|
n_after = g_list_model_get_n_items (G_LIST_MODEL (self));
|
||||||
|
start = gtk_bitset_get_minimum (self->matches);
|
||||||
|
end = gtk_bitset_get_maximum (self->matches);
|
||||||
|
|
||||||
|
n_before = gtk_bitset_get_size (self->matches);
|
||||||
|
if (n_before == n_after)
|
||||||
{
|
{
|
||||||
n_after = g_list_model_get_n_items (G_LIST_MODEL (self));
|
g_clear_pointer (&self->matches, gtk_bitset_unref);
|
||||||
g_clear_pointer (&self->items, gtk_rb_tree_unref);
|
|
||||||
g_list_model_items_changed (G_LIST_MODEL (self), start, n_before - end - start, n_after - end - start);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_clear_pointer (&self->items, gtk_rb_tree_unref);
|
GtkBitset *inverse;
|
||||||
|
|
||||||
|
inverse = gtk_bitset_new_range (0, n_after);
|
||||||
|
gtk_bitset_subtract (inverse, self->matches);
|
||||||
|
/* otherwise all items would be visible */
|
||||||
|
g_assert (!gtk_bitset_is_empty (inverse));
|
||||||
|
|
||||||
|
/* find first filtered */
|
||||||
|
start = gtk_bitset_get_minimum (inverse);
|
||||||
|
end = n_after - gtk_bitset_get_maximum (inverse) - 1;
|
||||||
|
|
||||||
|
gtk_bitset_unref (inverse);
|
||||||
|
|
||||||
|
g_clear_pointer (&self->matches, gtk_bitset_unref);
|
||||||
|
g_list_model_items_changed (G_LIST_MODEL (self), start, n_before - end - start, n_after - end - start);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -574,40 +475,44 @@ gtk_filter_list_model_update_strictness_and_refilter (GtkFilterListModel *self)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case GTK_FILTER_MATCH_SOME:
|
case GTK_FILTER_MATCH_SOME:
|
||||||
switch (self->strictness)
|
{
|
||||||
{
|
GtkBitset *old, *pending;
|
||||||
case GTK_FILTER_MATCH_NONE:
|
|
||||||
|
if (self->matches == NULL)
|
||||||
{
|
{
|
||||||
guint n_after;
|
if (self->strictness == GTK_FILTER_MATCH_ALL)
|
||||||
self->strictness = new_strictness;
|
old = gtk_bitset_new_range (0, g_list_model_get_n_items (self->model));
|
||||||
self->items = gtk_rb_tree_new (FilterNode,
|
else
|
||||||
FilterAugment,
|
old = gtk_bitset_new_empty ();
|
||||||
gtk_filter_list_model_augment,
|
|
||||||
NULL, NULL);
|
|
||||||
n_after = gtk_filter_list_model_add_items (self, NULL, 0, g_list_model_get_n_items (self->model));
|
|
||||||
if (n_after > 0)
|
|
||||||
g_list_model_items_changed (G_LIST_MODEL (self), 0, 0, n_after);
|
|
||||||
}
|
}
|
||||||
break;
|
else
|
||||||
case GTK_FILTER_MATCH_ALL:
|
|
||||||
{
|
{
|
||||||
guint start, end, n_before, n_after;
|
old = self->matches;
|
||||||
self->strictness = new_strictness;
|
|
||||||
self->items = gtk_rb_tree_new (FilterNode,
|
|
||||||
FilterAugment,
|
|
||||||
gtk_filter_list_model_augment,
|
|
||||||
NULL, NULL);
|
|
||||||
n_before = g_list_model_get_n_items (self->model);
|
|
||||||
gtk_filter_list_model_add_items (self, NULL, 0, n_before);
|
|
||||||
if (gtk_filter_list_model_find_filtered (self, &start, &end, &n_after))
|
|
||||||
g_list_model_items_changed (G_LIST_MODEL (self), start, n_before - end - start, n_after - end - start);
|
|
||||||
}
|
}
|
||||||
break;
|
self->strictness = new_strictness;
|
||||||
default:
|
switch (change)
|
||||||
case GTK_FILTER_MATCH_SOME:
|
{
|
||||||
gtk_filter_list_model_refilter (self);
|
default:
|
||||||
break;
|
g_assert_not_reached ();
|
||||||
}
|
G_GNUC_FALLTHROUGH;
|
||||||
|
case GTK_FILTER_CHANGE_DIFFERENT:
|
||||||
|
self->matches = gtk_bitset_new_empty ();
|
||||||
|
pending = gtk_bitset_new_range (0, g_list_model_get_n_items (self->model));
|
||||||
|
break;
|
||||||
|
case GTK_FILTER_CHANGE_LESS_STRICT:
|
||||||
|
self->matches = gtk_bitset_copy (old);
|
||||||
|
pending = gtk_bitset_new_range (0, g_list_model_get_n_items (self->model));
|
||||||
|
gtk_bitset_subtract (pending, self->matches);
|
||||||
|
break;
|
||||||
|
case GTK_FILTER_CHANGE_MORE_STRICT:
|
||||||
|
self->matches = gtk_bitset_new_empty ();
|
||||||
|
pending = gtk_bitset_copy (old);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
gtk_filter_list_model_start_filtering (self, pending);
|
||||||
|
|
||||||
|
gtk_filter_list_model_emit_items_changed_for_changes (self, old);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -616,7 +521,7 @@ gtk_filter_list_model_filter_changed_cb (GtkFilter *filter,
|
|||||||
GtkFilterChange change,
|
GtkFilterChange change,
|
||||||
GtkFilterListModel *self)
|
GtkFilterListModel *self)
|
||||||
{
|
{
|
||||||
gtk_filter_list_model_update_strictness_and_refilter (self);
|
gtk_filter_list_model_refilter (self, change);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -636,7 +541,7 @@ gtk_filter_list_model_dispose (GObject *object)
|
|||||||
|
|
||||||
gtk_filter_list_model_clear_model (self);
|
gtk_filter_list_model_clear_model (self);
|
||||||
gtk_filter_list_model_clear_filter (self);
|
gtk_filter_list_model_clear_filter (self);
|
||||||
g_clear_pointer (&self->items, gtk_rb_tree_unref);
|
g_clear_pointer (&self->matches, gtk_bitset_unref);
|
||||||
|
|
||||||
G_OBJECT_CLASS (gtk_filter_list_model_parent_class)->dispose (object);
|
G_OBJECT_CLASS (gtk_filter_list_model_parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
@@ -663,16 +568,16 @@ gtk_filter_list_model_class_init (GtkFilterListModelClass *class)
|
|||||||
GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
|
GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GtkFilterListModel:item-type:
|
* GtkFilterListModel:incremental:
|
||||||
*
|
*
|
||||||
* The #GType for elements of this object
|
* If the model should filter items incrementally
|
||||||
*/
|
*/
|
||||||
properties[PROP_ITEM_TYPE] =
|
properties[PROP_INCREMENTAL] =
|
||||||
g_param_spec_gtype ("item-type",
|
g_param_spec_boolean ("incremental",
|
||||||
P_("Item type"),
|
P_("Incremental"),
|
||||||
P_("The type of elements of this object"),
|
P_("Filer items incrementally"),
|
||||||
G_TYPE_OBJECT,
|
FALSE,
|
||||||
GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY);
|
GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GtkFilterListModel:model:
|
* GtkFilterListModel:model:
|
||||||
@@ -684,7 +589,19 @@ gtk_filter_list_model_class_init (GtkFilterListModelClass *class)
|
|||||||
P_("Model"),
|
P_("Model"),
|
||||||
P_("The model being filtered"),
|
P_("The model being filtered"),
|
||||||
G_TYPE_LIST_MODEL,
|
G_TYPE_LIST_MODEL,
|
||||||
GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY);
|
GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GtkFilterListModel:pending:
|
||||||
|
*
|
||||||
|
* Number of items not yet filtered
|
||||||
|
*/
|
||||||
|
properties[PROP_PENDING] =
|
||||||
|
g_param_spec_uint ("pending",
|
||||||
|
P_("Pending"),
|
||||||
|
P_("Number of items not yet filtered"),
|
||||||
|
0, G_MAXUINT, 0,
|
||||||
|
GTK_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY);
|
||||||
|
|
||||||
g_object_class_install_properties (gobject_class, NUM_PROPERTIES, properties);
|
g_object_class_install_properties (gobject_class, NUM_PROPERTIES, properties);
|
||||||
}
|
}
|
||||||
@@ -697,7 +614,7 @@ gtk_filter_list_model_init (GtkFilterListModel *self)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* gtk_filter_list_model_new:
|
* gtk_filter_list_model_new:
|
||||||
* @model: the model to sort
|
* @model: (allow-none): the model to sort
|
||||||
* @filter: (allow-none): filter or %NULL to not filter items
|
* @filter: (allow-none): filter or %NULL to not filter items
|
||||||
*
|
*
|
||||||
* Creates a new #GtkFilterListModel that will filter @model using the given
|
* Creates a new #GtkFilterListModel that will filter @model using the given
|
||||||
@@ -711,10 +628,10 @@ gtk_filter_list_model_new (GListModel *model,
|
|||||||
{
|
{
|
||||||
GtkFilterListModel *result;
|
GtkFilterListModel *result;
|
||||||
|
|
||||||
g_return_val_if_fail (G_IS_LIST_MODEL (model), NULL);
|
g_return_val_if_fail (model == NULL || G_IS_LIST_MODEL (model), NULL);
|
||||||
|
g_return_val_if_fail (filter == NULL || GTK_IS_FILTER (filter), NULL);
|
||||||
|
|
||||||
result = g_object_new (GTK_TYPE_FILTER_LIST_MODEL,
|
result = g_object_new (GTK_TYPE_FILTER_LIST_MODEL,
|
||||||
"item-type", g_list_model_get_item_type (model),
|
|
||||||
"model", model,
|
"model", model,
|
||||||
"filter", filter,
|
"filter", filter,
|
||||||
NULL);
|
NULL);
|
||||||
@@ -722,26 +639,6 @@ gtk_filter_list_model_new (GListModel *model,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* gtk_filter_list_model_new_for_type:
|
|
||||||
* @item_type: the type of the items that will be returned
|
|
||||||
*
|
|
||||||
* Creates a new empty filter list model set up to return items of type @item_type.
|
|
||||||
* It is up to the application to set a proper filter and model to ensure
|
|
||||||
* the item type is matched.
|
|
||||||
*
|
|
||||||
* Returns: a new #GtkFilterListModel
|
|
||||||
**/
|
|
||||||
GtkFilterListModel *
|
|
||||||
gtk_filter_list_model_new_for_type (GType item_type)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (g_type_is_a (item_type, G_TYPE_OBJECT), NULL);
|
|
||||||
|
|
||||||
return g_object_new (GTK_TYPE_FILTER_LIST_MODEL,
|
|
||||||
"item-type", item_type,
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gtk_filter_list_model_set_filter:
|
* gtk_filter_list_model_set_filter:
|
||||||
* @self: a #GtkFilterListModel
|
* @self: a #GtkFilterListModel
|
||||||
@@ -769,7 +666,7 @@ gtk_filter_list_model_set_filter (GtkFilterListModel *self,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gtk_filter_list_model_update_strictness_and_refilter (self);
|
gtk_filter_list_model_refilter (self, GTK_FILTER_CHANGE_LESS_STRICT);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FILTER]);
|
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FILTER]);
|
||||||
@@ -828,13 +725,18 @@ gtk_filter_list_model_set_model (GtkFilterListModel *self,
|
|||||||
if (removed == 0)
|
if (removed == 0)
|
||||||
{
|
{
|
||||||
self->strictness = GTK_FILTER_MATCH_NONE;
|
self->strictness = GTK_FILTER_MATCH_NONE;
|
||||||
gtk_filter_list_model_update_strictness_and_refilter (self);
|
gtk_filter_list_model_refilter (self, GTK_FILTER_CHANGE_LESS_STRICT);
|
||||||
added = 0;
|
added = 0;
|
||||||
}
|
}
|
||||||
else if (self->items)
|
else if (self->matches)
|
||||||
added = gtk_filter_list_model_add_items (self, NULL, 0, g_list_model_get_n_items (model));
|
{
|
||||||
|
gtk_filter_list_model_start_filtering (self, gtk_bitset_new_range (0, g_list_model_get_n_items (model)));
|
||||||
|
added = gtk_bitset_get_size (self->matches);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
added = g_list_model_get_n_items (model);
|
{
|
||||||
|
added = g_list_model_get_n_items (model);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -864,54 +766,89 @@ gtk_filter_list_model_get_model (GtkFilterListModel *self)
|
|||||||
return self->model;
|
return self->model;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
/**
|
||||||
gtk_filter_list_model_refilter (GtkFilterListModel *self)
|
* gtk_filter_list_model_set_incremental:
|
||||||
|
* @self: a #GtkFilterListModel
|
||||||
|
* @incremental: %TRUE to enable incremental filtering
|
||||||
|
*
|
||||||
|
* When incremental filtering is enabled, the filterlistmodel will not run
|
||||||
|
* filters immediately, but will instead queue an idle handler that
|
||||||
|
* incrementally filters the items and adds them to the list. This of course
|
||||||
|
* means that items are not instantly added to the list, but only appear
|
||||||
|
* incrementally.
|
||||||
|
*
|
||||||
|
* When your filter blocks the UI while filtering, you might consider
|
||||||
|
* turning this on. Depending on your model and filters, this may become
|
||||||
|
* interesting around 10,000 to 100,000 items.
|
||||||
|
*
|
||||||
|
* By default, incremental filtering is disabled.
|
||||||
|
**/
|
||||||
|
void
|
||||||
|
gtk_filter_list_model_set_incremental (GtkFilterListModel *self,
|
||||||
|
gboolean incremental)
|
||||||
{
|
{
|
||||||
FilterNode *node;
|
|
||||||
guint i, first_change, last_change;
|
|
||||||
guint n_is_visible, n_was_visible;
|
|
||||||
gboolean visible;
|
|
||||||
|
|
||||||
g_return_if_fail (GTK_IS_FILTER_LIST_MODEL (self));
|
g_return_if_fail (GTK_IS_FILTER_LIST_MODEL (self));
|
||||||
|
|
||||||
if (self->items == NULL || self->model == NULL)
|
if (self->incremental == incremental)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
first_change = G_MAXUINT;
|
self->incremental = incremental;
|
||||||
last_change = 0;
|
|
||||||
n_is_visible = 0;
|
|
||||||
n_was_visible = 0;
|
|
||||||
for (i = 0, node = gtk_rb_tree_get_first (self->items);
|
|
||||||
node != NULL;
|
|
||||||
i++, node = gtk_rb_tree_node_get_next (node))
|
|
||||||
{
|
|
||||||
visible = gtk_filter_list_model_run_filter (self, i);
|
|
||||||
if (visible == node->visible)
|
|
||||||
{
|
|
||||||
if (visible)
|
|
||||||
{
|
|
||||||
n_is_visible++;
|
|
||||||
n_was_visible++;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
node->visible = visible;
|
if (!incremental)
|
||||||
gtk_rb_tree_node_mark_dirty (node);
|
{
|
||||||
first_change = MIN (n_is_visible, first_change);
|
GtkBitset *old;
|
||||||
if (visible)
|
gtk_filter_list_model_run_filter (self, G_MAXUINT);
|
||||||
n_is_visible++;
|
|
||||||
else
|
old = gtk_bitset_copy (self->matches);
|
||||||
n_was_visible++;
|
gtk_filter_list_model_run_filter (self, 512);
|
||||||
last_change = MAX (n_is_visible, last_change);
|
|
||||||
|
gtk_filter_list_model_stop_filtering (self);
|
||||||
|
|
||||||
|
gtk_filter_list_model_emit_items_changed_for_changes (self, old);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (first_change <= last_change)
|
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_INCREMENTAL]);
|
||||||
{
|
|
||||||
g_list_model_items_changed (G_LIST_MODEL (self),
|
|
||||||
first_change,
|
|
||||||
last_change - first_change + n_was_visible - n_is_visible,
|
|
||||||
last_change - first_change);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gtk_filter_list_model_get_incremental:
|
||||||
|
* @self: a #GtkFilterListModel
|
||||||
|
*
|
||||||
|
* Returns whether incremental filtering was enabled via
|
||||||
|
* gtk_filter_list_model_set_incremental().
|
||||||
|
*
|
||||||
|
* Returns: %TRUE if incremental filtering is enabled
|
||||||
|
**/
|
||||||
|
gboolean
|
||||||
|
gtk_filter_list_model_get_incremental (GtkFilterListModel *self)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GTK_IS_FILTER_LIST_MODEL (self), FALSE);
|
||||||
|
|
||||||
|
return self->incremental;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gtk_filter_list_model_get_pending:
|
||||||
|
* @self: a #GtkFilterListModel
|
||||||
|
*
|
||||||
|
* Returns the number of items that have not been filtered yet.
|
||||||
|
*
|
||||||
|
* When incremental filtering is not enabled, this always returns 0.
|
||||||
|
*
|
||||||
|
* You can use this value to check if @self is busy filtering by
|
||||||
|
* comparing the return value to 0 or you can compute the percentage
|
||||||
|
* of the filter remaining by dividing the return value by
|
||||||
|
* g_list_model_get_n_items(gtk_filter_list_model_get_model (self)).
|
||||||
|
*
|
||||||
|
* Returns: The number of items not yet filtered
|
||||||
|
**/
|
||||||
|
guint
|
||||||
|
gtk_filter_list_model_get_pending (GtkFilterListModel *self)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GTK_IS_FILTER_LIST_MODEL (self), FALSE);
|
||||||
|
|
||||||
|
if (self->pending == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return gtk_bitset_get_size (self->pending);
|
||||||
|
}
|
||||||
|
|||||||
@@ -39,8 +39,6 @@ G_DECLARE_FINAL_TYPE (GtkFilterListModel, gtk_filter_list_model, GTK, FILTER_LIS
|
|||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
GtkFilterListModel * gtk_filter_list_model_new (GListModel *model,
|
GtkFilterListModel * gtk_filter_list_model_new (GListModel *model,
|
||||||
GtkFilter *filter);
|
GtkFilter *filter);
|
||||||
GDK_AVAILABLE_IN_ALL
|
|
||||||
GtkFilterListModel * gtk_filter_list_model_new_for_type (GType item_type);
|
|
||||||
|
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
void gtk_filter_list_model_set_filter (GtkFilterListModel *self,
|
void gtk_filter_list_model_set_filter (GtkFilterListModel *self,
|
||||||
@@ -52,6 +50,14 @@ void gtk_filter_list_model_set_model (GtkFilterListMo
|
|||||||
GListModel *model);
|
GListModel *model);
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
GListModel * gtk_filter_list_model_get_model (GtkFilterListModel *self);
|
GListModel * gtk_filter_list_model_get_model (GtkFilterListModel *self);
|
||||||
|
GDK_AVAILABLE_IN_ALL
|
||||||
|
void gtk_filter_list_model_set_incremental (GtkFilterListModel *self,
|
||||||
|
gboolean incremental);
|
||||||
|
GDK_AVAILABLE_IN_ALL
|
||||||
|
gboolean gtk_filter_list_model_get_incremental (GtkFilterListModel *self);
|
||||||
|
GDK_AVAILABLE_IN_ALL
|
||||||
|
guint gtk_filter_list_model_get_pending (GtkFilterListModel *self);
|
||||||
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,6 @@
|
|||||||
|
|
||||||
enum {
|
enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_ITEM_TYPE,
|
|
||||||
PROP_MODEL,
|
PROP_MODEL,
|
||||||
NUM_PROPERTIES
|
NUM_PROPERTIES
|
||||||
};
|
};
|
||||||
@@ -64,7 +63,6 @@ struct _GtkFlattenListModel
|
|||||||
{
|
{
|
||||||
GObject parent_instance;
|
GObject parent_instance;
|
||||||
|
|
||||||
GType item_type;
|
|
||||||
GListModel *model;
|
GListModel *model;
|
||||||
GtkRbTree *items; /* NULL if model == NULL */
|
GtkRbTree *items; /* NULL if model == NULL */
|
||||||
};
|
};
|
||||||
@@ -157,9 +155,7 @@ gtk_flatten_list_model_get_nth_model (GtkRbTree *tree,
|
|||||||
static GType
|
static GType
|
||||||
gtk_flatten_list_model_get_item_type (GListModel *list)
|
gtk_flatten_list_model_get_item_type (GListModel *list)
|
||||||
{
|
{
|
||||||
GtkFlattenListModel *self = GTK_FLATTEN_LIST_MODEL (list);
|
return G_TYPE_OBJECT;
|
||||||
|
|
||||||
return self->item_type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static guint
|
static guint
|
||||||
@@ -299,7 +295,6 @@ gtk_flatten_list_model_add_items (GtkFlattenListModel *self,
|
|||||||
{
|
{
|
||||||
node = gtk_rb_tree_insert_before (self->items, after);
|
node = gtk_rb_tree_insert_before (self->items, after);
|
||||||
node->model = g_list_model_get_item (self->model, position + i);
|
node->model = g_list_model_get_item (self->model, position + i);
|
||||||
g_warn_if_fail (g_type_is_a (g_list_model_get_item_type (node->model), self->item_type));
|
|
||||||
g_signal_connect (node->model,
|
g_signal_connect (node->model,
|
||||||
"items-changed",
|
"items-changed",
|
||||||
G_CALLBACK (gtk_flatten_list_model_items_changed_cb),
|
G_CALLBACK (gtk_flatten_list_model_items_changed_cb),
|
||||||
@@ -321,10 +316,6 @@ gtk_flatten_list_model_set_property (GObject *object,
|
|||||||
|
|
||||||
switch (prop_id)
|
switch (prop_id)
|
||||||
{
|
{
|
||||||
case PROP_ITEM_TYPE:
|
|
||||||
self->item_type = g_value_get_gtype (value);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PROP_MODEL:
|
case PROP_MODEL:
|
||||||
gtk_flatten_list_model_set_model (self, g_value_get_object (value));
|
gtk_flatten_list_model_set_model (self, g_value_get_object (value));
|
||||||
break;
|
break;
|
||||||
@@ -345,10 +336,6 @@ gtk_flatten_list_model_get_property (GObject *object,
|
|||||||
|
|
||||||
switch (prop_id)
|
switch (prop_id)
|
||||||
{
|
{
|
||||||
case PROP_ITEM_TYPE:
|
|
||||||
g_value_set_gtype (value, self->item_type);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PROP_MODEL:
|
case PROP_MODEL:
|
||||||
g_value_set_object (value, self->model);
|
g_value_set_object (value, self->model);
|
||||||
break;
|
break;
|
||||||
@@ -416,18 +403,6 @@ gtk_flatten_list_model_class_init (GtkFlattenListModelClass *class)
|
|||||||
gobject_class->get_property = gtk_flatten_list_model_get_property;
|
gobject_class->get_property = gtk_flatten_list_model_get_property;
|
||||||
gobject_class->dispose = gtk_flatten_list_model_dispose;
|
gobject_class->dispose = gtk_flatten_list_model_dispose;
|
||||||
|
|
||||||
/**
|
|
||||||
* GtkFlattenListModel:item-type:
|
|
||||||
*
|
|
||||||
* The #GType for elements of this object
|
|
||||||
*/
|
|
||||||
properties[PROP_ITEM_TYPE] =
|
|
||||||
g_param_spec_gtype ("item-type",
|
|
||||||
P_("Item type"),
|
|
||||||
P_("The type of elements of this object"),
|
|
||||||
G_TYPE_OBJECT,
|
|
||||||
GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GtkFlattenListModel:model:
|
* GtkFlattenListModel:model:
|
||||||
*
|
*
|
||||||
@@ -450,26 +425,20 @@ gtk_flatten_list_model_init (GtkFlattenListModel *self)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* gtk_flatten_list_model_new:
|
* gtk_flatten_list_model_new:
|
||||||
* @item_type: The type of items in the to-be-flattened models
|
* @model: (nullable) (transfer none): the model to be flattened
|
||||||
* @model: (nullable) (transfer none): the item to be flattened
|
|
||||||
*
|
*
|
||||||
* Creates a new #GtkFlattenListModel that flattens @list. The
|
* Creates a new #GtkFlattenListModel that flattens @list.
|
||||||
* models returned by @model must conform to the given @item_type,
|
|
||||||
* either by having an identical type or a subtype.
|
|
||||||
*
|
*
|
||||||
* Returns: a new #GtkFlattenListModel
|
* Returns: a new #GtkFlattenListModel
|
||||||
**/
|
**/
|
||||||
GtkFlattenListModel *
|
GtkFlattenListModel *
|
||||||
gtk_flatten_list_model_new (GType item_type,
|
gtk_flatten_list_model_new (GListModel *model)
|
||||||
GListModel *model)
|
|
||||||
{
|
{
|
||||||
GtkFlattenListModel *result;
|
GtkFlattenListModel *result;
|
||||||
|
|
||||||
g_return_val_if_fail (g_type_is_a (item_type, G_TYPE_OBJECT), NULL);
|
|
||||||
g_return_val_if_fail (model == NULL || G_IS_LIST_MODEL (model), NULL);
|
g_return_val_if_fail (model == NULL || G_IS_LIST_MODEL (model), NULL);
|
||||||
|
|
||||||
result = g_object_new (GTK_TYPE_FLATTEN_LIST_MODEL,
|
result = g_object_new (GTK_TYPE_FLATTEN_LIST_MODEL,
|
||||||
"item-type", item_type,
|
|
||||||
"model", model,
|
"model", model,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
@@ -481,8 +450,7 @@ gtk_flatten_list_model_new (GType item_type,
|
|||||||
* @self: a #GtkFlattenListModel
|
* @self: a #GtkFlattenListModel
|
||||||
* @model: (nullable) (transfer none): the new model or %NULL
|
* @model: (nullable) (transfer none): the new model or %NULL
|
||||||
*
|
*
|
||||||
* Sets a new model to be flattened. The model must contain items of
|
* Sets a new model to be flattened.
|
||||||
* #GListModel that conform to the item type of @self.
|
|
||||||
**/
|
**/
|
||||||
void
|
void
|
||||||
gtk_flatten_list_model_set_model (GtkFlattenListModel *self,
|
gtk_flatten_list_model_set_model (GtkFlattenListModel *self,
|
||||||
@@ -492,10 +460,6 @@ gtk_flatten_list_model_set_model (GtkFlattenListModel *self,
|
|||||||
|
|
||||||
g_return_if_fail (GTK_IS_FLATTEN_LIST_MODEL (self));
|
g_return_if_fail (GTK_IS_FLATTEN_LIST_MODEL (self));
|
||||||
g_return_if_fail (model == NULL || G_IS_LIST_MODEL (model));
|
g_return_if_fail (model == NULL || G_IS_LIST_MODEL (model));
|
||||||
if (model)
|
|
||||||
{
|
|
||||||
g_return_if_fail (g_type_is_a (g_list_model_get_item_type (model), G_TYPE_LIST_MODEL));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self->model == model)
|
if (self->model == model)
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -36,8 +36,7 @@ GDK_AVAILABLE_IN_ALL
|
|||||||
G_DECLARE_FINAL_TYPE (GtkFlattenListModel, gtk_flatten_list_model, GTK, FLATTEN_LIST_MODEL, GObject)
|
G_DECLARE_FINAL_TYPE (GtkFlattenListModel, gtk_flatten_list_model, GTK, FLATTEN_LIST_MODEL, GObject)
|
||||||
|
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
GtkFlattenListModel * gtk_flatten_list_model_new (GType item_type,
|
GtkFlattenListModel * gtk_flatten_list_model_new (GListModel *model);
|
||||||
GListModel *model);
|
|
||||||
|
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
void gtk_flatten_list_model_set_model (GtkFlattenListModel *self,
|
void gtk_flatten_list_model_set_model (GtkFlattenListModel *self,
|
||||||
|
|||||||
@@ -784,7 +784,7 @@ update_fontlist (GtkFontChooserWidget *self)
|
|||||||
if ((self->level & GTK_FONT_CHOOSER_LEVEL_STYLE) == 0)
|
if ((self->level & GTK_FONT_CHOOSER_LEVEL_STYLE) == 0)
|
||||||
model = g_object_ref (G_LIST_MODEL (fontmap));
|
model = g_object_ref (G_LIST_MODEL (fontmap));
|
||||||
else
|
else
|
||||||
model = G_LIST_MODEL (gtk_flatten_list_model_new (PANGO_TYPE_FONT_FACE, G_LIST_MODEL (fontmap)));
|
model = G_LIST_MODEL (gtk_flatten_list_model_new (G_LIST_MODEL (fontmap)));
|
||||||
gtk_filter_list_model_set_model (self->filter_model, model);
|
gtk_filter_list_model_set_model (self->filter_model, model);
|
||||||
g_object_unref (model);
|
g_object_unref (model);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,135 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright © 2019 Benjamin Otte
|
|
||||||
*
|
|
||||||
* 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.1 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/>.
|
|
||||||
*
|
|
||||||
* Authors: Benjamin Otte <otte@gnome.org>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
#include "gtkfunctionslistitemfactory.h"
|
|
||||||
|
|
||||||
#include "gtklistitemfactoryprivate.h"
|
|
||||||
#include "gtklistitemprivate.h"
|
|
||||||
|
|
||||||
struct _GtkFunctionsListItemFactory
|
|
||||||
{
|
|
||||||
GtkListItemFactory parent_instance;
|
|
||||||
|
|
||||||
GtkListItemSetupFunc setup_func;
|
|
||||||
GtkListItemBindFunc bind_func;
|
|
||||||
gpointer user_data;
|
|
||||||
GDestroyNotify user_destroy;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _GtkFunctionsListItemFactoryClass
|
|
||||||
{
|
|
||||||
GtkListItemFactoryClass parent_class;
|
|
||||||
};
|
|
||||||
|
|
||||||
G_DEFINE_TYPE (GtkFunctionsListItemFactory, gtk_functions_list_item_factory, GTK_TYPE_LIST_ITEM_FACTORY)
|
|
||||||
|
|
||||||
static void
|
|
||||||
gtk_functions_list_item_factory_setup (GtkListItemFactory *factory,
|
|
||||||
GtkListItemWidget *widget,
|
|
||||||
GtkListItem *list_item)
|
|
||||||
{
|
|
||||||
GtkFunctionsListItemFactory *self = GTK_FUNCTIONS_LIST_ITEM_FACTORY (factory);
|
|
||||||
|
|
||||||
if (self->setup_func)
|
|
||||||
self->setup_func (list_item, self->user_data);
|
|
||||||
|
|
||||||
GTK_LIST_ITEM_FACTORY_CLASS (gtk_functions_list_item_factory_parent_class)->setup (factory, widget, list_item);
|
|
||||||
|
|
||||||
if (gtk_list_item_get_item (list_item) != NULL && self->bind_func)
|
|
||||||
self->bind_func (list_item, self->user_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gtk_functions_list_item_factory_update (GtkListItemFactory *factory,
|
|
||||||
GtkListItemWidget *widget,
|
|
||||||
GtkListItem *list_item,
|
|
||||||
guint position,
|
|
||||||
gpointer item,
|
|
||||||
gboolean selected)
|
|
||||||
{
|
|
||||||
GtkFunctionsListItemFactory *self = GTK_FUNCTIONS_LIST_ITEM_FACTORY (factory);
|
|
||||||
|
|
||||||
GTK_LIST_ITEM_FACTORY_CLASS (gtk_functions_list_item_factory_parent_class)->update (factory, widget, list_item, position, item, selected);
|
|
||||||
|
|
||||||
if (item != NULL && self->bind_func)
|
|
||||||
self->bind_func (list_item, self->user_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gtk_functions_list_item_factory_finalize (GObject *object)
|
|
||||||
{
|
|
||||||
GtkFunctionsListItemFactory *self = GTK_FUNCTIONS_LIST_ITEM_FACTORY (object);
|
|
||||||
|
|
||||||
if (self->user_destroy)
|
|
||||||
self->user_destroy (self->user_data);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (gtk_functions_list_item_factory_parent_class)->finalize (object);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gtk_functions_list_item_factory_class_init (GtkFunctionsListItemFactoryClass *klass)
|
|
||||||
{
|
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
||||||
GtkListItemFactoryClass *factory_class = GTK_LIST_ITEM_FACTORY_CLASS (klass);
|
|
||||||
|
|
||||||
object_class->finalize = gtk_functions_list_item_factory_finalize;
|
|
||||||
|
|
||||||
factory_class->setup = gtk_functions_list_item_factory_setup;
|
|
||||||
factory_class->update = gtk_functions_list_item_factory_update;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gtk_functions_list_item_factory_init (GtkFunctionsListItemFactory *self)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* gtk_functions_list_item_factory_new: (skip)
|
|
||||||
* @setup_func: (scope call) (destroy user_destroy): the setup function for the list item factory
|
|
||||||
* @bind_func: (scope call) (destroy user_destroy): the bind function for the list item factory
|
|
||||||
* @user_data: user data for the @setup_func and @bind_func functions
|
|
||||||
* @user_destroy: a function called to destroy @user_data
|
|
||||||
*
|
|
||||||
* Creates a new #GtkListItemFactory with the given functions.
|
|
||||||
*
|
|
||||||
* Returns: (transfer full): the newly created list item factory object
|
|
||||||
*/
|
|
||||||
GtkListItemFactory *
|
|
||||||
gtk_functions_list_item_factory_new (GtkListItemSetupFunc setup_func,
|
|
||||||
GtkListItemBindFunc bind_func,
|
|
||||||
gpointer user_data,
|
|
||||||
GDestroyNotify user_destroy)
|
|
||||||
{
|
|
||||||
GtkFunctionsListItemFactory *self;
|
|
||||||
|
|
||||||
g_return_val_if_fail (setup_func || bind_func, NULL);
|
|
||||||
g_return_val_if_fail (user_data != NULL || user_destroy == NULL, NULL);
|
|
||||||
|
|
||||||
self = g_object_new (GTK_TYPE_FUNCTIONS_LIST_ITEM_FACTORY, NULL);
|
|
||||||
|
|
||||||
self->setup_func = setup_func;
|
|
||||||
self->bind_func = bind_func;
|
|
||||||
self->user_data = user_data;
|
|
||||||
self->user_destroy = user_destroy;
|
|
||||||
|
|
||||||
return GTK_LIST_ITEM_FACTORY (self);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright © 2019 Benjamin Otte
|
|
||||||
*
|
|
||||||
* 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.1 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/>.
|
|
||||||
*
|
|
||||||
* Authors: Benjamin Otte <otte@gnome.org>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __GTK_FUNCTIONS_LIST_ITEM_FACTORY_H__
|
|
||||||
#define __GTK_FUNCTIONS_LIST_ITEM_FACTORY_H__
|
|
||||||
|
|
||||||
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
|
|
||||||
#error "Only <gtk/gtk.h> can be included directly."
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <gtk/gtklistitemfactory.h>
|
|
||||||
#include <gtk/gtklistitem.h>
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
|
||||||
|
|
||||||
#define GTK_TYPE_FUNCTIONS_LIST_ITEM_FACTORY (gtk_functions_list_item_factory_get_type ())
|
|
||||||
#define GTK_FUNCTIONS_LIST_ITEM_FACTORY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GTK_TYPE_FUNCTIONS_LIST_ITEM_FACTORY, GtkFunctionsListItemFactory))
|
|
||||||
#define GTK_FUNCTIONS_LIST_ITEM_FACTORY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GTK_TYPE_FUNCTIONS_LIST_ITEM_FACTORY, GtkFunctionsListItemFactoryClass))
|
|
||||||
#define GTK_IS_FUNCTIONS_LIST_ITEM_FACTORY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GTK_TYPE_FUNCTIONS_LIST_ITEM_FACTORY))
|
|
||||||
#define GTK_IS_FUNCTIONS_LIST_ITEM_FACTORY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GTK_TYPE_FUNCTIONS_LIST_ITEM_FACTORY))
|
|
||||||
#define GTK_FUNCTIONS_LIST_ITEM_FACTORY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GTK_TYPE_FUNCTIONS_LIST_ITEM_FACTORY, GtkFunctionsListItemFactoryClass))
|
|
||||||
|
|
||||||
typedef struct _GtkFunctionsListItemFactory GtkFunctionsListItemFactory;
|
|
||||||
typedef struct _GtkFunctionsListItemFactoryClass GtkFunctionsListItemFactoryClass;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GtkListItemSetupFunc:
|
|
||||||
* @item: the #GtkListItem to set up
|
|
||||||
* @user_data: (closure): user data
|
|
||||||
*
|
|
||||||
* Called whenever a new list item needs to be setup for managing a row in
|
|
||||||
* the list.
|
|
||||||
*
|
|
||||||
* At this point, the list item is not bound yet, so gtk_list_item_get_item()
|
|
||||||
* will return %NULL.
|
|
||||||
* The list item will later be bound to an item via the #GtkListItemBindFunc.
|
|
||||||
*/
|
|
||||||
typedef void (* GtkListItemSetupFunc) (GtkListItem *item, gpointer user_data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GtkListItemBindFunc:
|
|
||||||
* @item: the #GtkListItem to bind
|
|
||||||
* @user_data: (closure): user data
|
|
||||||
*
|
|
||||||
* Binds a#GtkListItem previously set up via a #GtkListItemSetupFunc to
|
|
||||||
* an @item.
|
|
||||||
*
|
|
||||||
* Rebinding a @item to different @items is supported as well as
|
|
||||||
* unbinding it by setting @item to %NULL.
|
|
||||||
*/
|
|
||||||
typedef void (* GtkListItemBindFunc) (GtkListItem *item,
|
|
||||||
gpointer user_data);
|
|
||||||
|
|
||||||
GDK_AVAILABLE_IN_ALL
|
|
||||||
GType gtk_functions_list_item_factory_get_type (void) G_GNUC_CONST;
|
|
||||||
|
|
||||||
GDK_AVAILABLE_IN_ALL
|
|
||||||
GtkListItemFactory * gtk_functions_list_item_factory_new (GtkListItemSetupFunc setup_func,
|
|
||||||
GtkListItemBindFunc bind_func,
|
|
||||||
gpointer user_data,
|
|
||||||
GDestroyNotify user_destroy);
|
|
||||||
|
|
||||||
|
|
||||||
G_END_DECLS
|
|
||||||
|
|
||||||
#endif /* __GTK_FUNCTIONS_LIST_ITEM_FACTORY_H__ */
|
|
||||||
@@ -1171,6 +1171,8 @@ gtk_grid_view_init (GtkGridView *self)
|
|||||||
gtk_list_base_set_anchor_max_widgets (GTK_LIST_BASE (self),
|
gtk_list_base_set_anchor_max_widgets (GTK_LIST_BASE (self),
|
||||||
self->max_columns * GTK_GRID_VIEW_MAX_VISIBLE_ROWS,
|
self->max_columns * GTK_GRID_VIEW_MAX_VISIBLE_ROWS,
|
||||||
self->max_columns);
|
self->max_columns);
|
||||||
|
|
||||||
|
gtk_widget_add_css_class (GTK_WIDGET (self), "view");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+3
-1
@@ -595,7 +595,7 @@ gtk_header_bar_class_init (GtkHeaderBarClass *class)
|
|||||||
g_param_spec_boolean ("show-title-buttons",
|
g_param_spec_boolean ("show-title-buttons",
|
||||||
P_("Show title buttons"),
|
P_("Show title buttons"),
|
||||||
P_("Whether to show title buttons"),
|
P_("Whether to show title buttons"),
|
||||||
FALSE,
|
TRUE,
|
||||||
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
|
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -629,6 +629,7 @@ gtk_header_bar_init (GtkHeaderBar *bar)
|
|||||||
|
|
||||||
priv->title_widget = NULL;
|
priv->title_widget = NULL;
|
||||||
priv->decoration_layout = NULL;
|
priv->decoration_layout = NULL;
|
||||||
|
priv->show_title_buttons = TRUE;
|
||||||
priv->state = GDK_SURFACE_STATE_WITHDRAWN;
|
priv->state = GDK_SURFACE_STATE_WITHDRAWN;
|
||||||
|
|
||||||
priv->handle = gtk_window_handle_new ();
|
priv->handle = gtk_window_handle_new ();
|
||||||
@@ -646,6 +647,7 @@ gtk_header_bar_init (GtkHeaderBar *bar)
|
|||||||
gtk_center_box_set_end_widget (GTK_CENTER_BOX (priv->center_box), priv->end_box);
|
gtk_center_box_set_end_widget (GTK_CENTER_BOX (priv->center_box), priv->end_box);
|
||||||
|
|
||||||
construct_title_label (bar);
|
construct_title_label (bar);
|
||||||
|
create_window_controls (bar);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GtkBuildableIface *parent_buildable_iface;
|
static GtkBuildableIface *parent_buildable_iface;
|
||||||
|
|||||||
+30
-25
@@ -55,6 +55,14 @@
|
|||||||
#include "gdk/gdktextureprivate.h"
|
#include "gdk/gdktextureprivate.h"
|
||||||
#include "gdk/gdkprofilerprivate.h"
|
#include "gdk/gdkprofilerprivate.h"
|
||||||
|
|
||||||
|
#define GTK_VECTOR_ELEMENT_TYPE char *
|
||||||
|
#define GTK_VECTOR_NULL_TERMINATED 1
|
||||||
|
#define GTK_VECTOR_FREE_FUNC g_free
|
||||||
|
#define GTK_VECTOR_TYPE_NAME GtkStrvBuilder
|
||||||
|
#define GTK_VECTOR_NAME gtk_strv_builder
|
||||||
|
#define GTK_VECTOR_PREALLOC 16
|
||||||
|
#include "gtkvectorimpl.c"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION:gtkicontheme
|
* SECTION:gtkicontheme
|
||||||
* @Short_description: Looking up icons by name
|
* @Short_description: Looking up icons by name
|
||||||
@@ -2276,13 +2284,13 @@ real_choose_icon (GtkIconTheme *self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
icon_name_list_add_icon (GPtrArray *icons,
|
icon_name_list_add_icon (GtkStrvBuilder *icons,
|
||||||
const gchar *dir_suffix,
|
const gchar *dir_suffix,
|
||||||
gchar *icon_name)
|
gchar *icon_name)
|
||||||
{
|
{
|
||||||
if (dir_suffix)
|
if (dir_suffix)
|
||||||
g_ptr_array_add (icons, g_strconcat (icon_name, dir_suffix, NULL));
|
gtk_strv_builder_append (icons, g_strconcat (icon_name, dir_suffix, NULL));
|
||||||
g_ptr_array_add (icons, icon_name);
|
gtk_strv_builder_append (icons, icon_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GtkIconPaintable *
|
static GtkIconPaintable *
|
||||||
@@ -2296,7 +2304,7 @@ choose_icon (GtkIconTheme *self,
|
|||||||
{
|
{
|
||||||
gboolean has_regular = FALSE, has_symbolic = FALSE;
|
gboolean has_regular = FALSE, has_symbolic = FALSE;
|
||||||
GtkIconPaintable *icon;
|
GtkIconPaintable *icon;
|
||||||
GPtrArray *new_names;
|
GtkStrvBuilder new_names;
|
||||||
const gchar *dir_suffix;
|
const gchar *dir_suffix;
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
@@ -2327,73 +2335,70 @@ choose_icon (GtkIconTheme *self,
|
|||||||
|
|
||||||
if ((flags & GTK_ICON_LOOKUP_FORCE_REGULAR) && has_symbolic)
|
if ((flags & GTK_ICON_LOOKUP_FORCE_REGULAR) && has_symbolic)
|
||||||
{
|
{
|
||||||
new_names = g_ptr_array_new_with_free_func (g_free);
|
gtk_strv_builder_init (&new_names);
|
||||||
for (i = 0; icon_names[i]; i++)
|
for (i = 0; icon_names[i]; i++)
|
||||||
{
|
{
|
||||||
if (icon_name_is_symbolic (icon_names[i], -1))
|
if (icon_name_is_symbolic (icon_names[i], -1))
|
||||||
icon_name_list_add_icon (new_names, dir_suffix, g_strndup (icon_names[i], strlen (icon_names[i]) - strlen ("-symbolic")));
|
icon_name_list_add_icon (&new_names, dir_suffix, g_strndup (icon_names[i], strlen (icon_names[i]) - strlen ("-symbolic")));
|
||||||
else
|
else
|
||||||
icon_name_list_add_icon (new_names, dir_suffix, g_strdup (icon_names[i]));
|
icon_name_list_add_icon (&new_names, dir_suffix, g_strdup (icon_names[i]));
|
||||||
}
|
}
|
||||||
for (i = 0; icon_names[i]; i++)
|
for (i = 0; icon_names[i]; i++)
|
||||||
{
|
{
|
||||||
if (icon_name_is_symbolic (icon_names[i], -1))
|
if (icon_name_is_symbolic (icon_names[i], -1))
|
||||||
icon_name_list_add_icon (new_names, dir_suffix, g_strdup (icon_names[i]));
|
icon_name_list_add_icon (&new_names, dir_suffix, g_strdup (icon_names[i]));
|
||||||
}
|
}
|
||||||
g_ptr_array_add (new_names, NULL);
|
|
||||||
|
|
||||||
icon = real_choose_icon (self,
|
icon = real_choose_icon (self,
|
||||||
(const gchar **) new_names->pdata,
|
(const char **) gtk_strv_builder_get_data (&new_names),
|
||||||
size,
|
size,
|
||||||
scale,
|
scale,
|
||||||
flags & ~(GTK_ICON_LOOKUP_FORCE_REGULAR | GTK_ICON_LOOKUP_FORCE_SYMBOLIC),
|
flags & ~(GTK_ICON_LOOKUP_FORCE_REGULAR | GTK_ICON_LOOKUP_FORCE_SYMBOLIC),
|
||||||
non_blocking);
|
non_blocking);
|
||||||
|
|
||||||
g_ptr_array_free (new_names, TRUE);
|
gtk_strv_builder_clear (&new_names);
|
||||||
}
|
}
|
||||||
else if ((flags & GTK_ICON_LOOKUP_FORCE_SYMBOLIC) && has_regular)
|
else if ((flags & GTK_ICON_LOOKUP_FORCE_SYMBOLIC) && has_regular)
|
||||||
{
|
{
|
||||||
new_names = g_ptr_array_new_with_free_func (g_free);
|
gtk_strv_builder_init (&new_names);
|
||||||
for (i = 0; icon_names[i]; i++)
|
for (i = 0; icon_names[i]; i++)
|
||||||
{
|
{
|
||||||
if (!icon_name_is_symbolic (icon_names[i], -1))
|
if (!icon_name_is_symbolic (icon_names[i], -1))
|
||||||
icon_name_list_add_icon (new_names, dir_suffix, g_strconcat (icon_names[i], "-symbolic", NULL));
|
icon_name_list_add_icon (&new_names, dir_suffix, g_strconcat (icon_names[i], "-symbolic", NULL));
|
||||||
else
|
else
|
||||||
icon_name_list_add_icon (new_names, dir_suffix, g_strdup (icon_names[i]));
|
icon_name_list_add_icon (&new_names, dir_suffix, g_strdup (icon_names[i]));
|
||||||
}
|
}
|
||||||
for (i = 0; icon_names[i]; i++)
|
for (i = 0; icon_names[i]; i++)
|
||||||
{
|
{
|
||||||
if (!icon_name_is_symbolic (icon_names[i], -1))
|
if (!icon_name_is_symbolic (icon_names[i], -1))
|
||||||
icon_name_list_add_icon (new_names, dir_suffix, g_strdup (icon_names[i]));
|
icon_name_list_add_icon (&new_names, dir_suffix, g_strdup (icon_names[i]));
|
||||||
}
|
}
|
||||||
g_ptr_array_add (new_names, NULL);
|
|
||||||
|
|
||||||
icon = real_choose_icon (self,
|
icon = real_choose_icon (self,
|
||||||
(const gchar **) new_names->pdata,
|
(const char **) gtk_strv_builder_get_data (&new_names),
|
||||||
size,
|
size,
|
||||||
scale,
|
scale,
|
||||||
flags & ~(GTK_ICON_LOOKUP_FORCE_REGULAR | GTK_ICON_LOOKUP_FORCE_SYMBOLIC),
|
flags & ~(GTK_ICON_LOOKUP_FORCE_REGULAR | GTK_ICON_LOOKUP_FORCE_SYMBOLIC),
|
||||||
non_blocking);
|
non_blocking);
|
||||||
|
|
||||||
g_ptr_array_free (new_names, TRUE);
|
gtk_strv_builder_clear (&new_names);
|
||||||
}
|
}
|
||||||
else if (dir_suffix)
|
else if (dir_suffix)
|
||||||
{
|
{
|
||||||
new_names = g_ptr_array_new_with_free_func (g_free);
|
gtk_strv_builder_init (&new_names);
|
||||||
for (i = 0; icon_names[i]; i++)
|
for (i = 0; icon_names[i]; i++)
|
||||||
{
|
{
|
||||||
icon_name_list_add_icon (new_names, dir_suffix, g_strdup (icon_names[i]));
|
icon_name_list_add_icon (&new_names, dir_suffix, g_strdup (icon_names[i]));
|
||||||
}
|
}
|
||||||
g_ptr_array_add (new_names, NULL);
|
|
||||||
|
|
||||||
icon = real_choose_icon (self,
|
icon = real_choose_icon (self,
|
||||||
(const gchar **) new_names->pdata,
|
(const char **) gtk_strv_builder_get_data (&new_names),
|
||||||
size,
|
size,
|
||||||
scale,
|
scale,
|
||||||
flags & ~(GTK_ICON_LOOKUP_FORCE_REGULAR | GTK_ICON_LOOKUP_FORCE_SYMBOLIC),
|
flags & ~(GTK_ICON_LOOKUP_FORCE_REGULAR | GTK_ICON_LOOKUP_FORCE_SYMBOLIC),
|
||||||
non_blocking);
|
non_blocking);
|
||||||
|
|
||||||
g_ptr_array_free (new_names, TRUE);
|
gtk_strv_builder_clear (&new_names);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
+7
-4
@@ -3573,12 +3573,15 @@ static void
|
|||||||
gtk_label_unrealize (GtkWidget *widget)
|
gtk_label_unrealize (GtkWidget *widget)
|
||||||
{
|
{
|
||||||
GtkLabel *self = GTK_LABEL (widget);
|
GtkLabel *self = GTK_LABEL (widget);
|
||||||
GdkClipboard *clipboard;
|
|
||||||
|
|
||||||
clipboard = gtk_widget_get_primary_clipboard (widget);
|
|
||||||
if (self->select_info &&
|
if (self->select_info &&
|
||||||
gdk_clipboard_get_content (clipboard) == self->select_info->provider)
|
self->select_info->provider)
|
||||||
gdk_clipboard_set_content (clipboard, NULL);
|
{
|
||||||
|
GdkClipboard *clipboard = gtk_widget_get_primary_clipboard (widget);
|
||||||
|
|
||||||
|
if (gdk_clipboard_get_content (clipboard) == self->select_info->provider)
|
||||||
|
gdk_clipboard_set_content (clipboard, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
GTK_WIDGET_CLASS (gtk_label_parent_class)->unrealize (widget);
|
GTK_WIDGET_CLASS (gtk_label_parent_class)->unrealize (widget);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,7 +56,7 @@
|
|||||||
* Various implementations of #GtkListItemFactory exist to allow you different
|
* Various implementations of #GtkListItemFactory exist to allow you different
|
||||||
* ways to provide those widgets. The most common implementations are
|
* ways to provide those widgets. The most common implementations are
|
||||||
* #GtkBuilderListItemFactory which takes a #GtkBuilder .ui file and then creates
|
* #GtkBuilderListItemFactory which takes a #GtkBuilder .ui file and then creates
|
||||||
* and manages widgets everything automatically from the information in that file
|
* widgets and manages everything automatically from the information in that file
|
||||||
* and #GtkSignalListItemFactory which allows you to connect to signals with your
|
* and #GtkSignalListItemFactory which allows you to connect to signals with your
|
||||||
* own code and retain full control over how the widgets are setup and managed.
|
* own code and retain full control over how the widgets are setup and managed.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -925,6 +925,8 @@ gtk_list_view_init (GtkListView *self)
|
|||||||
gtk_list_base_set_anchor_max_widgets (GTK_LIST_BASE (self),
|
gtk_list_base_set_anchor_max_widgets (GTK_LIST_BASE (self),
|
||||||
GTK_LIST_VIEW_MAX_LIST_ITEMS,
|
GTK_LIST_VIEW_MAX_LIST_ITEMS,
|
||||||
GTK_LIST_VIEW_EXTRA_ITEMS);
|
GTK_LIST_VIEW_EXTRA_ITEMS);
|
||||||
|
|
||||||
|
gtk_widget_add_css_class (GTK_WIDGET (self), "view");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+24
-20
@@ -95,7 +95,6 @@
|
|||||||
#include "gdk/gdk-private.h"
|
#include "gdk/gdk-private.h"
|
||||||
#include "gsk/gskprivate.h"
|
#include "gsk/gskprivate.h"
|
||||||
#include "gsk/gskrendernodeprivate.h"
|
#include "gsk/gskrendernodeprivate.h"
|
||||||
#include "gtkarrayimplprivate.h"
|
|
||||||
#include "gtknative.h"
|
#include "gtknative.h"
|
||||||
|
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
@@ -138,6 +137,13 @@
|
|||||||
#include "a11y/gtkaccessibility.h"
|
#include "a11y/gtkaccessibility.h"
|
||||||
#include "inspector/window.h"
|
#include "inspector/window.h"
|
||||||
|
|
||||||
|
#define GTK_VECTOR_ELEMENT_TYPE GtkWidget *
|
||||||
|
#define GTK_VECTOR_TYPE_NAME GtkWidgetStack
|
||||||
|
#define GTK_VECTOR_NAME gtk_widget_stack
|
||||||
|
#define GTK_VECTOR_FREE_FUNC g_object_unref
|
||||||
|
#define GTK_VECTOR_PREALLOC 16
|
||||||
|
#include "gtkvectorimpl.c"
|
||||||
|
|
||||||
static GtkWindowGroup *gtk_main_get_window_group (GtkWidget *widget);
|
static GtkWindowGroup *gtk_main_get_window_group (GtkWidget *widget);
|
||||||
|
|
||||||
static gint pre_initialized = FALSE;
|
static gint pre_initialized = FALSE;
|
||||||
@@ -1321,8 +1327,7 @@ gtk_synthesize_crossing_events (GtkRoot *toplevel,
|
|||||||
double x, y;
|
double x, y;
|
||||||
GtkWidget *prev;
|
GtkWidget *prev;
|
||||||
gboolean seen_ancestor;
|
gboolean seen_ancestor;
|
||||||
GtkArray target_array;
|
GtkWidgetStack target_array;
|
||||||
GtkWidget *stack_targets[16];
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (old_target == new_target)
|
if (old_target == new_target)
|
||||||
@@ -1376,19 +1381,19 @@ gtk_synthesize_crossing_events (GtkRoot *toplevel,
|
|||||||
widget = _gtk_widget_get_parent (widget);
|
widget = _gtk_widget_get_parent (widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
gtk_array_init (&target_array, (void**)stack_targets, 16);
|
gtk_widget_stack_init (&target_array);
|
||||||
for (widget = new_target; widget; widget = _gtk_widget_get_parent (widget))
|
for (widget = new_target; widget; widget = _gtk_widget_get_parent (widget))
|
||||||
gtk_array_add (&target_array, widget);
|
gtk_widget_stack_append (&target_array, g_object_ref (widget));
|
||||||
|
|
||||||
crossing.direction = GTK_CROSSING_IN;
|
crossing.direction = GTK_CROSSING_IN;
|
||||||
|
|
||||||
seen_ancestor = FALSE;
|
seen_ancestor = FALSE;
|
||||||
for (i = (int)target_array.len - 1; i >= 0; i--)
|
for (i = gtk_widget_stack_get_size (&target_array) - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
widget = gtk_array_index (&target_array, i);
|
widget = gtk_widget_stack_get (&target_array, i);
|
||||||
|
|
||||||
if (i < (int)target_array.len - 1)
|
if (i < gtk_widget_stack_get_size (&target_array) - 1)
|
||||||
crossing.new_descendent = gtk_array_index (&target_array, i + 1);
|
crossing.new_descendent = gtk_widget_stack_get (&target_array, i + 1);
|
||||||
else
|
else
|
||||||
crossing.new_descendent = NULL;
|
crossing.new_descendent = NULL;
|
||||||
|
|
||||||
@@ -1417,7 +1422,7 @@ gtk_synthesize_crossing_events (GtkRoot *toplevel,
|
|||||||
gtk_widget_set_state_flags (widget, GTK_STATE_FLAG_PRELIGHT, FALSE);
|
gtk_widget_set_state_flags (widget, GTK_STATE_FLAG_PRELIGHT, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
gtk_array_free (&target_array, NULL);
|
gtk_widget_stack_clear (&target_array);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GtkWidget *
|
static GtkWidget *
|
||||||
@@ -1994,13 +1999,12 @@ gtk_propagate_event_internal (GtkWidget *widget,
|
|||||||
{
|
{
|
||||||
gint handled_event = FALSE;
|
gint handled_event = FALSE;
|
||||||
GtkWidget *target = widget;
|
GtkWidget *target = widget;
|
||||||
GtkArray widget_array;
|
GtkWidgetStack widget_array;
|
||||||
GtkWidget *stack_widgets[16];
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* First, propagate event down */
|
/* First, propagate event down */
|
||||||
gtk_array_init (&widget_array, (void**)stack_widgets, 16);
|
gtk_widget_stack_init (&widget_array);
|
||||||
gtk_array_add (&widget_array, g_object_ref (widget));
|
gtk_widget_stack_append (&widget_array, g_object_ref (widget));
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
@@ -2008,16 +2012,16 @@ gtk_propagate_event_internal (GtkWidget *widget,
|
|||||||
if (!widget)
|
if (!widget)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
gtk_array_add (&widget_array, g_object_ref (widget));
|
gtk_widget_stack_append (&widget_array, g_object_ref (widget));
|
||||||
|
|
||||||
if (widget == topmost)
|
if (widget == topmost)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
i = widget_array.len - 1;
|
i = gtk_widget_stack_get_size (&widget_array) - 1;
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
widget = gtk_array_index (&widget_array, i);
|
widget = gtk_widget_stack_get (&widget_array, i);
|
||||||
|
|
||||||
if (!_gtk_widget_is_sensitive (widget))
|
if (!_gtk_widget_is_sensitive (widget))
|
||||||
{
|
{
|
||||||
@@ -2050,9 +2054,9 @@ gtk_propagate_event_internal (GtkWidget *widget,
|
|||||||
* parents can see the button and motion
|
* parents can see the button and motion
|
||||||
* events of the children.
|
* events of the children.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < widget_array.len; i++)
|
for (i = 0; i < gtk_widget_stack_get_size (&widget_array); i++)
|
||||||
{
|
{
|
||||||
widget = gtk_array_index (&widget_array, i);
|
widget = gtk_widget_stack_get (&widget_array, i);
|
||||||
|
|
||||||
/* Scroll events are special cased here because it
|
/* Scroll events are special cased here because it
|
||||||
* feels wrong when scrolling a GtkViewport, say,
|
* feels wrong when scrolling a GtkViewport, say,
|
||||||
@@ -2071,7 +2075,7 @@ gtk_propagate_event_internal (GtkWidget *widget,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gtk_array_free (&widget_array, g_object_unref);
|
gtk_widget_stack_clear (&widget_array);
|
||||||
return handled_event;
|
return handled_event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-35
@@ -63,7 +63,6 @@
|
|||||||
enum {
|
enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_HAS_MAP,
|
PROP_HAS_MAP,
|
||||||
PROP_ITEM_TYPE,
|
|
||||||
PROP_MODEL,
|
PROP_MODEL,
|
||||||
NUM_PROPERTIES
|
NUM_PROPERTIES
|
||||||
};
|
};
|
||||||
@@ -86,7 +85,6 @@ struct _GtkMapListModel
|
|||||||
{
|
{
|
||||||
GObject parent_instance;
|
GObject parent_instance;
|
||||||
|
|
||||||
GType item_type;
|
|
||||||
GListModel *model;
|
GListModel *model;
|
||||||
GtkMapListModelMapFunc map_func;
|
GtkMapListModelMapFunc map_func;
|
||||||
gpointer user_data;
|
gpointer user_data;
|
||||||
@@ -145,9 +143,7 @@ gtk_map_list_model_get_nth (GtkRbTree *tree,
|
|||||||
static GType
|
static GType
|
||||||
gtk_map_list_model_get_item_type (GListModel *list)
|
gtk_map_list_model_get_item_type (GListModel *list)
|
||||||
{
|
{
|
||||||
GtkMapListModel *self = GTK_MAP_LIST_MODEL (list);
|
return G_TYPE_OBJECT;
|
||||||
|
|
||||||
return self->item_type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static guint
|
static guint
|
||||||
@@ -199,11 +195,6 @@ gtk_map_list_model_get_item (GListModel *list,
|
|||||||
}
|
}
|
||||||
|
|
||||||
node->item = self->map_func (g_list_model_get_item (self->model, position), self->user_data);
|
node->item = self->map_func (g_list_model_get_item (self->model, position), self->user_data);
|
||||||
if (!G_TYPE_CHECK_INSTANCE_TYPE (node->item, self->item_type))
|
|
||||||
{
|
|
||||||
g_critical ("Map function returned a %s, but it is not a subtype of the model's type %s",
|
|
||||||
G_OBJECT_TYPE_NAME (node->item), g_type_name (self->item_type));
|
|
||||||
}
|
|
||||||
g_object_add_weak_pointer (node->item, &node->item);
|
g_object_add_weak_pointer (node->item, &node->item);
|
||||||
|
|
||||||
return node->item;
|
return node->item;
|
||||||
@@ -293,10 +284,6 @@ gtk_map_list_model_set_property (GObject *object,
|
|||||||
|
|
||||||
switch (prop_id)
|
switch (prop_id)
|
||||||
{
|
{
|
||||||
case PROP_ITEM_TYPE:
|
|
||||||
self->item_type = g_value_get_gtype (value);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PROP_MODEL:
|
case PROP_MODEL:
|
||||||
gtk_map_list_model_set_model (self, g_value_get_object (value));
|
gtk_map_list_model_set_model (self, g_value_get_object (value));
|
||||||
break;
|
break;
|
||||||
@@ -321,10 +308,6 @@ gtk_map_list_model_get_property (GObject *object,
|
|||||||
g_value_set_boolean (value, self->items != NULL);
|
g_value_set_boolean (value, self->items != NULL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_ITEM_TYPE:
|
|
||||||
g_value_set_gtype (value, self->item_type);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PROP_MODEL:
|
case PROP_MODEL:
|
||||||
g_value_set_object (value, self->model);
|
g_value_set_object (value, self->model);
|
||||||
break;
|
break;
|
||||||
@@ -382,18 +365,6 @@ gtk_map_list_model_class_init (GtkMapListModelClass *class)
|
|||||||
FALSE,
|
FALSE,
|
||||||
GTK_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY);
|
GTK_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY);
|
||||||
|
|
||||||
/**
|
|
||||||
* GtkMapListModel:item-type:
|
|
||||||
*
|
|
||||||
* The #GType for elements of this object
|
|
||||||
*/
|
|
||||||
properties[PROP_ITEM_TYPE] =
|
|
||||||
g_param_spec_gtype ("item-type",
|
|
||||||
P_("Item type"),
|
|
||||||
P_("The type of elements of this object"),
|
|
||||||
G_TYPE_OBJECT,
|
|
||||||
GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GtkMapListModel:model:
|
* GtkMapListModel:model:
|
||||||
*
|
*
|
||||||
@@ -441,7 +412,6 @@ gtk_map_list_model_augment (GtkRbTree *map,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* gtk_map_list_model_new:
|
* gtk_map_list_model_new:
|
||||||
* @item_type: the #GType to use as the model's item type
|
|
||||||
* @model: (allow-none): The model to map or %NULL for none
|
* @model: (allow-none): The model to map or %NULL for none
|
||||||
* @map_func: (allow-none): map function or %NULL to not map items
|
* @map_func: (allow-none): map function or %NULL to not map items
|
||||||
* @user_data: (closure): user data passed to @map_func
|
* @user_data: (closure): user data passed to @map_func
|
||||||
@@ -452,19 +422,16 @@ gtk_map_list_model_augment (GtkRbTree *map,
|
|||||||
* Returns: a new #GtkMapListModel
|
* Returns: a new #GtkMapListModel
|
||||||
**/
|
**/
|
||||||
GtkMapListModel *
|
GtkMapListModel *
|
||||||
gtk_map_list_model_new (GType item_type,
|
gtk_map_list_model_new (GListModel *model,
|
||||||
GListModel *model,
|
|
||||||
GtkMapListModelMapFunc map_func,
|
GtkMapListModelMapFunc map_func,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GDestroyNotify user_destroy)
|
GDestroyNotify user_destroy)
|
||||||
{
|
{
|
||||||
GtkMapListModel *result;
|
GtkMapListModel *result;
|
||||||
|
|
||||||
g_return_val_if_fail (g_type_is_a (item_type, G_TYPE_OBJECT), NULL);
|
|
||||||
g_return_val_if_fail (model == NULL || G_IS_LIST_MODEL (model), NULL);
|
g_return_val_if_fail (model == NULL || G_IS_LIST_MODEL (model), NULL);
|
||||||
|
|
||||||
result = g_object_new (GTK_TYPE_MAP_LIST_MODEL,
|
result = g_object_new (GTK_TYPE_MAP_LIST_MODEL,
|
||||||
"item-type", item_type,
|
|
||||||
"model", model,
|
"model", model,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
|
|||||||
@@ -53,8 +53,7 @@ G_DECLARE_FINAL_TYPE (GtkMapListModel, gtk_map_list_model, GTK, MAP_LIST_MODEL,
|
|||||||
typedef gpointer (* GtkMapListModelMapFunc) (gpointer item, gpointer user_data);
|
typedef gpointer (* GtkMapListModelMapFunc) (gpointer item, gpointer user_data);
|
||||||
|
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
GtkMapListModel * gtk_map_list_model_new (GType item_type,
|
GtkMapListModel * gtk_map_list_model_new (GListModel *model,
|
||||||
GListModel *model,
|
|
||||||
GtkMapListModelMapFunc map_func,
|
GtkMapListModelMapFunc map_func,
|
||||||
gpointer user_data,
|
gpointer user_data,
|
||||||
GDestroyNotify user_destroy);
|
GDestroyNotify user_destroy);
|
||||||
|
|||||||
+73
-12
@@ -62,9 +62,7 @@ static GParamSpec *properties[N_PROPS] = { NULL, };
|
|||||||
static GType
|
static GType
|
||||||
gtk_multi_selection_get_item_type (GListModel *list)
|
gtk_multi_selection_get_item_type (GListModel *list)
|
||||||
{
|
{
|
||||||
GtkMultiSelection *self = GTK_MULTI_SELECTION (list);
|
return G_TYPE_OBJECT;
|
||||||
|
|
||||||
return g_list_model_get_item_type (self->model);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static guint
|
static guint
|
||||||
@@ -72,6 +70,9 @@ gtk_multi_selection_get_n_items (GListModel *list)
|
|||||||
{
|
{
|
||||||
GtkMultiSelection *self = GTK_MULTI_SELECTION (list);
|
GtkMultiSelection *self = GTK_MULTI_SELECTION (list);
|
||||||
|
|
||||||
|
if (self->model == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
return g_list_model_get_n_items (self->model);
|
return g_list_model_get_n_items (self->model);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,6 +82,9 @@ gtk_multi_selection_get_item (GListModel *list,
|
|||||||
{
|
{
|
||||||
GtkMultiSelection *self = GTK_MULTI_SELECTION (list);
|
GtkMultiSelection *self = GTK_MULTI_SELECTION (list);
|
||||||
|
|
||||||
|
if (self->model == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
return g_list_model_get_item (self->model, position);
|
return g_list_model_get_item (self->model, position);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,7 +178,7 @@ gtk_multi_selection_set_selection (GtkSelectionModel *model,
|
|||||||
max = gtk_bitset_get_maximum (changes);
|
max = gtk_bitset_get_maximum (changes);
|
||||||
|
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
n_items = g_list_model_get_n_items (self->model);
|
n_items = self->model ? g_list_model_get_n_items (self->model) : 0;
|
||||||
if (max >= n_items)
|
if (max >= n_items)
|
||||||
{
|
{
|
||||||
gtk_bitset_remove_range_closed (changes, n_items, max);
|
gtk_bitset_remove_range_closed (changes, n_items, max);
|
||||||
@@ -218,7 +222,7 @@ gtk_multi_selection_items_changed_cb (GListModel *model,
|
|||||||
GHashTable *pending = NULL;
|
GHashTable *pending = NULL;
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
gtk_bitset_slice (self->selected, position, removed, added);
|
gtk_bitset_splice (self->selected, position, removed, added);
|
||||||
|
|
||||||
g_hash_table_iter_init (&iter, self->items);
|
g_hash_table_iter_init (&iter, self->items);
|
||||||
while (g_hash_table_iter_next (&iter, &item, &pos_pointer))
|
while (g_hash_table_iter_next (&iter, &item, &pos_pointer))
|
||||||
@@ -291,12 +295,7 @@ gtk_multi_selection_set_property (GObject *object,
|
|||||||
switch (prop_id)
|
switch (prop_id)
|
||||||
{
|
{
|
||||||
case PROP_MODEL:
|
case PROP_MODEL:
|
||||||
self->model = g_value_dup_object (value);
|
gtk_multi_selection_set_model (self, g_value_get_object (value));
|
||||||
g_warn_if_fail (self->model != NULL);
|
|
||||||
g_signal_connect (self->model,
|
|
||||||
"items-changed",
|
|
||||||
G_CALLBACK (gtk_multi_selection_items_changed_cb),
|
|
||||||
self);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -357,7 +356,7 @@ gtk_multi_selection_class_init (GtkMultiSelectionClass *klass)
|
|||||||
P_("Model"),
|
P_("Model"),
|
||||||
P_("List managed by this selection"),
|
P_("List managed by this selection"),
|
||||||
G_TYPE_LIST_MODEL,
|
G_TYPE_LIST_MODEL,
|
||||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||||
|
|
||||||
g_object_class_install_properties (gobject_class, N_PROPS, properties);
|
g_object_class_install_properties (gobject_class, N_PROPS, properties);
|
||||||
}
|
}
|
||||||
@@ -386,3 +385,65 @@ gtk_multi_selection_new (GListModel *model)
|
|||||||
"model", model,
|
"model", model,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gtk_multi_selection_get_model:
|
||||||
|
* @self: a #GtkMultiSelection
|
||||||
|
*
|
||||||
|
* Returns the underlying model of @self.
|
||||||
|
*
|
||||||
|
* Returns: (transfer none): the underlying model
|
||||||
|
*/
|
||||||
|
GListModel *
|
||||||
|
gtk_multi_selection_get_model (GtkMultiSelection *self)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GTK_IS_MULTI_SELECTION (self), NULL);
|
||||||
|
|
||||||
|
return self->model;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gtk_multi_selection_set_model:
|
||||||
|
* @self: a #GtkMultiSelection
|
||||||
|
* @model: (allow-none): A #GListModel to wrap
|
||||||
|
*
|
||||||
|
* Sets the model that @self should wrap. If @model is %NULL, @self
|
||||||
|
* will be empty.
|
||||||
|
**/
|
||||||
|
void
|
||||||
|
gtk_multi_selection_set_model (GtkMultiSelection *self,
|
||||||
|
GListModel *model)
|
||||||
|
{
|
||||||
|
guint n_items_before;
|
||||||
|
|
||||||
|
g_return_if_fail (GTK_IS_MULTI_SELECTION (self));
|
||||||
|
g_return_if_fail (model == NULL || G_IS_LIST_MODEL (model));
|
||||||
|
|
||||||
|
if (self->model == model)
|
||||||
|
return;
|
||||||
|
|
||||||
|
n_items_before = self->model ? g_list_model_get_n_items (self->model) : 0;
|
||||||
|
gtk_multi_selection_clear_model (self);
|
||||||
|
|
||||||
|
if (model)
|
||||||
|
{
|
||||||
|
self->model = g_object_ref (model);
|
||||||
|
g_signal_connect (self->model,
|
||||||
|
"items-changed",
|
||||||
|
G_CALLBACK (gtk_multi_selection_items_changed_cb),
|
||||||
|
self);
|
||||||
|
gtk_multi_selection_items_changed_cb (self->model,
|
||||||
|
0,
|
||||||
|
n_items_before,
|
||||||
|
g_list_model_get_n_items (model),
|
||||||
|
self);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gtk_bitset_remove_all (self->selected);
|
||||||
|
g_hash_table_remove_all (self->items);
|
||||||
|
g_list_model_items_changed (G_LIST_MODEL (self), 0, n_items_before, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MODEL]);
|
||||||
|
}
|
||||||
|
|||||||
@@ -33,6 +33,11 @@ G_DECLARE_FINAL_TYPE (GtkMultiSelection, gtk_multi_selection, GTK, MULTI_SELECTI
|
|||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
GListModel * gtk_multi_selection_new (GListModel *model);
|
GListModel * gtk_multi_selection_new (GListModel *model);
|
||||||
|
|
||||||
|
GDK_AVAILABLE_IN_ALL
|
||||||
|
GListModel * gtk_multi_selection_get_model (GtkMultiSelection *self);
|
||||||
|
GDK_AVAILABLE_IN_ALL
|
||||||
|
void gtk_multi_selection_set_model (GtkMultiSelection *self,
|
||||||
|
GListModel *model);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|||||||
+50
-12
@@ -60,9 +60,7 @@ static GParamSpec *properties[N_PROPS] = { NULL, };
|
|||||||
static GType
|
static GType
|
||||||
gtk_no_selection_get_item_type (GListModel *list)
|
gtk_no_selection_get_item_type (GListModel *list)
|
||||||
{
|
{
|
||||||
GtkNoSelection *self = GTK_NO_SELECTION (list);
|
return G_TYPE_OBJECT;
|
||||||
|
|
||||||
return g_list_model_get_item_type (self->model);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static guint
|
static guint
|
||||||
@@ -70,15 +68,21 @@ gtk_no_selection_get_n_items (GListModel *list)
|
|||||||
{
|
{
|
||||||
GtkNoSelection *self = GTK_NO_SELECTION (list);
|
GtkNoSelection *self = GTK_NO_SELECTION (list);
|
||||||
|
|
||||||
|
if (self->model == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
return g_list_model_get_n_items (self->model);
|
return g_list_model_get_n_items (self->model);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gpointer
|
static gpointer
|
||||||
gtk_no_selection_get_item (GListModel *list,
|
gtk_no_selection_get_item (GListModel *list,
|
||||||
guint position)
|
guint position)
|
||||||
{
|
{
|
||||||
GtkNoSelection *self = GTK_NO_SELECTION (list);
|
GtkNoSelection *self = GTK_NO_SELECTION (list);
|
||||||
|
|
||||||
|
if (self->model == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
return g_list_model_get_item (self->model, position);
|
return g_list_model_get_item (self->model, position);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,9 +136,9 @@ gtk_no_selection_clear_model (GtkNoSelection *self)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_no_selection_set_property (GObject *object,
|
gtk_no_selection_set_property (GObject *object,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
const GValue *value,
|
const GValue *value,
|
||||||
GParamSpec *pspec)
|
GParamSpec *pspec)
|
||||||
|
|
||||||
{
|
{
|
||||||
GtkNoSelection *self = GTK_NO_SELECTION (object);
|
GtkNoSelection *self = GTK_NO_SELECTION (object);
|
||||||
@@ -142,10 +146,7 @@ gtk_no_selection_set_property (GObject *object,
|
|||||||
switch (prop_id)
|
switch (prop_id)
|
||||||
{
|
{
|
||||||
case PROP_MODEL:
|
case PROP_MODEL:
|
||||||
gtk_no_selection_clear_model (self);
|
gtk_no_selection_set_model (self, g_value_get_object (value));
|
||||||
self->model = g_value_dup_object (value);
|
|
||||||
g_signal_connect_swapped (self->model, "items-changed",
|
|
||||||
G_CALLBACK (g_list_model_items_changed), self);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -203,7 +204,7 @@ gtk_no_selection_class_init (GtkNoSelectionClass *klass)
|
|||||||
P_("The model"),
|
P_("The model"),
|
||||||
P_("The model being managed"),
|
P_("The model being managed"),
|
||||||
G_TYPE_LIST_MODEL,
|
G_TYPE_LIST_MODEL,
|
||||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||||
|
|
||||||
g_object_class_install_properties (gobject_class, N_PROPS, properties);
|
g_object_class_install_properties (gobject_class, N_PROPS, properties);
|
||||||
}
|
}
|
||||||
@@ -247,3 +248,40 @@ gtk_no_selection_get_model (GtkNoSelection *self)
|
|||||||
return self->model;
|
return self->model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gtk_no_selection_set_model:
|
||||||
|
* @self: a #GtkNoSelection
|
||||||
|
* @model: (allow-none): A #GListModel to wrap
|
||||||
|
*
|
||||||
|
* Sets the model that @self should wrap. If @model is %NULL, this
|
||||||
|
* model will be empty.
|
||||||
|
**/
|
||||||
|
void
|
||||||
|
gtk_no_selection_set_model (GtkNoSelection *self,
|
||||||
|
GListModel *model)
|
||||||
|
{
|
||||||
|
guint n_items_before;
|
||||||
|
|
||||||
|
g_return_if_fail (GTK_IS_NO_SELECTION (self));
|
||||||
|
g_return_if_fail (model == NULL || G_IS_LIST_MODEL (model));
|
||||||
|
|
||||||
|
if (self->model == model)
|
||||||
|
return;
|
||||||
|
|
||||||
|
n_items_before = self->model ? g_list_model_get_n_items (self->model) : 0;
|
||||||
|
gtk_no_selection_clear_model (self);
|
||||||
|
|
||||||
|
if (model)
|
||||||
|
{
|
||||||
|
self->model = g_object_ref (model);
|
||||||
|
g_signal_connect_swapped (self->model, "items-changed",
|
||||||
|
G_CALLBACK (g_list_model_items_changed), self);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_list_model_items_changed (G_LIST_MODEL (self),
|
||||||
|
0,
|
||||||
|
n_items_before,
|
||||||
|
model ? g_list_model_get_n_items (self->model) : 0);
|
||||||
|
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MODEL]);
|
||||||
|
}
|
||||||
|
|||||||
@@ -34,6 +34,9 @@ GtkNoSelection * gtk_no_selection_new (GListModel
|
|||||||
|
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
GListModel * gtk_no_selection_get_model (GtkNoSelection *self);
|
GListModel * gtk_no_selection_get_model (GtkNoSelection *self);
|
||||||
|
GDK_AVAILABLE_IN_ALL
|
||||||
|
void gtk_no_selection_set_model (GtkNoSelection *self,
|
||||||
|
GListModel *model);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|||||||
@@ -306,7 +306,7 @@ gtk_page_setup_unix_dialog_init (GtkPageSetupUnixDialog *dialog)
|
|||||||
g_list_store_append (store, dialog->page_setup_list);
|
g_list_store_append (store, dialog->page_setup_list);
|
||||||
g_list_store_append (store, dialog->custom_paper_list);
|
g_list_store_append (store, dialog->custom_paper_list);
|
||||||
g_list_store_append (store, dialog->manage_papers_list);
|
g_list_store_append (store, dialog->manage_papers_list);
|
||||||
paper_size_list = G_LIST_MODEL (gtk_flatten_list_model_new (GTK_TYPE_PAGE_SETUP, G_LIST_MODEL (store)));
|
paper_size_list = G_LIST_MODEL (gtk_flatten_list_model_new (G_LIST_MODEL (store)));
|
||||||
gtk_drop_down_set_model (GTK_DROP_DOWN (dialog->paper_size_combo), paper_size_list);
|
gtk_drop_down_set_model (GTK_DROP_DOWN (dialog->paper_size_combo), paper_size_list);
|
||||||
g_object_unref (store);
|
g_object_unref (store);
|
||||||
g_object_unref (paper_size_list);
|
g_object_unref (paper_size_list);
|
||||||
@@ -321,7 +321,7 @@ gtk_page_setup_unix_dialog_init (GtkPageSetupUnixDialog *dialog)
|
|||||||
g_list_store_append (printer_list_list, printer_list);
|
g_list_store_append (printer_list_list, printer_list);
|
||||||
g_object_unref (printer_list);
|
g_object_unref (printer_list);
|
||||||
|
|
||||||
full_list = G_LIST_MODEL (gtk_flatten_list_model_new (GTK_TYPE_PRINTER, G_LIST_MODEL (printer_list_list)));
|
full_list = G_LIST_MODEL (gtk_flatten_list_model_new (G_LIST_MODEL (printer_list_list)));
|
||||||
|
|
||||||
filter = gtk_custom_filter_new (match_func, NULL, NULL);
|
filter = gtk_custom_filter_new (match_func, NULL, NULL);
|
||||||
dialog->printer_list = G_LIST_MODEL (gtk_filter_list_model_new (full_list, filter));
|
dialog->printer_list = G_LIST_MODEL (gtk_filter_list_model_new (full_list, filter));
|
||||||
|
|||||||
+47
-56
@@ -162,7 +162,7 @@ struct _GtkPlacesSidebar {
|
|||||||
|
|
||||||
GtkWidget *popover;
|
GtkWidget *popover;
|
||||||
GtkSidebarRow *context_row;
|
GtkSidebarRow *context_row;
|
||||||
GSList *shortcuts;
|
GListStore *shortcuts;
|
||||||
|
|
||||||
GDBusProxy *hostnamed_proxy;
|
GDBusProxy *hostnamed_proxy;
|
||||||
GCancellable *hostnamed_cancellable;
|
GCancellable *hostnamed_cancellable;
|
||||||
@@ -709,15 +709,25 @@ file_is_shown (GtkPlacesSidebar *sidebar,
|
|||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GtkPlacesSidebar *sidebar;
|
||||||
|
guint position;
|
||||||
|
} ShortcutData;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_app_shortcuts_query_complete (GObject *source,
|
on_app_shortcuts_query_complete (GObject *source,
|
||||||
GAsyncResult *result,
|
GAsyncResult *result,
|
||||||
gpointer data)
|
gpointer data)
|
||||||
{
|
{
|
||||||
GtkPlacesSidebar *sidebar = data;
|
ShortcutData *sdata = data;
|
||||||
|
GtkPlacesSidebar *sidebar = sdata->sidebar;
|
||||||
|
guint pos = sdata->position;
|
||||||
GFile *file = G_FILE (source);
|
GFile *file = G_FILE (source);
|
||||||
GFileInfo *info;
|
GFileInfo *info;
|
||||||
|
|
||||||
|
g_free (sdata);
|
||||||
|
|
||||||
info = g_file_query_info_finish (file, result, NULL);
|
info = g_file_query_info_finish (file, result, NULL);
|
||||||
|
|
||||||
if (info)
|
if (info)
|
||||||
@@ -726,20 +736,12 @@ on_app_shortcuts_query_complete (GObject *source,
|
|||||||
gchar *tooltip;
|
gchar *tooltip;
|
||||||
const gchar *name;
|
const gchar *name;
|
||||||
GIcon *start_icon;
|
GIcon *start_icon;
|
||||||
int pos = 0;
|
|
||||||
|
|
||||||
name = g_file_info_get_display_name (info);
|
name = g_file_info_get_display_name (info);
|
||||||
start_icon = g_file_info_get_symbolic_icon (info);
|
start_icon = g_file_info_get_symbolic_icon (info);
|
||||||
uri = g_file_get_uri (file);
|
uri = g_file_get_uri (file);
|
||||||
tooltip = g_file_get_parse_name (file);
|
tooltip = g_file_get_parse_name (file);
|
||||||
|
|
||||||
/* XXX: we could avoid this by using an ancillary closure
|
|
||||||
* with the index coming from add_application_shortcuts(),
|
|
||||||
* but in terms of algorithmic overhead, the application
|
|
||||||
* shortcuts is not going to be really big
|
|
||||||
*/
|
|
||||||
pos = g_slist_index (sidebar->shortcuts, file);
|
|
||||||
|
|
||||||
add_place (sidebar, PLACES_BUILT_IN,
|
add_place (sidebar, PLACES_BUILT_IN,
|
||||||
SECTION_COMPUTER,
|
SECTION_COMPUTER,
|
||||||
name, start_icon, NULL, uri,
|
name, start_icon, NULL, uri,
|
||||||
@@ -757,11 +759,13 @@ on_app_shortcuts_query_complete (GObject *source,
|
|||||||
static void
|
static void
|
||||||
add_application_shortcuts (GtkPlacesSidebar *sidebar)
|
add_application_shortcuts (GtkPlacesSidebar *sidebar)
|
||||||
{
|
{
|
||||||
GSList *l;
|
guint i, n;
|
||||||
|
|
||||||
for (l = sidebar->shortcuts; l; l = l->next)
|
n = g_list_model_get_n_items (G_LIST_MODEL (sidebar->shortcuts));
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
{
|
{
|
||||||
GFile *file = l->data;
|
GFile *file = g_list_model_get_item (G_LIST_MODEL (sidebar->shortcuts), i);
|
||||||
|
ShortcutData *data;
|
||||||
|
|
||||||
if (!should_show_file (sidebar, file))
|
if (!should_show_file (sidebar, file))
|
||||||
continue;
|
continue;
|
||||||
@@ -769,13 +773,16 @@ add_application_shortcuts (GtkPlacesSidebar *sidebar)
|
|||||||
if (file_is_shown (sidebar, file))
|
if (file_is_shown (sidebar, file))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
data = g_new (ShortcutData, 1);
|
||||||
|
data->sidebar = sidebar;
|
||||||
|
data->position = i;
|
||||||
g_file_query_info_async (file,
|
g_file_query_info_async (file,
|
||||||
"standard::display-name,standard::symbolic-icon",
|
"standard::display-name,standard::symbolic-icon",
|
||||||
G_FILE_QUERY_INFO_NONE,
|
G_FILE_QUERY_INFO_NONE,
|
||||||
G_PRIORITY_DEFAULT,
|
G_PRIORITY_DEFAULT,
|
||||||
sidebar->cancellable,
|
sidebar->cancellable,
|
||||||
on_app_shortcuts_query_complete,
|
on_app_shortcuts_query_complete,
|
||||||
sidebar);
|
data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3748,6 +3755,8 @@ gtk_places_sidebar_init (GtkPlacesSidebar *sidebar)
|
|||||||
sidebar->show_recent = TRUE;
|
sidebar->show_recent = TRUE;
|
||||||
sidebar->show_desktop = TRUE;
|
sidebar->show_desktop = TRUE;
|
||||||
|
|
||||||
|
sidebar->shortcuts = g_list_store_new (G_TYPE_FILE);
|
||||||
|
|
||||||
create_volume_monitor (sidebar);
|
create_volume_monitor (sidebar);
|
||||||
|
|
||||||
sidebar->open_flags = GTK_PLACES_OPEN_NORMAL;
|
sidebar->open_flags = GTK_PLACES_OPEN_NORMAL;
|
||||||
@@ -4018,9 +4027,7 @@ gtk_places_sidebar_dispose (GObject *object)
|
|||||||
|
|
||||||
g_clear_object (&sidebar->current_location);
|
g_clear_object (&sidebar->current_location);
|
||||||
g_clear_pointer (&sidebar->rename_uri, g_free);
|
g_clear_pointer (&sidebar->rename_uri, g_free);
|
||||||
|
g_clear_object (&sidebar->shortcuts);
|
||||||
g_slist_free_full (sidebar->shortcuts, g_object_unref);
|
|
||||||
sidebar->shortcuts = NULL;
|
|
||||||
|
|
||||||
#ifdef HAVE_CLOUDPROVIDERS
|
#ifdef HAVE_CLOUDPROVIDERS
|
||||||
for (l = cloud_providers_collector_get_providers (sidebar->cloud_manager);
|
for (l = cloud_providers_collector_get_providers (sidebar->cloud_manager);
|
||||||
@@ -4782,24 +4789,6 @@ gtk_places_sidebar_get_show_trash (GtkPlacesSidebar *sidebar)
|
|||||||
return sidebar->show_trash;
|
return sidebar->show_trash;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GSList *
|
|
||||||
find_shortcut_link (GtkPlacesSidebar *sidebar,
|
|
||||||
GFile *location)
|
|
||||||
{
|
|
||||||
GSList *l;
|
|
||||||
|
|
||||||
for (l = sidebar->shortcuts; l; l = l->next)
|
|
||||||
{
|
|
||||||
GFile *shortcut;
|
|
||||||
|
|
||||||
shortcut = G_FILE (l->data);
|
|
||||||
if (g_file_equal (shortcut, location))
|
|
||||||
return l;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* gtk_places_sidebar_add_shortcut:
|
* gtk_places_sidebar_add_shortcut:
|
||||||
* @sidebar: a places sidebar
|
* @sidebar: a places sidebar
|
||||||
@@ -4823,8 +4812,7 @@ gtk_places_sidebar_add_shortcut (GtkPlacesSidebar *sidebar,
|
|||||||
g_return_if_fail (GTK_IS_PLACES_SIDEBAR (sidebar));
|
g_return_if_fail (GTK_IS_PLACES_SIDEBAR (sidebar));
|
||||||
g_return_if_fail (G_IS_FILE (location));
|
g_return_if_fail (G_IS_FILE (location));
|
||||||
|
|
||||||
g_object_ref (location);
|
g_list_store_append (sidebar->shortcuts, location);
|
||||||
sidebar->shortcuts = g_slist_append (sidebar->shortcuts, location);
|
|
||||||
|
|
||||||
update_places (sidebar);
|
update_places (sidebar);
|
||||||
}
|
}
|
||||||
@@ -4842,43 +4830,46 @@ void
|
|||||||
gtk_places_sidebar_remove_shortcut (GtkPlacesSidebar *sidebar,
|
gtk_places_sidebar_remove_shortcut (GtkPlacesSidebar *sidebar,
|
||||||
GFile *location)
|
GFile *location)
|
||||||
{
|
{
|
||||||
GSList *link;
|
guint i, n;
|
||||||
GFile *shortcut;
|
|
||||||
|
|
||||||
g_return_if_fail (GTK_IS_PLACES_SIDEBAR (sidebar));
|
g_return_if_fail (GTK_IS_PLACES_SIDEBAR (sidebar));
|
||||||
g_return_if_fail (G_IS_FILE (location));
|
g_return_if_fail (G_IS_FILE (location));
|
||||||
|
|
||||||
link = find_shortcut_link (sidebar, location);
|
n = g_list_model_get_n_items (G_LIST_MODEL (sidebar->shortcuts));
|
||||||
if (!link)
|
for (i = 0; i < n; i++)
|
||||||
return;
|
{
|
||||||
|
GFile *shortcut = g_list_model_get_item (G_LIST_MODEL (sidebar->shortcuts), i);
|
||||||
|
|
||||||
shortcut = G_FILE (link->data);
|
if (shortcut == location)
|
||||||
g_object_unref (shortcut);
|
{
|
||||||
|
g_list_store_remove (sidebar->shortcuts, i);
|
||||||
|
g_object_unref (shortcut);
|
||||||
|
update_places (sidebar);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
sidebar->shortcuts = g_slist_delete_link (sidebar->shortcuts, link);
|
g_object_unref (shortcut);
|
||||||
update_places (sidebar);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* gtk_places_sidebar_list_shortcuts:
|
* gtk_places_sidebar_list_shortcuts:
|
||||||
* @sidebar: a places sidebar
|
* @sidebar: a places sidebar
|
||||||
*
|
*
|
||||||
* Gets the list of shortcuts.
|
* Gets the list of shortcuts, as a list model containing #GFile objects.
|
||||||
*
|
*
|
||||||
* Returns: (element-type GFile) (transfer full):
|
* You should not modify the returned list model. Future changes to
|
||||||
* A #GSList of #GFile of the locations that have been added as
|
* @sidebar may or may not affect the returned model.
|
||||||
|
*
|
||||||
|
* Returns: (transfer full): a list model of #GFiles that have been added as
|
||||||
* application-specific shortcuts with gtk_places_sidebar_add_shortcut().
|
* application-specific shortcuts with gtk_places_sidebar_add_shortcut().
|
||||||
* To free this list, you can use
|
|
||||||
* |[<!-- language="C" -->
|
|
||||||
* g_slist_free_full (list, (GDestroyNotify) g_object_unref);
|
|
||||||
* ]|
|
|
||||||
*/
|
*/
|
||||||
GSList *
|
GListModel *
|
||||||
gtk_places_sidebar_list_shortcuts (GtkPlacesSidebar *sidebar)
|
gtk_places_sidebar_get_shortcuts (GtkPlacesSidebar *sidebar)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (GTK_IS_PLACES_SIDEBAR (sidebar), NULL);
|
g_return_val_if_fail (GTK_IS_PLACES_SIDEBAR (sidebar), NULL);
|
||||||
|
|
||||||
return g_slist_copy_deep (sidebar->shortcuts, (GCopyFunc) g_object_ref, NULL);
|
return G_LIST_MODEL (g_object_ref (sidebar->shortcuts));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ void gtk_places_sidebar_add_shortcut (GtkPlacesSideb
|
|||||||
GFile *location);
|
GFile *location);
|
||||||
void gtk_places_sidebar_remove_shortcut (GtkPlacesSidebar *sidebar,
|
void gtk_places_sidebar_remove_shortcut (GtkPlacesSidebar *sidebar,
|
||||||
GFile *location);
|
GFile *location);
|
||||||
GSList * gtk_places_sidebar_list_shortcuts (GtkPlacesSidebar *sidebar);
|
GListModel * gtk_places_sidebar_get_shortcuts (GtkPlacesSidebar *sidebar);
|
||||||
|
|
||||||
GFile * gtk_places_sidebar_get_nth_bookmark (GtkPlacesSidebar *sidebar,
|
GFile * gtk_places_sidebar_get_nth_bookmark (GtkPlacesSidebar *sidebar,
|
||||||
gint n);
|
gint n);
|
||||||
|
|||||||
@@ -806,7 +806,7 @@ gtk_print_unix_dialog_init (GtkPrintUnixDialog *dialog)
|
|||||||
g_list_store_append (store, dialog->page_setup_list);
|
g_list_store_append (store, dialog->page_setup_list);
|
||||||
g_list_store_append (store, dialog->custom_paper_list);
|
g_list_store_append (store, dialog->custom_paper_list);
|
||||||
g_list_store_append (store, dialog->manage_papers_list);
|
g_list_store_append (store, dialog->manage_papers_list);
|
||||||
paper_size_list = G_LIST_MODEL (gtk_flatten_list_model_new (GTK_TYPE_PAGE_SETUP, G_LIST_MODEL (store)));
|
paper_size_list = G_LIST_MODEL (gtk_flatten_list_model_new (G_LIST_MODEL (store)));
|
||||||
gtk_drop_down_set_model (GTK_DROP_DOWN (dialog->paper_size_combo), paper_size_list);
|
gtk_drop_down_set_model (GTK_DROP_DOWN (dialog->paper_size_combo), paper_size_list);
|
||||||
g_object_unref (store);
|
g_object_unref (store);
|
||||||
g_object_unref (paper_size_list);
|
g_object_unref (paper_size_list);
|
||||||
@@ -1056,7 +1056,7 @@ load_print_backends (GtkPrintUnixDialog *dialog)
|
|||||||
g_list_store_append (lists, gtk_print_backend_get_printers (backend));
|
g_list_store_append (lists, gtk_print_backend_get_printers (backend));
|
||||||
}
|
}
|
||||||
|
|
||||||
model = G_LIST_MODEL (gtk_flatten_list_model_new (GTK_TYPE_PRINTER, G_LIST_MODEL (lists)));
|
model = G_LIST_MODEL (gtk_flatten_list_model_new (G_LIST_MODEL (lists)));
|
||||||
|
|
||||||
g_object_unref (lists);
|
g_object_unref (lists);
|
||||||
|
|
||||||
|
|||||||
@@ -250,16 +250,6 @@ G_DEFINE_TYPE_WITH_CODE (GtkRange, gtk_range, GTK_TYPE_WIDGET,
|
|||||||
static guint signals[LAST_SIGNAL];
|
static guint signals[LAST_SIGNAL];
|
||||||
static GParamSpec *properties[LAST_PROP];
|
static GParamSpec *properties[LAST_PROP];
|
||||||
|
|
||||||
static void
|
|
||||||
gtk_range_snapshot (GtkWidget *widget,
|
|
||||||
GtkSnapshot *snapshot)
|
|
||||||
{
|
|
||||||
GtkRange *range = GTK_RANGE (widget);
|
|
||||||
GtkRangePrivate *priv = gtk_range_get_instance_private (range);
|
|
||||||
|
|
||||||
gtk_widget_snapshot_child (widget, priv->trough_widget, snapshot);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_range_class_init (GtkRangeClass *class)
|
gtk_range_class_init (GtkRangeClass *class)
|
||||||
{
|
{
|
||||||
@@ -275,7 +265,6 @@ gtk_range_class_init (GtkRangeClass *class)
|
|||||||
gobject_class->dispose = gtk_range_dispose;
|
gobject_class->dispose = gtk_range_dispose;
|
||||||
|
|
||||||
widget_class->measure = gtk_range_measure;
|
widget_class->measure = gtk_range_measure;
|
||||||
widget_class->snapshot = gtk_range_snapshot;
|
|
||||||
widget_class->size_allocate = gtk_range_size_allocate;
|
widget_class->size_allocate = gtk_range_size_allocate;
|
||||||
widget_class->unmap = gtk_range_unmap;
|
widget_class->unmap = gtk_range_unmap;
|
||||||
widget_class->direction_changed = gtk_range_direction_changed;
|
widget_class->direction_changed = gtk_range_direction_changed;
|
||||||
|
|||||||
+13
-11
@@ -47,14 +47,12 @@ static void
|
|||||||
gtk_theming_background_snapshot_color (GtkCssBoxes *boxes,
|
gtk_theming_background_snapshot_color (GtkCssBoxes *boxes,
|
||||||
GtkSnapshot *snapshot,
|
GtkSnapshot *snapshot,
|
||||||
const GdkRGBA *bg_color,
|
const GdkRGBA *bg_color,
|
||||||
const GtkCssValue *background_image)
|
guint n_bg_values)
|
||||||
{
|
{
|
||||||
const GskRoundedRect *box;
|
const GskRoundedRect *box;
|
||||||
gint n_values;
|
|
||||||
GtkCssArea clip;
|
GtkCssArea clip;
|
||||||
|
|
||||||
n_values = _gtk_css_array_value_get_n_values (background_image);
|
clip = _gtk_css_area_value_get (_gtk_css_array_value_get_nth (boxes->style->background->background_clip, n_bg_values - 1));
|
||||||
clip = _gtk_css_area_value_get (_gtk_css_array_value_get_nth (boxes->style->background->background_clip, n_values - 1));
|
|
||||||
box = gtk_css_boxes_get_box (boxes, clip);
|
box = gtk_css_boxes_get_box (boxes, clip);
|
||||||
|
|
||||||
if (gsk_rounded_rect_is_rectilinear (box))
|
if (gsk_rounded_rect_is_rectilinear (box))
|
||||||
@@ -94,9 +92,6 @@ gtk_theming_background_snapshot_layer (GtkCssBoxes *bg,
|
|||||||
|
|
||||||
pos = _gtk_css_array_value_get_nth (background->background_position, idx);
|
pos = _gtk_css_array_value_get_nth (background->background_position, idx);
|
||||||
repeat = _gtk_css_array_value_get_nth (background->background_repeat, idx);
|
repeat = _gtk_css_array_value_get_nth (background->background_repeat, idx);
|
||||||
hrepeat = _gtk_css_background_repeat_value_get_x (repeat);
|
|
||||||
vrepeat = _gtk_css_background_repeat_value_get_y (repeat);
|
|
||||||
|
|
||||||
|
|
||||||
origin = gtk_css_boxes_get_box (bg,
|
origin = gtk_css_boxes_get_box (bg,
|
||||||
_gtk_css_area_value_get (
|
_gtk_css_area_value_get (
|
||||||
@@ -125,8 +120,13 @@ gtk_theming_background_snapshot_layer (GtkCssBoxes *bg,
|
|||||||
/* optimization */
|
/* optimization */
|
||||||
if (image_width == width)
|
if (image_width == width)
|
||||||
hrepeat = GTK_CSS_REPEAT_STYLE_NO_REPEAT;
|
hrepeat = GTK_CSS_REPEAT_STYLE_NO_REPEAT;
|
||||||
|
else
|
||||||
|
hrepeat = _gtk_css_background_repeat_value_get_x (repeat);
|
||||||
|
|
||||||
if (image_height == height)
|
if (image_height == height)
|
||||||
vrepeat = GTK_CSS_REPEAT_STYLE_NO_REPEAT;
|
vrepeat = GTK_CSS_REPEAT_STYLE_NO_REPEAT;
|
||||||
|
else
|
||||||
|
vrepeat = _gtk_css_background_repeat_value_get_y (repeat);
|
||||||
|
|
||||||
gtk_snapshot_push_debug (snapshot, "Layer %u", idx);
|
gtk_snapshot_push_debug (snapshot, "Layer %u", idx);
|
||||||
gtk_snapshot_push_rounded_clip (snapshot, clip);
|
gtk_snapshot_push_rounded_clip (snapshot, clip);
|
||||||
@@ -262,7 +262,8 @@ gtk_css_style_snapshot_background (GtkCssBoxes *boxes,
|
|||||||
gboolean has_bg_color;
|
gboolean has_bg_color;
|
||||||
gboolean has_bg_image;
|
gboolean has_bg_image;
|
||||||
gboolean has_shadow;
|
gboolean has_shadow;
|
||||||
gint idx;
|
int idx;
|
||||||
|
guint number_of_layers;
|
||||||
|
|
||||||
if (background->base.type == GTK_CSS_BACKGROUND_INITIAL_VALUES)
|
if (background->base.type == GTK_CSS_BACKGROUND_INITIAL_VALUES)
|
||||||
return;
|
return;
|
||||||
@@ -286,10 +287,11 @@ gtk_css_style_snapshot_background (GtkCssBoxes *boxes,
|
|||||||
snapshot,
|
snapshot,
|
||||||
gtk_css_boxes_get_border_box (boxes));
|
gtk_css_boxes_get_border_box (boxes));
|
||||||
|
|
||||||
|
number_of_layers = _gtk_css_array_value_get_n_values (background_image);
|
||||||
|
|
||||||
if (has_bg_image)
|
if (has_bg_image)
|
||||||
{
|
{
|
||||||
GtkCssValue *blend_modes = background->background_blend_mode;
|
GtkCssValue *blend_modes = background->background_blend_mode;
|
||||||
const int number_of_layers = _gtk_css_array_value_get_n_values (background_image);
|
|
||||||
GskBlendMode *blend_mode_values = g_alloca (sizeof (GskBlendMode) * number_of_layers);
|
GskBlendMode *blend_mode_values = g_alloca (sizeof (GskBlendMode) * number_of_layers);
|
||||||
|
|
||||||
for (idx = number_of_layers - 1; idx >= 0; idx--)
|
for (idx = number_of_layers - 1; idx >= 0; idx--)
|
||||||
@@ -301,7 +303,7 @@ gtk_css_style_snapshot_background (GtkCssBoxes *boxes,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (has_bg_color)
|
if (has_bg_color)
|
||||||
gtk_theming_background_snapshot_color (boxes, snapshot, bg_color, background_image);
|
gtk_theming_background_snapshot_color (boxes, snapshot, bg_color, number_of_layers);
|
||||||
|
|
||||||
for (idx = number_of_layers - 1; idx >= 0; idx--)
|
for (idx = number_of_layers - 1; idx >= 0; idx--)
|
||||||
{
|
{
|
||||||
@@ -319,7 +321,7 @@ gtk_css_style_snapshot_background (GtkCssBoxes *boxes,
|
|||||||
}
|
}
|
||||||
else if (has_bg_color)
|
else if (has_bg_color)
|
||||||
{
|
{
|
||||||
gtk_theming_background_snapshot_color (boxes, snapshot, bg_color, background_image);
|
gtk_theming_background_snapshot_color (boxes, snapshot, bg_color, number_of_layers);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has_shadow)
|
if (has_shadow)
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user