Compare commits

..

2 Commits

Author SHA1 Message Date
Matthias Clasen 4269ec3f22 Make GtkFileFilter a GtkFilter 2020-07-03 18:19:21 -04:00
Matthias Clasen e68ed9cac1 filefiler: No more floating
Make GtkFileFilter not be initially unowned anymore.
This is in preparation for deriving GtkFileFilter
from GtkFilter. Update all callers.
2020-07-03 18:06:48 -04:00
101 changed files with 4750 additions and 7947 deletions
+1 -1
View File
@@ -188,7 +188,7 @@ constraint_view_init (ConstraintView *self)
g_list_store_append (list, children);
g_list_store_append (list, guides);
g_list_store_append (list, constraints);
self->model = G_LIST_MODEL (gtk_flatten_list_model_new (G_LIST_MODEL (list)));
self->model = G_LIST_MODEL (gtk_flatten_list_model_new (G_TYPE_OBJECT, G_LIST_MODEL (list)));
g_object_unref (children);
g_object_unref (guides);
g_object_unref (constraints);
-1
View File
@@ -226,7 +226,6 @@
<file>listview_minesweeper.c</file>
<file>listview_settings.c</file>
<file>listview_weather.c</file>
<file>listview_words.c</file>
<file>list_store.c</file>
<file>markup.c</file>
<file>modelbutton.c</file>
+3 -63
View File
@@ -676,7 +676,7 @@ create_color_grid (void)
gtk_grid_view_set_max_columns (GTK_GRID_VIEW (gridview), 24);
gtk_grid_view_set_enable_rubberband (GTK_GRID_VIEW (gridview), TRUE);
model = G_LIST_MODEL (gtk_sor3_list_model_new (gtk_color_list_new (0), NULL));
model = G_LIST_MODEL (gtk_sort_list_model_new (gtk_color_list_new (0), NULL));
selection = G_LIST_MODEL (gtk_multi_selection_new (model));
gtk_grid_view_set_model (GTK_GRID_VIEW (gridview), selection);
@@ -835,54 +835,6 @@ update_selection_average (GListModel *model,
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;
GtkWidget *
@@ -1012,7 +964,7 @@ do_listview_colors (GtkWidget *do_widget)
button = gtk_button_new_with_mnemonic ("_Refill");
g_signal_connect (button, "clicked",
G_CALLBACK (refill),
gtk_sor3_list_model_get_model (GTK_SOR3_LIST_MODEL (model)));
gtk_sort_list_model_get_model (GTK_SORT_LIST_MODEL (model)));
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), button);
@@ -1035,7 +987,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 });
g_signal_connect (dropdown, "notify::selected",
G_CALLBACK (limit_changed_cb),
gtk_sor3_list_model_get_model (GTK_SOR3_LIST_MODEL (model)));
gtk_sort_list_model_get_model (GTK_SORT_LIST_MODEL (model)));
g_signal_connect (dropdown, "notify::selected",
G_CALLBACK (limit_changed_cb2),
label);
@@ -1070,30 +1022,18 @@ do_listview_colors (GtkWidget *do_widget)
g_list_store_append (sorters, 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"));
gtk_numeric_sorter_set_sort_order (GTK_NUMERIC_SORTER (sorter), GTK_SORT_DESCENDING);
set_title (sorter, "Green");
g_list_store_append (sorters, 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"));
gtk_numeric_sorter_set_sort_order (GTK_NUMERIC_SORTER (sorter), GTK_SORT_DESCENDING);
set_title (sorter, "Blue");
g_list_store_append (sorters, 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");
g_list_store_append (sorters, multi_sorter);
g_object_unref (multi_sorter);
-241
View File
@@ -1,241 +0,0 @@
/* 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;
}
-1
View File
@@ -49,7 +49,6 @@ demos = files([
'listview_minesweeper.c',
'listview_settings.c',
'listview_weather.c',
'listview_words.c',
'markup.c',
'modelbutton.c',
'overlay.c',
+2 -2
View File
@@ -54,9 +54,8 @@
<section>
<xi:include href="xml/gtkfilter.xml" />
<xi:include href="xml/gtkcustomfilter.xml" />
<xi:include href="xml/gtkmultifilter.xml" />
<xi:include href="xml/gtkstringfilter.xml" />
<xi:include href="xml/gtkfilefilter.xml" />
<xi:include href="xml/gtkmultifilter.xml" />
</section>
<xi:include href="xml/gtkflattenlistmodel.xml" />
<xi:include href="xml/gtkmaplistmodel.xml" />
@@ -286,6 +285,7 @@
<xi:include href="xml/gtkfilechoosernative.xml" />
<xi:include href="xml/gtkfilechooserdialog.xml" />
<xi:include href="xml/gtkfilechooserwidget.xml" />
<xi:include href="xml/gtkfilefilter.xml" />
<xi:include href="xml/gtkfontchooser.xml" />
<xi:include href="xml/gtkfontbutton.xml" />
<xi:include href="xml/gtkfontchooserwidget.xml" />
+11 -12
View File
@@ -348,7 +348,6 @@ GtkBitset
gtk_bitset_ref
gtk_bitset_unref
gtk_bitset_new_empty
gtk_bitset_new_range
gtk_bitset_copy
<SUBSECTION>
gtk_bitset_contains
@@ -375,7 +374,7 @@ gtk_bitset_subtract
gtk_bitset_difference
gtk_bitset_shift_left
gtk_bitset_shift_right
gtk_bitset_splice
gtk_bitset_slice
<SUBSECTION>
GtkBitsetIter
gtk_bitset_iter_init_first
@@ -423,7 +422,6 @@ gtk_selection_model_get_type
GtkNoSelection
gtk_no_selection_new
gtk_no_selection_get_model
gtk_no_selection_set_model
<SUBSECTION Private>
gtk_no_selection_get_type
</SECTION>
@@ -435,7 +433,6 @@ GtkSingleSelection
GTK_INVALID_LIST_POSITION
gtk_single_selection_new
gtk_single_selection_get_model
gtk_single_selection_set_model
gtk_single_selection_get_selected
gtk_single_selection_set_selected
gtk_single_selection_get_selected_item
@@ -453,7 +450,6 @@ gtk_single_selection_get_type
GtkMultiSelection
gtk_multi_selection_new
gtk_multi_selection_get_model
gtk_multi_selection_set_model
<SUBSECTION Private>
gtk_multi_selection_get_type
</SECTION>
@@ -1310,7 +1306,7 @@ gtk_file_chooser_get_current_folder
<SUBSECTION>
gtk_file_chooser_add_filter
gtk_file_chooser_remove_filter
gtk_file_chooser_get_filters
gtk_file_chooser_list_filters
gtk_file_chooser_set_filter
gtk_file_chooser_get_filter
<SUBSECTION>
@@ -1413,13 +1409,18 @@ GtkFileChooserButtonPrivate
<SECTION>
<FILE>gtkfilefilter</FILE>
GtkFileFilter
GtkFileFilterInfo
GtkFileFilterFlags
GtkFileFilterFunc
gtk_file_filter_new
gtk_file_filter_set_name
gtk_file_filter_get_name
gtk_file_filter_add_mime_type
gtk_file_filter_add_pattern
gtk_file_filter_add_pixbuf_formats
gtk_file_filter_get_attributes
gtk_file_filter_add_custom
gtk_file_filter_get_needed
gtk_file_filter_filter
<SUBSECTION Serialization>
gtk_file_filter_new_from_gvariant
@@ -1538,13 +1539,11 @@ gtk_custom_filter_get_type
<TITLE>GtkFilterListModel</TITLE>
GtkFilterListModel
gtk_filter_list_model_new
gtk_filter_list_model_new_for_type
gtk_filter_list_model_set_model
gtk_filter_list_model_get_model
gtk_filter_list_model_set_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>
GTK_FILTER_LIST_MODEL
GTK_IS_FILTER_LIST_MODEL
@@ -2699,6 +2698,7 @@ gtk_size_group_get_type
<TITLE>GtkSliceListModel</TITLE>
GtkSliceListModel
gtk_slice_list_model_new
gtk_slice_list_model_new_for_type
gtk_slice_list_model_set_model
gtk_slice_list_model_get_model
gtk_slice_list_model_set_offset
@@ -2830,6 +2830,7 @@ gtk_tree_list_row_sorter_get_type
<TITLE>GtkSortListModel</TITLE>
GtkSortListModel
gtk_sort_list_model_new
gtk_sort_list_model_new_for_type
gtk_sort_list_model_set_sorter
gtk_sort_list_model_get_sorter
gtk_sort_list_model_set_model
@@ -7609,9 +7610,7 @@ gtk_string_list_take
gtk_string_list_remove
gtk_string_list_splice
gtk_string_list_get_string
<SUBSECTION>
GtkStringObject
gtk_string_object_new
gtk_string_object_get_string
</SECTION>
+1
View File
@@ -295,6 +295,7 @@ gtk_cell_accessible_action_do_action (AtkAction *action,
GtkCellAccessible *cell = GTK_CELL_ACCESSIBLE (action);
GtkCellAccessibleParent *parent;
cell = GTK_CELL_ACCESSIBLE (action);
if (gtk_accessible_get_widget (GTK_ACCESSIBLE (cell)) == NULL)
return FALSE;
+1 -1
View File
@@ -65,7 +65,7 @@ static gunichar
gtk_password_entry_accessible_get_character_at_offset (AtkText *atk_text,
gint offset)
{
GtkText *text;
GtkText *text = get_text_widget (GTK_ACCESSIBLE (atk_text));
char *contents, *index;
gunichar result;
-2
View File
@@ -233,8 +233,6 @@
#include <gtk/gtkslicelistmodel.h>
#include <gtk/gtksnapshot.h>
#include <gtk/gtksorter.h>
#include <gtk/gtksor2listmodel.h>
#include <gtk/gtksor3listmodel.h>
#include <gtk/gtksortlistmodel.h>
#include <gtk/gtkstacksidebar.h>
#include <gtk/gtksizegroup.h>
+137
View File
@@ -0,0 +1,137 @@
#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
+7 -29
View File
@@ -268,7 +268,7 @@ gtk_bitset_get_nth (const GtkBitset *self,
*
* Creates a new empty bitset.
*
* Returns: A new empty bitset
* Returns: A new empty bitset.
**/
GtkBitset *
gtk_bitset_new_empty (void)
@@ -284,28 +284,6 @@ gtk_bitset_new_empty (void)
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:
* @self: a #GtkBitset
@@ -707,7 +685,7 @@ gtk_bitset_shift_right (GtkBitset *self,
}
/**
* gtk_bitset_splice:
* gtk_bitset_slice:
* @self: a #GtkBitset
* @position: position at which to slice
* @removed: number of values to remove
@@ -725,10 +703,10 @@ gtk_bitset_shift_right (GtkBitset *self,
* up space that can then be filled.
**/
void
gtk_bitset_splice (GtkBitset *self,
guint position,
guint removed,
guint added)
gtk_bitset_slice (GtkBitset *self,
guint position,
guint removed,
guint added)
{
g_return_if_fail (self != NULL);
/* overflow */
@@ -742,7 +720,7 @@ gtk_bitset_splice (GtkBitset *self,
GtkBitset *shift = gtk_bitset_copy (self);
gtk_bitset_remove_range (shift, 0, position);
gtk_bitset_remove_range_closed (self, position, G_MAXUINT);
gtk_bitset_remove_range (self, position, G_MAXUINT - position + 1);
if (added > removed)
gtk_bitset_shift_right (shift, added - removed);
else
+1 -4
View File
@@ -65,9 +65,6 @@ GDK_AVAILABLE_IN_ALL
GtkBitset * gtk_bitset_new_empty (void);
GDK_AVAILABLE_IN_ALL
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
void gtk_bitset_remove_all (GtkBitset *self);
@@ -125,7 +122,7 @@ GDK_AVAILABLE_IN_ALL
void gtk_bitset_shift_right (GtkBitset *self,
guint amount);
GDK_AVAILABLE_IN_ALL
void gtk_bitset_splice (GtkBitset *self,
void gtk_bitset_slice (GtkBitset *self,
guint position,
guint removed,
guint added);
+15 -13
View File
@@ -391,9 +391,9 @@ gtk_css_provider_init (GtkCssProvider *css_provider)
}
static void
verify_tree_match_results (GtkCssProvider *provider,
GtkCssNode *node,
GtkCssSelectorMatches *tree_rules)
verify_tree_match_results (GtkCssProvider *provider,
GtkCssNode *node,
GtkArray *tree_rules)
{
#ifdef VERIFY_TREE
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);
for (j = 0; j < gtk_css_selector_matches_get_size (tree_rules); j++)
for (j = 0; j < tree_rules->len; j++)
{
if (ruleset == gtk_css_selector_matches_get (tree_rules, j))
if (ruleset == gtk_array_index (tree_rules, j))
{
found = TRUE;
break;
@@ -459,21 +459,22 @@ gtk_css_style_provider_lookup (GtkStyleProvider *provider,
GtkCssRuleset *ruleset;
guint j;
int i;
GtkCssSelectorMatches tree_rules;
GtkArray tree_rules_array;
GtkCssRuleset *rules_stack[32];
if (_gtk_css_selector_tree_is_empty (priv->tree))
return;
gtk_css_selector_matches_init (&tree_rules);
_gtk_css_selector_tree_match_all (priv->tree, filter, node, &tree_rules);
gtk_array_init (&tree_rules_array, (void**)rules_stack, 32);
_gtk_css_selector_tree_match_all (priv->tree, filter, node, &tree_rules_array);
if (!gtk_css_selector_matches_is_empty (&tree_rules))
if (tree_rules_array.len > 0)
{
verify_tree_match_results (css_provider, node, &tree_rules);
verify_tree_match_results (css_provider, node, &tree_rules_array);
for (i = gtk_css_selector_matches_get_size (&tree_rules) - 1; i >= 0; i--)
for (i = tree_rules_array.len - 1; i >= 0; i--)
{
ruleset = gtk_css_selector_matches_get (&tree_rules, i);
ruleset = gtk_array_index (&tree_rules_array, i);
if (ruleset->styles == NULL)
continue;
@@ -492,8 +493,9 @@ gtk_css_style_provider_lookup (GtkStyleProvider *provider,
ruleset->styles[j].value);
}
}
gtk_array_free (&tree_rules_array, NULL);
}
gtk_css_selector_matches_clear (&tree_rules);
if (change)
*change = gtk_css_selector_tree_get_change_all (priv->tree, filter, node);
+20 -17
View File
@@ -24,6 +24,7 @@
#include "gtkcssprovider.h"
#include "gtkstylecontextprivate.h"
#include "gtkarrayimplprivate.h"
#include <errno.h>
#if defined(_MSC_VER) && _MSC_VER >= 1500
@@ -151,14 +152,14 @@ gtk_css_selector_tree_get_matches (const GtkCssSelectorTree *tree)
}
static void
gtk_css_selector_matches_insert_sorted (GtkCssSelectorMatches *matches,
gpointer data)
gtk_array_insert_sorted (GtkArray *array,
gpointer data)
{
guint i;
for (i = 0; i < gtk_css_selector_matches_get_size (matches); i++)
for (i = 0; i < array->len; i++)
{
gpointer elem = gtk_css_selector_matches_get (matches, i);
gpointer elem = gtk_array_index (array, i);
if (data == elem)
return;
@@ -167,7 +168,7 @@ gtk_css_selector_matches_insert_sorted (GtkCssSelectorMatches *matches,
break;
}
gtk_css_selector_matches_splice (matches, i, 0, (gpointer[1]) { data }, 1);
gtk_array_insert (array, i, data);
}
static inline gboolean
@@ -1876,7 +1877,7 @@ gtk_css_selector_tree_get_change (const GtkCssSelectorTree *tree,
static void
gtk_css_selector_tree_found_match (const GtkCssSelectorTree *tree,
GtkCssSelectorMatches *results)
GtkArray *results)
{
int i;
gpointer *matches;
@@ -1886,7 +1887,7 @@ gtk_css_selector_tree_found_match (const GtkCssSelectorTree *tree,
return;
for (i = 0; matches[i] != NULL; i++)
gtk_css_selector_matches_insert_sorted (results, matches[i]);
gtk_array_insert_sorted (results, matches[i]);
}
static gboolean
@@ -1894,7 +1895,7 @@ gtk_css_selector_tree_match (const GtkCssSelectorTree *tree,
const GtkCountingBloomFilter *filter,
gboolean match_filter,
GtkCssNode *node,
GtkCssSelectorMatches *results)
GtkArray *results)
{
const GtkCssSelectorTree *prev;
GtkCssNode *child;
@@ -1931,7 +1932,7 @@ void
_gtk_css_selector_tree_match_all (const GtkCssSelectorTree *tree,
const GtkCountingBloomFilter *filter,
GtkCssNode *node,
GtkCssSelectorMatches *out_tree_rules)
GtkArray *out_tree_rules)
{
const GtkCssSelectorTree *iter;
@@ -2116,7 +2117,8 @@ subdivide_infos (GByteArray *array,
GHashTableIter iter;
guint max_count;
gpointer key, value;
GtkCssSelectorMatches exact_matches;
void *exact_matches_stack[8];
GtkArray exact_matches_array;
gint32 res;
guint i;
@@ -2158,7 +2160,7 @@ subdivide_infos (GByteArray *array,
matched_infos = g_alloca (sizeof (GtkCssSelectorRuleSetInfo *) * n_infos);
remaining_infos = g_alloca (sizeof (GtkCssSelectorRuleSetInfo *) * n_infos);
gtk_css_selector_matches_init (&exact_matches);
gtk_array_init (&exact_matches_array, (void**)exact_matches_stack, 8);
for (i = 0; i < n_infos; i++)
{
GtkCssSelectorRuleSetInfo *info = infos[i];
@@ -2169,7 +2171,7 @@ subdivide_infos (GByteArray *array,
if (info->current_selector == NULL)
{
/* Matches current node */
gtk_css_selector_matches_append (&exact_matches, info->match);
gtk_array_add (&exact_matches_array, info->match);
if (info->selector_match != NULL)
*info->selector_match = GUINT_TO_POINTER (tree_offset);
}
@@ -2186,16 +2188,17 @@ subdivide_infos (GByteArray *array,
}
}
if (!gtk_css_selector_matches_is_empty (&exact_matches))
if (exact_matches_array.len > 0)
{
gtk_css_selector_matches_append (&exact_matches, NULL); /* Null terminate */
gtk_array_add (&exact_matches_array, NULL); /* Null terminate */
res = array->len;
g_byte_array_append (array, (guint8 *) gtk_css_selector_matches_get_data (&exact_matches),
gtk_css_selector_matches_get_size (&exact_matches) * sizeof (gpointer));
g_byte_array_append (array, (guint8 *)gtk_array_get_data (&exact_matches_array),
exact_matches_array.len * sizeof (gpointer));
gtk_array_free (&exact_matches_array, NULL);
}
else
res = GTK_CSS_SELECTOR_TREE_EMPTY_OFFSET;
gtk_css_selector_matches_clear (&exact_matches);
get_tree (array, tree_offset)->matches_offset = res;
res = subdivide_infos (array, matched_infos, n_matched, tree_offset);
+3 -8
View File
@@ -21,12 +21,7 @@
#include "gtk/gtkcountingbloomfilterprivate.h"
#include "gtk/gtkcsstypesprivate.h"
#include "gtk/gtkcssparserprivate.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"
#include "gtk/gtkarrayimplprivate.h"
G_BEGIN_DECLS
@@ -50,8 +45,8 @@ int _gtk_css_selector_compare (const GtkCssSelector *a,
void _gtk_css_selector_tree_free (GtkCssSelectorTree *tree);
void _gtk_css_selector_tree_match_all (const GtkCssSelectorTree *tree,
const GtkCountingBloomFilter *filter,
GtkCssNode *node,
GtkCssSelectorMatches *out_tree_rules);
GtkCssNode *node,
GtkArray *out_tree_rules);
GtkCssChange gtk_css_selector_tree_get_change_all (const GtkCssSelectorTree *tree,
const GtkCountingBloomFilter *filter,
GtkCssNode *node);
+1 -1
View File
@@ -321,7 +321,7 @@ gtk_custom_paper_unix_dialog_init (GtkCustomPaperUnixDialog *dialog)
g_list_store_append (printer_list_list, printer_list);
g_object_unref (printer_list);
full_list = G_LIST_MODEL (gtk_flatten_list_model_new (G_LIST_MODEL (printer_list_list)));
full_list = G_LIST_MODEL (gtk_flatten_list_model_new (GTK_TYPE_PRINTER, G_LIST_MODEL (printer_list_list)));
g_object_unref (printer_list_list);
filter = gtk_custom_filter_new (match_func, NULL, NULL);
+1 -1
View File
@@ -224,7 +224,7 @@ gtk_drop_controller_motion_class_init (GtkDropControllerMotionClass *klass)
props[PROP_CONTAINS_POINTER] =
g_param_spec_boolean ("contains-pointer",
P_("Contains Pointer"),
P_("Whether the pointer is in the controllers widget or a descendant"),
P_("Whether the pointer is inthe controllers widget or a descendant"),
FALSE,
G_PARAM_READABLE);
+1 -1
View File
@@ -943,7 +943,7 @@ gtk_drop_down_set_from_strings (GtkDropDown *self,
set_default_factory (self);
model = G_LIST_MODEL (gtk_string_list_new (texts));
model = G_LIST_MODEL (gtk_string_list_new ((const char **)texts));
gtk_drop_down_set_model (self, model);
g_object_unref (model);
}
+1 -1
View File
@@ -221,7 +221,7 @@ gtk_event_controller_motion_class_init (GtkEventControllerMotionClass *klass)
props[PROP_CONTAINS_POINTER] =
g_param_spec_boolean ("contains-pointer",
P_("Contains Pointer"),
P_("Whether the pointer is in the controllers widget or a descendant"),
P_("Whether the pointer is inthe controllers widget or a descendant"),
FALSE,
G_PARAM_READABLE);
+15 -50
View File
@@ -168,38 +168,6 @@ gtk_file_chooser_default_init (GtkFileChooserInterface *iface)
FALSE,
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:
*
@@ -714,24 +682,23 @@ gtk_file_chooser_remove_filter (GtkFileChooser *chooser,
}
/**
* gtk_file_chooser_get_filters:
* gtk_file_chooser_list_filters:
* @chooser: a #GtkFileChooser
*
* Gets the current set of user-selectable filters, as a list model; see
* Lists the current set of user-selectable filters; see
* gtk_file_chooser_add_filter(), gtk_file_chooser_remove_filter().
*
* You should not modify the returned list model. Future changes to
* @chooser may or may not affect the returned model.
*
* Returns: (transfer full): a #GListModel containing the current set
* of user-selectable filters.
* Returns: (element-type GtkFileFilter) (transfer container): a
* #GSList containing the current set of user selectable filters. The
* 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.
**/
GListModel *
gtk_file_chooser_get_filters (GtkFileChooser *chooser)
GSList *
gtk_file_chooser_list_filters (GtkFileChooser *chooser)
{
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
return GTK_FILE_CHOOSER_GET_IFACE (chooser)->get_filters (chooser);
return GTK_FILE_CHOOSER_GET_IFACE (chooser)->list_filters (chooser);
}
/**
@@ -783,23 +750,21 @@ gtk_file_chooser_get_filter (GtkFileChooser *chooser)
}
/**
* gtk_file_chooser_get_shortcut_folders:
* gtk_file_chooser_list_shortcut_folders:
* @chooser: a #GtkFileChooser
*
* Queries the list of shortcut folders in the file chooser, as set by
* gtk_file_chooser_add_shortcut_folder().
*
* You should not modify the returned list model. Future changes to
* @chooser may or may not affect the returned model.
*
* Returns: (transfer full): A list model of #GFiles
* Returns: (nullable) (element-type Gio.File) (transfer full): A list
* of folder filenames, or %NULL if there are no shortcut folders.
*/
GListModel *
gtk_file_chooser_get_shortcut_folders (GtkFileChooser *chooser)
GSList *
gtk_file_chooser_list_shortcut_folders (GtkFileChooser *chooser)
{
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
return GTK_FILE_CHOOSER_GET_IFACE (chooser)->get_shortcut_folders (chooser);
return GTK_FILE_CHOOSER_GET_IFACE (chooser)->list_shortcut_folders (chooser);
}
/**
+9 -9
View File
@@ -145,18 +145,18 @@ GFile * gtk_file_chooser_get_current_folder (GtkFileChooser *chooser);
*/
GDK_AVAILABLE_IN_ALL
void gtk_file_chooser_add_filter (GtkFileChooser *chooser,
GtkFileFilter *filter);
GtkFileFilter *filter);
GDK_AVAILABLE_IN_ALL
void gtk_file_chooser_remove_filter (GtkFileChooser *chooser,
GtkFileFilter *filter);
GtkFileFilter *filter);
GDK_AVAILABLE_IN_ALL
GListModel *gtk_file_chooser_get_filters (GtkFileChooser *chooser);
GSList *gtk_file_chooser_list_filters (GtkFileChooser *chooser);
/* Current filter
*/
GDK_AVAILABLE_IN_ALL
void gtk_file_chooser_set_filter (GtkFileChooser *chooser,
GtkFileFilter *filter);
GtkFileFilter *filter);
GDK_AVAILABLE_IN_ALL
GtkFileFilter *gtk_file_chooser_get_filter (GtkFileChooser *chooser);
@@ -164,14 +164,14 @@ GtkFileFilter *gtk_file_chooser_get_filter (GtkFileChooser *chooser);
GDK_AVAILABLE_IN_ALL
gboolean gtk_file_chooser_add_shortcut_folder (GtkFileChooser *chooser,
GFile *folder,
GError **error);
GFile *folder,
GError **error);
GDK_AVAILABLE_IN_ALL
gboolean gtk_file_chooser_remove_shortcut_folder (GtkFileChooser *chooser,
GFile *folder,
GError **error);
GFile *folder,
GError **error);
GDK_AVAILABLE_IN_ALL
GListModel *gtk_file_chooser_get_shortcut_folders (GtkFileChooser *chooser);
GSList *gtk_file_chooser_list_shortcut_folders (GtkFileChooser *chooser);
GDK_AVAILABLE_IN_ALL
void gtk_file_chooser_add_choice (GtkFileChooser *chooser,
-2
View File
@@ -1035,8 +1035,6 @@ gtk_file_chooser_button_get_property (GObject *object,
case GTK_FILE_CHOOSER_PROP_FILTER:
case GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE:
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);
break;
+50 -8
View File
@@ -33,7 +33,6 @@
#include "gtkintl.h"
#include "gtkmarshalers.h"
#include "gtkfilefilterprivate.h"
#include "gtkfilter.h"
#include "gtkeventcontrollerfocus.h"
typedef struct _GtkFileChooserEntryClass GtkFileChooserEntryClass;
@@ -195,22 +194,65 @@ match_func (GtkEntryCompletion *compl,
* current file filter (e.g. just jpg files) here. */
if (chooser_entry->current_filter != NULL)
{
char *mime_type = NULL;
gboolean matches;
GFile *file;
GFileInfo *info;
GFileInfo *file_info;
GtkFileFilterInfo filter_info;
GtkFileFilterFlags needed_flags;
file = _gtk_file_system_model_get_file (GTK_FILE_SYSTEM_MODEL (chooser_entry->completion_store),
iter);
info = _gtk_file_system_model_get_info (GTK_FILE_SYSTEM_MODEL (chooser_entry->completion_store),
iter);
file_info = _gtk_file_system_model_get_info (GTK_FILE_SYSTEM_MODEL (chooser_entry->completion_store),
iter);
/* We always allow navigating into subfolders, so don't ever filter directories */
if (g_file_info_get_file_type (info) != G_FILE_TYPE_REGULAR)
if (g_file_info_get_file_type (file_info) != G_FILE_TYPE_REGULAR)
return TRUE;
if (!g_file_info_has_attribute (info, "standard::file"))
g_file_info_set_attribute_object (info, "standard::file", G_OBJECT (file));
needed_flags = gtk_file_filter_get_needed (chooser_entry->current_filter);
return gtk_filter_match (GTK_FILTER (chooser_entry->current_filter), info);
filter_info.display_name = g_file_info_get_display_name (file_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;
+10 -19
View File
@@ -126,7 +126,7 @@ response_cb (GDBusConnection *connection,
if (current_filter)
{
GtkFileFilter *filter = gtk_file_filter_new_from_gvariant (current_filter);
const char *current_filter_name = gtk_file_filter_get_name (filter);
const gchar *current_filter_name = gtk_file_filter_get_name (filter);
/* Try to find the given filter in the list of filters.
* Since filters are compared by pointer value, using the passed
@@ -137,24 +137,18 @@ response_cb (GDBusConnection *connection,
* If there is no match, just set the filter as it was retrieved.
*/
GtkFileFilter *filter_to_select = filter;
GListModel *filters;
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++)
GSList *filters = gtk_file_chooser_list_filters (GTK_FILE_CHOOSER (self));
for (GSList *l = filters; l; l = l->next)
{
GtkFileFilter *f = g_list_model_get_item (filters, j);
GtkFileFilter *f = l->data;
if (g_strcmp0 (gtk_file_filter_get_name (f), current_filter_name) == 0)
{
filter_to_select = f;
break;
}
g_object_unref (f);
}
g_object_unref (filters);
g_slist_free (filters);
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);
@@ -270,20 +264,17 @@ open_file_msg_cb (GObject *source_object,
static GVariant *
get_filters (GtkFileChooser *self)
{
GListModel *filters;
guint n, i;
GSList *list, *l;
GVariantBuilder builder;
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(sa(us))"));
filters = gtk_file_chooser_get_filters (self);
n = g_list_model_get_n_items (filters);
for (i = 0; i < n; i++)
list = gtk_file_chooser_list_filters (self);
for (l = list; l; l = l->next)
{
GtkFileFilter *filter = g_list_model_get_item (filters, i);
GtkFileFilter *filter = l->data;
g_variant_builder_add (&builder, "@(sa(us))", gtk_file_filter_to_gvariant (filter));
g_object_unref (filter);
}
g_object_unref (filters);
g_slist_free (list);
return g_variant_builder_end (&builder);
}
+14 -36
View File
@@ -99,10 +99,9 @@ typedef struct {
else
[data->panel setAllowedFileTypes:filter];
GListModel *filters = gtk_file_chooser_get_filters (GTK_FILE_CHOOSER (data->self));
data->self->current_filter = g_list_model_get_item (filters, selected_index);
g_object_unref (data->self->current_filter);
g_object_unref (filters);
GSList *filters = gtk_file_chooser_list_filters (GTK_FILE_CHOOSER (data->self));
data->self->current_filter = g_slist_nth_data (filters, selected_index);
g_slist_free (filters);
g_object_notify (G_OBJECT (data->self), "filter");
}
@end
@@ -308,28 +307,13 @@ filechooser_quartz_launch (FileChooserQuartzData *data)
if (data->self->current_filter)
{
GListModel *filters;
guint i, n;
guint current_filter_index = GTK_INVALID_LIST_POSITION;
GSList *filters = gtk_file_chooser_list_filters (GTK_FILE_CHOOSER (data->self));
gint current_filter_index = g_slist_index (filters, data->self->current_filter);
g_slist_free (filters);
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)
if (current_filter_index >= 0)
[data->filter_combo_box selectItemAtIndex:current_filter_index];
else
else
[data->filter_combo_box selectItemAtIndex:0];
}
else
@@ -453,15 +437,15 @@ gtk_file_chooser_native_quartz_show (GtkFileChooserNative *self)
GtkWindow *transient_for;
GtkFileChooserAction action;
GListModel *filters;
guint n_filters, i;
GSList *filters, *l;
int n_filters, i;
char *message = NULL;
data = g_new0 (FileChooserQuartzData, 1);
// examine filters!
filters = gtk_file_chooser_get_filters (GTK_FILE_CHOOSER (self));
n_filters = g_list_model_get_n_items (filters);
filters = gtk_file_chooser_list_filters (GTK_FILE_CHOOSER (self));
n_filters = g_slist_length (filters);
if (n_filters > 0)
{
data->filters = [NSMutableArray arrayWithCapacity:n_filters];
@@ -469,17 +453,13 @@ gtk_file_chooser_native_quartz_show (GtkFileChooserNative *self)
data->filter_names = [NSMutableArray arrayWithCapacity:n_filters];
[data->filter_names retain];
for (i = 0; i < n; i++)
for (l = filters, i = 0; l != NULL; l = l->next, i++)
{
GtkFileFilter *filter = g_list_model_get_item (filters, i);
if (!file_filter_to_quartz (filter, data->filters, data->filter_names))
if (!file_filter_to_quartz (l->data, data->filters, data->filter_names))
{
filechooser_quartz_data_free (data);
g_object_unref (filter);
g_object_unref (filters);
return FALSE;
}
g_object_unref (filter);
}
self->current_filter = gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (self));
}
@@ -487,8 +467,6 @@ gtk_file_chooser_native_quartz_show (GtkFileChooserNative *self)
{
self->current_filter = NULL;
}
g_object_unref (filters);
self->mode_data = data;
data->self = g_object_ref (self);
+18 -45
View File
@@ -66,7 +66,7 @@ typedef struct {
char *cancel_label;
char *title;
GListModel *shortcut_files;
GSList *shortcut_files;
GArray *choices_selections;
GFile *current_folder;
@@ -244,11 +244,9 @@ ifiledialogevents_OnTypeChange (IFileDialogEvents * self,
return S_OK;
}
fileType--; // fileTypeIndex starts at 1
GListModel *filters = gtk_file_chooser_get_filters (GTK_FILE_CHOOSER (events->data->self));
GtkFileFilter *filter = g_list_model_get_item (filters, fileType);
events->data->self->current_filter = filter;
g_object_unref (filter);
g_object_unref (filters);
GSList *filters = gtk_file_chooser_list_filters (GTK_FILE_CHOOSER (events->data->self));
events->data->self->current_filter = g_slist_nth_data (filters, fileType);
g_slist_free (filters);
g_object_notify (G_OBJECT (events->data->self), "filter");
return S_OK;
}
@@ -330,7 +328,7 @@ filechooser_win32_thread_data_free (FilechooserWin32ThreadData *data)
g_array_free (data->choices_selections, TRUE);
data->choices_selections = NULL;
}
g_object_unref (data->shortcut_files);
g_slist_free_full (data->shortcut_files, g_object_unref);
g_slist_free_full (data->files, g_object_unref);
if (data->self)
g_object_unref (data->self);
@@ -465,7 +463,7 @@ filechooser_win32_thread (gpointer _data)
IFileDialog2 *pfd2 = NULL;
DWORD flags;
DWORD cookie;
guint j, n_items;
GSList *l;
CoInitializeEx (NULL, COINIT_APARTMENTTHREADED);
@@ -531,11 +529,9 @@ filechooser_win32_thread (gpointer _data)
g_free (label);
}
n_items = g_list_model_get_n_items (data->shortcut_files);
for (j = 0; j < n_items; j++)
for (l = data->shortcut_files; l != NULL; l = l->next)
{
GFile *file = g_list_model_get_item (data->shortcut_files, j);
IShellItem *item = get_shell_item_for_file (file);
IShellItem *item = get_shell_item_for_file (l->data);
if (item)
{
hr = IFileDialog_AddPlace (pfd, item, FDAP_BOTTOM);
@@ -543,7 +539,6 @@ filechooser_win32_thread (gpointer _data)
g_warning_hr ("Can't add dialog shortcut", hr);
IShellItem_Release (item);
}
g_object_unref (file);
}
if (data->current_file)
@@ -596,23 +591,9 @@ filechooser_win32_thread (gpointer _data)
if (data->self->current_filter)
{
GListModel *filters;
guint current_filter_index = GTK_INVALID_LIST_POSITION;
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);
GSList *filters = gtk_file_chooser_list_filters (GTK_FILE_CHOOSER (data->self));
gint current_filter_index = g_slist_index (filters, data->self->current_filter);
g_slist_free (filters);
if (current_filter_index >= 0)
hr = IFileDialog_SetFileTypeIndex (pfd, current_filter_index + 1);
@@ -636,8 +617,6 @@ filechooser_win32_thread (gpointer _data)
hr = IFileDialog_QueryInterface (pfd, &IID_IFileDialogCustomize, (LPVOID *) &pfdc);
if (SUCCEEDED (hr))
{
GSList *l;
for (l = data->self->choices; l; l = l->next, dialog_control_id++)
{
GtkFileChooserNativeChoice *choice = (GtkFileChooserNativeChoice*) l->data;
@@ -763,8 +742,6 @@ filechooser_win32_thread (gpointer _data)
hr = IFileDialog_QueryInterface (pfd, &IID_IFileDialogCustomize, (LPVOID *) &pfdc);
if (SUCCEEDED (hr))
{
GSList *l;
for (l = data->self->choices; l; l = l->next)
{
GtkFileChooserNativeChoice *choice = (GtkFileChooserNativeChoice*) l->data;
@@ -887,24 +864,21 @@ gtk_file_chooser_native_win32_show (GtkFileChooserNative *self)
FilechooserWin32ThreadData *data;
GtkWindow *transient_for;
GtkFileChooserAction action;
GListModel *filters;
guint n_filters, i;
GSList *filters, *l;
int n_filters, i;
data = g_new0 (FilechooserWin32ThreadData, 1);
filters = gtk_file_chooser_get_filters (GTK_FILE_CHOOSER (self));
n_filters = g_list_model_get_n_items (filters);
filters = gtk_file_chooser_list_filters (GTK_FILE_CHOOSER (self));
n_filters = g_slist_length (filters);
if (n_filters > 0)
{
data->filters = g_new0 (COMDLG_FILTERSPEC, n_filters + 1);
for (i = 0; i < n_filters; i++)
for (l = filters, i = 0; l != NULL; l = l->next, i++)
{
GtkFileFilter *filter = g_list_model_get_item (filters, i);
if (!file_filter_to_win32 (filter, &data->filters[i]))
if (!file_filter_to_win32 (l->data, &data->filters[i]))
{
g_object_unref (filter);
g_object_unref (filters);
filechooser_win32_thread_data_free (data);
return FALSE;
}
@@ -915,13 +889,12 @@ gtk_file_chooser_native_win32_show (GtkFileChooserNative *self)
{
self->current_filter = NULL;
}
g_object_unref (filters);
self->mode_data = data;
data->self = g_object_ref (self);
data->shortcut_files =
gtk_file_chooser_get_shortcut_folders (GTK_FILE_CHOOSER (self->dialog));
gtk_file_chooser_list_shortcut_folders (GTK_FILE_CHOOSER (self->dialog));
data->accept_label = translate_mnemonics (self->accept_label);
data->cancel_label = translate_mnemonics (self->cancel_label);
+25 -25
View File
@@ -58,34 +58,34 @@ struct _GtkFileChooserIface
/* Methods
*/
gboolean (*set_current_folder) (GtkFileChooser *chooser,
GFile *file,
GError **error);
GFile * (*get_current_folder) (GtkFileChooser *chooser);
void (*set_current_name) (GtkFileChooser *chooser,
const gchar *name);
gboolean (*set_current_folder) (GtkFileChooser *chooser,
GFile *file,
GError **error);
GFile * (*get_current_folder) (GtkFileChooser *chooser);
void (*set_current_name) (GtkFileChooser *chooser,
const gchar *name);
gchar * (*get_current_name) (GtkFileChooser *chooser);
gboolean (*select_file) (GtkFileChooser *chooser,
GFile *file,
GError **error);
void (*unselect_file) (GtkFileChooser *chooser,
GFile *file);
void (*select_all) (GtkFileChooser *chooser);
void (*unselect_all) (GtkFileChooser *chooser);
GSList * (*get_files) (GtkFileChooser *chooser);
GtkFileSystem *(*get_file_system) (GtkFileChooser *chooser);
void (*add_filter) (GtkFileChooser *chooser,
GtkFileFilter *filter);
void (*remove_filter) (GtkFileChooser *chooser,
GtkFileFilter *filter);
GListModel * (*get_filters) (GtkFileChooser *chooser);
gboolean (*select_file) (GtkFileChooser *chooser,
GFile *file,
GError **error);
void (*unselect_file) (GtkFileChooser *chooser,
GFile *file);
void (*select_all) (GtkFileChooser *chooser);
void (*unselect_all) (GtkFileChooser *chooser);
GSList * (*get_files) (GtkFileChooser *chooser);
GtkFileSystem *(*get_file_system) (GtkFileChooser *chooser);
void (*add_filter) (GtkFileChooser *chooser,
GtkFileFilter *filter);
void (*remove_filter) (GtkFileChooser *chooser,
GtkFileFilter *filter);
GSList * (*list_filters) (GtkFileChooser *chooser);
gboolean (*add_shortcut_folder) (GtkFileChooser *chooser,
GFile *file,
GError **error);
GFile *file,
GError **error);
gboolean (*remove_shortcut_folder) (GtkFileChooser *chooser,
GFile *file,
GError **error);
GListModel * (*get_shortcut_folders) (GtkFileChooser *chooser);
GFile *file,
GError **error);
GSList * (*list_shortcut_folders) (GtkFileChooser *chooser);
/* Signals
*/
+18 -24
View File
@@ -45,14 +45,14 @@ static void delegate_add_filter (GtkFileChooser *choose
GtkFileFilter *filter);
static void delegate_remove_filter (GtkFileChooser *chooser,
GtkFileFilter *filter);
static GListModel * delegate_get_filters (GtkFileChooser *chooser);
static GSList * delegate_list_filters (GtkFileChooser *chooser);
static gboolean delegate_add_shortcut_folder (GtkFileChooser *chooser,
GFile *file,
GError **error);
static gboolean delegate_remove_shortcut_folder (GtkFileChooser *chooser,
GFile *file,
GError **error);
static GListModel * delegate_get_shortcut_folders (GtkFileChooser *chooser);
static GSList * delegate_list_shortcut_folders (GtkFileChooser *chooser);
static void delegate_notify (GObject *object,
GParamSpec *pspec,
gpointer data);
@@ -92,23 +92,17 @@ void
_gtk_file_chooser_install_properties (GObjectClass *klass)
{
g_object_class_override_property (klass,
GTK_FILE_CHOOSER_PROP_ACTION,
"action");
GTK_FILE_CHOOSER_PROP_ACTION,
"action");
g_object_class_override_property (klass,
GTK_FILE_CHOOSER_PROP_FILTER,
"filter");
GTK_FILE_CHOOSER_PROP_FILTER,
"filter");
g_object_class_override_property (klass,
GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE,
"select-multiple");
GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE,
"select-multiple");
g_object_class_override_property (klass,
GTK_FILE_CHOOSER_PROP_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");
GTK_FILE_CHOOSER_PROP_CREATE_FOLDERS,
"create-folders");
}
/**
@@ -137,10 +131,10 @@ _gtk_file_chooser_delegate_iface_init (GtkFileChooserIface *iface)
iface->get_file_system = delegate_get_file_system;
iface->add_filter = delegate_add_filter;
iface->remove_filter = delegate_remove_filter;
iface->get_filters = delegate_get_filters;
iface->list_filters = delegate_list_filters;
iface->add_shortcut_folder = delegate_add_shortcut_folder;
iface->remove_shortcut_folder = delegate_remove_shortcut_folder;
iface->get_shortcut_folders = delegate_get_shortcut_folders;
iface->list_shortcut_folders = delegate_list_shortcut_folders;
iface->add_choice = delegate_add_choice;
iface->remove_choice = delegate_remove_choice;
iface->set_choice = delegate_set_choice;
@@ -247,10 +241,10 @@ delegate_remove_filter (GtkFileChooser *chooser,
gtk_file_chooser_remove_filter (get_delegate (chooser), filter);
}
static GListModel *
delegate_get_filters (GtkFileChooser *chooser)
static GSList *
delegate_list_filters (GtkFileChooser *chooser)
{
return gtk_file_chooser_get_filters (get_delegate (chooser));
return gtk_file_chooser_list_filters (get_delegate (chooser));
}
static gboolean
@@ -269,10 +263,10 @@ delegate_remove_shortcut_folder (GtkFileChooser *chooser,
return gtk_file_chooser_remove_shortcut_folder (get_delegate (chooser), file, error);
}
static GListModel *
delegate_get_shortcut_folders (GtkFileChooser *chooser)
static GSList *
delegate_list_shortcut_folders (GtkFileChooser *chooser)
{
return gtk_file_chooser_get_shortcut_folders (get_delegate (chooser));
return gtk_file_chooser_list_shortcut_folders (get_delegate (chooser));
}
static gboolean
+1 -3
View File
@@ -32,9 +32,7 @@ typedef enum {
GTK_FILE_CHOOSER_PROP_FILTER,
GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE,
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
GTK_FILE_CHOOSER_PROP_LAST = GTK_FILE_CHOOSER_PROP_CREATE_FOLDERS
} GtkFileChooserProp;
void _gtk_file_chooser_install_properties (GObjectClass *klass);
+28 -39
View File
@@ -485,14 +485,14 @@ static void gtk_file_chooser_widget_add_filter (GtkF
GtkFileFilter *filter);
static void gtk_file_chooser_widget_remove_filter (GtkFileChooser *chooser,
GtkFileFilter *filter);
static GListModel * gtk_file_chooser_widget_get_filters (GtkFileChooser *chooser);
static GSList * gtk_file_chooser_widget_list_filters (GtkFileChooser *chooser);
static gboolean gtk_file_chooser_widget_add_shortcut_folder (GtkFileChooser *chooser,
GFile *file,
GError **error);
static gboolean gtk_file_chooser_widget_remove_shortcut_folder (GtkFileChooser *chooser,
GFile *file,
GError **error);
static GListModel * gtk_file_chooser_widget_get_shortcut_folders (GtkFileChooser *chooser);
static GSList * gtk_file_chooser_widget_list_shortcut_folders (GtkFileChooser *chooser);
static gboolean gtk_file_chooser_widget_should_respond (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->add_filter = gtk_file_chooser_widget_add_filter;
iface->remove_filter = gtk_file_chooser_widget_remove_filter;
iface->get_filters = gtk_file_chooser_widget_get_filters;
iface->list_filters = gtk_file_chooser_widget_list_filters;
iface->add_shortcut_folder = gtk_file_chooser_widget_add_shortcut_folder;
iface->remove_shortcut_folder = gtk_file_chooser_widget_remove_shortcut_folder;
iface->get_shortcut_folders = gtk_file_chooser_widget_get_shortcut_folders;
iface->list_shortcut_folders = gtk_file_chooser_widget_list_shortcut_folders;
iface->add_choice = gtk_file_chooser_widget_add_choice;
iface->remove_choice = gtk_file_chooser_widget_remove_choice;
iface->set_choice = gtk_file_chooser_widget_set_choice;
@@ -3072,14 +3072,6 @@ gtk_file_chooser_widget_get_property (GObject *object,
g_value_set_boolean (value, impl->create_folders);
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:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -3437,27 +3429,25 @@ set_startup_mode (GtkFileChooserWidget *impl)
static gboolean
shortcut_exists (GtkFileChooserWidget *impl, GFile *needle)
{
GListModel *haystack;
guint n, i;
GSList *haystack;
GSList *l;
gboolean exists;
exists = FALSE;
haystack = gtk_places_sidebar_get_shortcuts (GTK_PLACES_SIDEBAR (impl->places_sidebar));
n = g_list_model_get_n_items (haystack);
for (i = 0; i < n; i++)
haystack = gtk_places_sidebar_list_shortcuts (GTK_PLACES_SIDEBAR (impl->places_sidebar));
for (l = haystack; l; l = l->next)
{
GFile *hay = g_list_model_get_item (haystack, i);
GFile *hay;
hay = G_FILE (l->data);
if (g_file_equal (hay, needle))
{
g_object_unref (hay);
exists = TRUE;
break;
}
g_object_unref (hay);
}
g_object_unref (haystack);
g_slist_free_full (haystack, g_object_unref);
return exists;
}
@@ -5574,8 +5564,6 @@ gtk_file_chooser_widget_add_filter (GtkFileChooser *chooser,
set_current_filter (impl, filter);
show_filters (impl, TRUE);
g_object_notify (G_OBJECT (chooser), "filters");
}
static void
@@ -5609,16 +5597,25 @@ gtk_file_chooser_widget_remove_filter (GtkFileChooser *chooser,
if (!impl->filters)
show_filters (impl, FALSE);
g_object_notify (G_OBJECT (chooser), "filters");
}
static GListModel *
gtk_file_chooser_widget_get_filters (GtkFileChooser *chooser)
static GSList *
gtk_file_chooser_widget_list_filters (GtkFileChooser *chooser)
{
GtkFileChooserWidget *impl = GTK_FILE_CHOOSER_WIDGET (chooser);
GSList *filters;
guint i;
return G_LIST_MODEL (g_object_ref (impl->filters));
filters = NULL;
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
@@ -5629,9 +5626,6 @@ gtk_file_chooser_widget_add_shortcut_folder (GtkFileChooser *chooser,
GtkFileChooserWidget *impl = GTK_FILE_CHOOSER_WIDGET (chooser);
gtk_places_sidebar_add_shortcut (GTK_PLACES_SIDEBAR (impl->places_sidebar), file);
g_object_notify (G_OBJECT (chooser), "shortcut-folders");
return TRUE;
}
@@ -5643,18 +5637,15 @@ gtk_file_chooser_widget_remove_shortcut_folder (GtkFileChooser *chooser,
GtkFileChooserWidget *impl = GTK_FILE_CHOOSER_WIDGET (chooser);
gtk_places_sidebar_remove_shortcut (GTK_PLACES_SIDEBAR (impl->places_sidebar), file);
g_object_notify (G_OBJECT (chooser), "shortcut-folders");
return TRUE;
}
static GListModel *
gtk_file_chooser_widget_get_shortcut_folders (GtkFileChooser *chooser)
static GSList *
gtk_file_chooser_widget_list_shortcut_folders (GtkFileChooser *chooser)
{
GtkFileChooserWidget *impl = GTK_FILE_CHOOSER_WIDGET (chooser);
return gtk_places_sidebar_get_shortcuts (GTK_PLACES_SIDEBAR (impl->places_sidebar));
return gtk_places_sidebar_list_shortcuts (GTK_PLACES_SIDEBAR (impl->places_sidebar));
}
struct switch_folder_closure {
@@ -6942,8 +6933,6 @@ filter_combo_changed (GtkDropDown *dropdown,
new_filter = gtk_drop_down_get_selected_item (dropdown);
set_current_filter (impl, new_filter);
if (impl->location_entry != NULL)
_gtk_file_chooser_entry_set_file_filter (GTK_FILE_CHOOSER_ENTRY (impl->location_entry),
new_filter);
+451 -326
View File
File diff suppressed because it is too large Load Diff
+78 -13
View File
@@ -33,34 +33,99 @@ G_BEGIN_DECLS
#define GTK_IS_FILE_FILTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_FILE_FILTER))
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
GType gtk_file_filter_get_type (void) G_GNUC_CONST;
GType gtk_file_filter_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_ALL
GtkFileFilter * gtk_file_filter_new (void);
GtkFileFilter * gtk_file_filter_new (void);
GDK_AVAILABLE_IN_ALL
void gtk_file_filter_set_name (GtkFileFilter *filter,
const char *name);
void gtk_file_filter_set_name (GtkFileFilter *filter,
const gchar *name);
GDK_AVAILABLE_IN_ALL
const char * gtk_file_filter_get_name (GtkFileFilter *filter);
const gchar * gtk_file_filter_get_name (GtkFileFilter *filter);
GDK_AVAILABLE_IN_ALL
void gtk_file_filter_add_mime_type (GtkFileFilter *filter,
const char *mime_type);
void gtk_file_filter_add_mime_type (GtkFileFilter *filter,
const gchar *mime_type);
GDK_AVAILABLE_IN_ALL
void gtk_file_filter_add_pattern (GtkFileFilter *filter,
const char *pattern);
void gtk_file_filter_add_pattern (GtkFileFilter *filter,
const gchar *pattern);
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
const char ** gtk_file_filter_get_attributes (GtkFileFilter *filter);
GtkFileFilterFlags gtk_file_filter_get_needed (GtkFileFilter *filter);
GDK_AVAILABLE_IN_ALL
gboolean gtk_file_filter_filter (GtkFileFilter *filter,
const GtkFileFilterInfo *filter_info);
GDK_AVAILABLE_IN_ALL
GVariant * gtk_file_filter_to_gvariant (GtkFileFilter *filter);
GVariant *gtk_file_filter_to_gvariant (GtkFileFilter *filter);
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
+56 -4
View File
@@ -29,7 +29,6 @@
#include "gtktreedatalist.h"
#include "gtktreednd.h"
#include "gtktreemodel.h"
#include "gtkfilter.h"
/*** Structure: how GtkFileSystemModel works
*
@@ -376,6 +375,12 @@ static gboolean
node_should_be_filtered_out (GtkFileSystemModel *model, guint 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)
return TRUE;
@@ -383,10 +388,57 @@ node_should_be_filtered_out (GtkFileSystemModel *model, guint id)
if (model->filter == NULL)
return FALSE;
if (!g_file_info_has_attribute (node->info, "standard::file"))
g_file_info_set_attribute_object (node->info, "standard::file", G_OBJECT (node->file));
/* fill info */
required = gtk_file_filter_get_needed (model->filter);
return !gtk_filter_match (GTK_FILTER (model->filter), node->info);
filter_info.contains = GTK_FILE_FILTER_DISPLAY_NAME;
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
+391 -328
View File
@@ -21,7 +21,7 @@
#include "gtkfilterlistmodel.h"
#include "gtkbitset.h"
#include "gtkrbtreeprivate.h"
#include "gtkintl.h"
#include "gtkprivate.h"
@@ -35,33 +35,40 @@
* listmodel.
* It hides some elements from the other model according to
* 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 {
PROP_0,
PROP_FILTER,
PROP_INCREMENTAL,
PROP_ITEM_TYPE,
PROP_MODEL,
PROP_PENDING,
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
{
GObject parent_instance;
GType item_type;
GListModel *model;
GtkFilter *filter;
GtkFilterMatch strictness;
gboolean incremental;
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 */
GtkRbTree *items; /* NULL if strictness != GTK_FILTER_MATCH_SOME */
};
struct _GtkFilterListModelClass
@@ -71,16 +78,133 @@ struct _GtkFilterListModelClass
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
gtk_filter_list_model_get_item_type (GListModel *list)
{
return G_TYPE_OBJECT;
GtkFilterListModel *self = GTK_FILTER_LIST_MODEL (list);
return self->item_type;
}
static guint
gtk_filter_list_model_get_n_items (GListModel *list)
{
GtkFilterListModel *self = GTK_FILTER_LIST_MODEL (list);
FilterAugment *aug;
FilterNode *node;
switch (self->strictness)
{
@@ -91,12 +215,18 @@ gtk_filter_list_model_get_n_items (GListModel *list)
return g_list_model_get_n_items (self->model);
case GTK_FILTER_MATCH_SOME:
return gtk_bitset_get_size (self->matches);
break;
default:
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
@@ -116,9 +246,7 @@ gtk_filter_list_model_get_item (GListModel *list,
break;
case GTK_FILTER_MATCH_SOME:
unfiltered = gtk_bitset_get_nth (self->matches, position);
if (unfiltered == 0 && position >= gtk_bitset_get_size (self->matches))
return NULL;
gtk_filter_list_model_get_nth_filtered (self->items, position, &unfiltered);
break;
default:
@@ -140,8 +268,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))
static gboolean
gtk_filter_list_model_run_filter_on_item (GtkFilterListModel *self,
guint position)
gtk_filter_list_model_run_filter (GtkFilterListModel *self,
guint position)
{
gpointer item;
gboolean visible;
@@ -156,120 +284,26 @@ gtk_filter_list_model_run_filter_on_item (GtkFilterListModel *self,
return visible;
}
static void
gtk_filter_list_model_run_filter (GtkFilterListModel *self,
guint n_steps)
static guint
gtk_filter_list_model_add_items (GtkFilterListModel *self,
FilterNode *after,
guint position,
guint n_items)
{
GtkBitsetIter iter;
guint i, pos;
gboolean more;
FilterNode *node;
guint i, n_visible;
g_return_if_fail (GTK_IS_FILTER_LIST_MODEL (self));
n_visible = 0;
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))
for (i = 0; i < n_items; i++)
{
if (gtk_filter_list_model_run_filter_on_item (self, pos))
gtk_bitset_add (self->matches, pos);
node = gtk_rb_tree_insert_before (self->items, after);
node->visible = gtk_filter_list_model_run_filter (self, position + i);
if (node->visible)
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");
return n_visible;
}
static void
@@ -279,7 +313,8 @@ gtk_filter_list_model_items_changed_cb (GListModel *model,
guint added,
GtkFilterListModel *self)
{
guint filter_removed, filter_added;
FilterNode *node;
guint i, filter_position, filter_removed, filter_added;
switch (self->strictness)
{
@@ -297,27 +332,22 @@ gtk_filter_list_model_items_changed_cb (GListModel *model,
g_assert_not_reached ();
}
if (removed > 0)
filter_removed = gtk_bitset_get_size_in_range (self->matches, position, position + removed - 1);
else
filter_removed = 0;
node = gtk_filter_list_model_get_nth (self->items, position, &filter_position);
gtk_bitset_splice (self->matches, position, removed, added);
if (self->pending)
gtk_bitset_splice (self->pending, position, removed, added);
if (added > 0)
filter_removed = 0;
for (i = 0; i < removed; i++)
{
gtk_filter_list_model_start_filtering (self, gtk_bitset_new_range (position, added));
filter_added = gtk_bitset_get_size_in_range (self->matches, position, position + added - 1);
FilterNode *next = gtk_rb_tree_node_get_next (node);
if (node->visible)
filter_removed++;
gtk_rb_tree_remove (self->items, node);
node = next;
}
else
filter_added = 0;
filter_added = gtk_filter_list_model_add_items (self, node, position, added);
if (filter_removed > 0 || filter_added > 0)
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);
g_list_model_items_changed (G_LIST_MODEL (self), filter_position, filter_removed, filter_added);
}
static void
@@ -334,8 +364,8 @@ gtk_filter_list_model_set_property (GObject *object,
gtk_filter_list_model_set_filter (self, g_value_get_object (value));
break;
case PROP_INCREMENTAL:
gtk_filter_list_model_set_incremental (self, g_value_get_boolean (value));
case PROP_ITEM_TYPE:
self->item_type = g_value_get_gtype (value);
break;
case PROP_MODEL:
@@ -362,18 +392,14 @@ gtk_filter_list_model_get_property (GObject *object,
g_value_set_object (value, self->filter);
break;
case PROP_INCREMENTAL:
g_value_set_boolean (value, self->incremental);
case PROP_ITEM_TYPE:
g_value_set_gtype (value, self->item_type);
break;
case PROP_MODEL:
g_value_set_object (value, self->model);
break;
case PROP_PENDING:
g_value_set_uint (value, gtk_filter_list_model_get_pending (self));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -386,16 +412,109 @@ gtk_filter_list_model_clear_model (GtkFilterListModel *self)
if (self->model == NULL)
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_clear_object (&self->model);
if (self->matches)
gtk_bitset_remove_all (self->matches);
if (self->items)
gtk_rb_tree_remove_all (self->items);
}
/*<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
gtk_filter_list_model_refilter (GtkFilterListModel *self,
GtkFilterChange change)
gtk_filter_list_model_refilter (GtkFilterListModel *self);
static void
gtk_filter_list_model_update_strictness_and_refilter (GtkFilterListModel *self)
{
GtkFilterMatch new_strictness;
@@ -413,9 +532,8 @@ gtk_filter_list_model_refilter (GtkFilterListModel *self,
case GTK_FILTER_MATCH_NONE:
{
guint n_before = 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);
self->strictness = new_strictness;
gtk_filter_list_model_stop_filtering (self);
if (n_before > 0)
g_list_model_items_changed (G_LIST_MODEL (self), 0, n_before, 0);
}
@@ -435,35 +553,16 @@ gtk_filter_list_model_refilter (GtkFilterListModel *self,
case GTK_FILTER_MATCH_SOME:
{
guint start, end, n_before, n_after;
gtk_filter_list_model_stop_filtering (self);
self->strictness = new_strictness;
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)
if (gtk_filter_list_model_find_filtered (self, &start, &end, &n_before))
{
g_clear_pointer (&self->matches, gtk_bitset_unref);
n_after = g_list_model_get_n_items (G_LIST_MODEL (self));
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
{
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);
g_clear_pointer (&self->items, gtk_rb_tree_unref);
}
}
break;
@@ -475,44 +574,40 @@ gtk_filter_list_model_refilter (GtkFilterListModel *self,
break;
case GTK_FILTER_MATCH_SOME:
{
GtkBitset *old, *pending;
if (self->matches == NULL)
switch (self->strictness)
{
case GTK_FILTER_MATCH_NONE:
{
if (self->strictness == GTK_FILTER_MATCH_ALL)
old = gtk_bitset_new_range (0, g_list_model_get_n_items (self->model));
else
old = gtk_bitset_new_empty ();
guint n_after;
self->strictness = new_strictness;
self->items = gtk_rb_tree_new (FilterNode,
FilterAugment,
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);
}
else
break;
case GTK_FILTER_MATCH_ALL:
{
old = self->matches;
guint start, end, n_before, n_after;
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);
}
self->strictness = new_strictness;
switch (change)
{
default:
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);
}
break;
default:
case GTK_FILTER_MATCH_SOME:
gtk_filter_list_model_refilter (self);
break;
}
}
}
@@ -521,7 +616,7 @@ gtk_filter_list_model_filter_changed_cb (GtkFilter *filter,
GtkFilterChange change,
GtkFilterListModel *self)
{
gtk_filter_list_model_refilter (self, change);
gtk_filter_list_model_update_strictness_and_refilter (self);
}
static void
@@ -541,7 +636,7 @@ gtk_filter_list_model_dispose (GObject *object)
gtk_filter_list_model_clear_model (self);
gtk_filter_list_model_clear_filter (self);
g_clear_pointer (&self->matches, gtk_bitset_unref);
g_clear_pointer (&self->items, gtk_rb_tree_unref);
G_OBJECT_CLASS (gtk_filter_list_model_parent_class)->dispose (object);
}
@@ -568,16 +663,16 @@ gtk_filter_list_model_class_init (GtkFilterListModelClass *class)
GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkFilterListModel:incremental:
* GtkFilterListModel:item-type:
*
* If the model should filter items incrementally
* The #GType for elements of this object
*/
properties[PROP_INCREMENTAL] =
g_param_spec_boolean ("incremental",
P_("Incremental"),
P_("Filer items incrementally"),
FALSE,
GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
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);
/**
* GtkFilterListModel:model:
@@ -591,18 +686,6 @@ gtk_filter_list_model_class_init (GtkFilterListModelClass *class)
G_TYPE_LIST_MODEL,
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);
}
@@ -614,7 +697,7 @@ gtk_filter_list_model_init (GtkFilterListModel *self)
/**
* gtk_filter_list_model_new:
* @model: (allow-none): the model to sort
* @model: the model to sort
* @filter: (allow-none): filter or %NULL to not filter items
*
* Creates a new #GtkFilterListModel that will filter @model using the given
@@ -628,10 +711,10 @@ gtk_filter_list_model_new (GListModel *model,
{
GtkFilterListModel *result;
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);
g_return_val_if_fail (G_IS_LIST_MODEL (model), NULL);
result = g_object_new (GTK_TYPE_FILTER_LIST_MODEL,
"item-type", g_list_model_get_item_type (model),
"model", model,
"filter", filter,
NULL);
@@ -639,6 +722,26 @@ gtk_filter_list_model_new (GListModel *model,
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:
* @self: a #GtkFilterListModel
@@ -666,7 +769,7 @@ gtk_filter_list_model_set_filter (GtkFilterListModel *self,
}
else
{
gtk_filter_list_model_refilter (self, GTK_FILTER_CHANGE_LESS_STRICT);
gtk_filter_list_model_update_strictness_and_refilter (self);
}
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FILTER]);
@@ -725,18 +828,13 @@ gtk_filter_list_model_set_model (GtkFilterListModel *self,
if (removed == 0)
{
self->strictness = GTK_FILTER_MATCH_NONE;
gtk_filter_list_model_refilter (self, GTK_FILTER_CHANGE_LESS_STRICT);
gtk_filter_list_model_update_strictness_and_refilter (self);
added = 0;
}
else if (self->matches)
{
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 if (self->items)
added = gtk_filter_list_model_add_items (self, NULL, 0, g_list_model_get_n_items (model));
else
{
added = g_list_model_get_n_items (model);
}
added = g_list_model_get_n_items (model);
}
else
{
@@ -766,89 +864,54 @@ gtk_filter_list_model_get_model (GtkFilterListModel *self)
return self->model;
}
/**
* 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)
static void
gtk_filter_list_model_refilter (GtkFilterListModel *self)
{
g_return_if_fail (GTK_IS_FILTER_LIST_MODEL (self));
FilterNode *node;
guint i, first_change, last_change;
guint n_is_visible, n_was_visible;
gboolean visible;
if (self->incremental == incremental)
g_return_if_fail (GTK_IS_FILTER_LIST_MODEL (self));
if (self->items == NULL || self->model == NULL)
return;
self->incremental = incremental;
if (!incremental)
first_change = G_MAXUINT;
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))
{
GtkBitset *old;
gtk_filter_list_model_run_filter (self, G_MAXUINT);
visible = gtk_filter_list_model_run_filter (self, i);
if (visible == node->visible)
{
if (visible)
{
n_is_visible++;
n_was_visible++;
}
continue;
}
old = gtk_bitset_copy (self->matches);
gtk_filter_list_model_run_filter (self, 512);
gtk_filter_list_model_stop_filtering (self);
gtk_filter_list_model_emit_items_changed_for_changes (self, old);
node->visible = visible;
gtk_rb_tree_node_mark_dirty (node);
first_change = MIN (n_is_visible, first_change);
if (visible)
n_is_visible++;
else
n_was_visible++;
last_change = MAX (n_is_visible, last_change);
}
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_INCREMENTAL]);
if (first_change <= last_change)
{
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);
}
+2 -8
View File
@@ -39,6 +39,8 @@ G_DECLARE_FINAL_TYPE (GtkFilterListModel, gtk_filter_list_model, GTK, FILTER_LIS
GDK_AVAILABLE_IN_ALL
GtkFilterListModel * gtk_filter_list_model_new (GListModel *model,
GtkFilter *filter);
GDK_AVAILABLE_IN_ALL
GtkFilterListModel * gtk_filter_list_model_new_for_type (GType item_type);
GDK_AVAILABLE_IN_ALL
void gtk_filter_list_model_set_filter (GtkFilterListModel *self,
@@ -50,14 +52,6 @@ void gtk_filter_list_model_set_model (GtkFilterListMo
GListModel *model);
GDK_AVAILABLE_IN_ALL
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
+41 -5
View File
@@ -40,6 +40,7 @@
enum {
PROP_0,
PROP_ITEM_TYPE,
PROP_MODEL,
NUM_PROPERTIES
};
@@ -63,6 +64,7 @@ struct _GtkFlattenListModel
{
GObject parent_instance;
GType item_type;
GListModel *model;
GtkRbTree *items; /* NULL if model == NULL */
};
@@ -155,7 +157,9 @@ gtk_flatten_list_model_get_nth_model (GtkRbTree *tree,
static GType
gtk_flatten_list_model_get_item_type (GListModel *list)
{
return G_TYPE_OBJECT;
GtkFlattenListModel *self = GTK_FLATTEN_LIST_MODEL (list);
return self->item_type;
}
static guint
@@ -295,6 +299,7 @@ gtk_flatten_list_model_add_items (GtkFlattenListModel *self,
{
node = gtk_rb_tree_insert_before (self->items, after);
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,
"items-changed",
G_CALLBACK (gtk_flatten_list_model_items_changed_cb),
@@ -316,6 +321,10 @@ gtk_flatten_list_model_set_property (GObject *object,
switch (prop_id)
{
case PROP_ITEM_TYPE:
self->item_type = g_value_get_gtype (value);
break;
case PROP_MODEL:
gtk_flatten_list_model_set_model (self, g_value_get_object (value));
break;
@@ -336,6 +345,10 @@ gtk_flatten_list_model_get_property (GObject *object,
switch (prop_id)
{
case PROP_ITEM_TYPE:
g_value_set_gtype (value, self->item_type);
break;
case PROP_MODEL:
g_value_set_object (value, self->model);
break;
@@ -403,6 +416,18 @@ gtk_flatten_list_model_class_init (GtkFlattenListModelClass *class)
gobject_class->get_property = gtk_flatten_list_model_get_property;
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:
*
@@ -425,20 +450,26 @@ gtk_flatten_list_model_init (GtkFlattenListModel *self)
/**
* gtk_flatten_list_model_new:
* @model: (nullable) (transfer none): the model to be flattened
* @item_type: The type of items in the to-be-flattened models
* @model: (nullable) (transfer none): the item to be flattened
*
* Creates a new #GtkFlattenListModel that flattens @list.
* Creates a new #GtkFlattenListModel that flattens @list. The
* models returned by @model must conform to the given @item_type,
* either by having an identical type or a subtype.
*
* Returns: a new #GtkFlattenListModel
**/
GtkFlattenListModel *
gtk_flatten_list_model_new (GListModel *model)
gtk_flatten_list_model_new (GType item_type,
GListModel *model)
{
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);
result = g_object_new (GTK_TYPE_FLATTEN_LIST_MODEL,
"item-type", item_type,
"model", model,
NULL);
@@ -450,7 +481,8 @@ gtk_flatten_list_model_new (GListModel *model)
* @self: a #GtkFlattenListModel
* @model: (nullable) (transfer none): the new model or %NULL
*
* Sets a new model to be flattened.
* Sets a new model to be flattened. The model must contain items of
* #GListModel that conform to the item type of @self.
**/
void
gtk_flatten_list_model_set_model (GtkFlattenListModel *self,
@@ -460,6 +492,10 @@ gtk_flatten_list_model_set_model (GtkFlattenListModel *self,
g_return_if_fail (GTK_IS_FLATTEN_LIST_MODEL (self));
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)
return;
+2 -1
View File
@@ -36,7 +36,8 @@ GDK_AVAILABLE_IN_ALL
G_DECLARE_FINAL_TYPE (GtkFlattenListModel, gtk_flatten_list_model, GTK, FLATTEN_LIST_MODEL, GObject)
GDK_AVAILABLE_IN_ALL
GtkFlattenListModel * gtk_flatten_list_model_new (GListModel *model);
GtkFlattenListModel * gtk_flatten_list_model_new (GType item_type,
GListModel *model);
GDK_AVAILABLE_IN_ALL
void gtk_flatten_list_model_set_model (GtkFlattenListModel *self,
+1 -1
View File
@@ -784,7 +784,7 @@ update_fontlist (GtkFontChooserWidget *self)
if ((self->level & GTK_FONT_CHOOSER_LEVEL_STYLE) == 0)
model = g_object_ref (G_LIST_MODEL (fontmap));
else
model = G_LIST_MODEL (gtk_flatten_list_model_new (G_LIST_MODEL (fontmap)));
model = G_LIST_MODEL (gtk_flatten_list_model_new (PANGO_TYPE_FONT_FACE, G_LIST_MODEL (fontmap)));
gtk_filter_list_model_set_model (self->filter_model, model);
g_object_unref (model);
}
+25 -30
View File
@@ -55,14 +55,6 @@
#include "gdk/gdktextureprivate.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
* @Short_description: Looking up icons by name
@@ -2284,13 +2276,13 @@ real_choose_icon (GtkIconTheme *self,
}
static void
icon_name_list_add_icon (GtkStrvBuilder *icons,
const gchar *dir_suffix,
gchar *icon_name)
icon_name_list_add_icon (GPtrArray *icons,
const gchar *dir_suffix,
gchar *icon_name)
{
if (dir_suffix)
gtk_strv_builder_append (icons, g_strconcat (icon_name, dir_suffix, NULL));
gtk_strv_builder_append (icons, icon_name);
g_ptr_array_add (icons, g_strconcat (icon_name, dir_suffix, NULL));
g_ptr_array_add (icons, icon_name);
}
static GtkIconPaintable *
@@ -2304,7 +2296,7 @@ choose_icon (GtkIconTheme *self,
{
gboolean has_regular = FALSE, has_symbolic = FALSE;
GtkIconPaintable *icon;
GtkStrvBuilder new_names;
GPtrArray *new_names;
const gchar *dir_suffix;
guint i;
@@ -2335,70 +2327,73 @@ choose_icon (GtkIconTheme *self,
if ((flags & GTK_ICON_LOOKUP_FORCE_REGULAR) && has_symbolic)
{
gtk_strv_builder_init (&new_names);
new_names = g_ptr_array_new_with_free_func (g_free);
for (i = 0; icon_names[i]; i++)
{
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
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++)
{
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,
(const char **) gtk_strv_builder_get_data (&new_names),
(const gchar **) new_names->pdata,
size,
scale,
flags & ~(GTK_ICON_LOOKUP_FORCE_REGULAR | GTK_ICON_LOOKUP_FORCE_SYMBOLIC),
non_blocking);
gtk_strv_builder_clear (&new_names);
g_ptr_array_free (new_names, TRUE);
}
else if ((flags & GTK_ICON_LOOKUP_FORCE_SYMBOLIC) && has_regular)
{
gtk_strv_builder_init (&new_names);
new_names = g_ptr_array_new_with_free_func (g_free);
for (i = 0; icon_names[i]; i++)
{
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
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++)
{
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,
(const char **) gtk_strv_builder_get_data (&new_names),
(const gchar **) new_names->pdata,
size,
scale,
flags & ~(GTK_ICON_LOOKUP_FORCE_REGULAR | GTK_ICON_LOOKUP_FORCE_SYMBOLIC),
non_blocking);
gtk_strv_builder_clear (&new_names);
g_ptr_array_free (new_names, TRUE);
}
else if (dir_suffix)
{
gtk_strv_builder_init (&new_names);
new_names = g_ptr_array_new_with_free_func (g_free);
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,
(const char **) gtk_strv_builder_get_data (&new_names),
(const gchar **) new_names->pdata,
size,
scale,
flags & ~(GTK_ICON_LOOKUP_FORCE_REGULAR | GTK_ICON_LOOKUP_FORCE_SYMBOLIC),
non_blocking);
gtk_strv_builder_clear (&new_names);
g_ptr_array_free (new_names, TRUE);
}
else
{
+20 -24
View File
@@ -95,6 +95,7 @@
#include "gdk/gdk-private.h"
#include "gsk/gskprivate.h"
#include "gsk/gskrendernodeprivate.h"
#include "gtkarrayimplprivate.h"
#include "gtknative.h"
#include <locale.h>
@@ -137,13 +138,6 @@
#include "a11y/gtkaccessibility.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 gint pre_initialized = FALSE;
@@ -1327,7 +1321,8 @@ gtk_synthesize_crossing_events (GtkRoot *toplevel,
double x, y;
GtkWidget *prev;
gboolean seen_ancestor;
GtkWidgetStack target_array;
GtkArray target_array;
GtkWidget *stack_targets[16];
int i;
if (old_target == new_target)
@@ -1381,19 +1376,19 @@ gtk_synthesize_crossing_events (GtkRoot *toplevel,
widget = _gtk_widget_get_parent (widget);
}
gtk_widget_stack_init (&target_array);
gtk_array_init (&target_array, (void**)stack_targets, 16);
for (widget = new_target; widget; widget = _gtk_widget_get_parent (widget))
gtk_widget_stack_append (&target_array, g_object_ref (widget));
gtk_array_add (&target_array, widget);
crossing.direction = GTK_CROSSING_IN;
seen_ancestor = FALSE;
for (i = gtk_widget_stack_get_size (&target_array) - 1; i >= 0; i--)
for (i = (int)target_array.len - 1; i >= 0; i--)
{
widget = gtk_widget_stack_get (&target_array, i);
widget = gtk_array_index (&target_array, i);
if (i < gtk_widget_stack_get_size (&target_array) - 1)
crossing.new_descendent = gtk_widget_stack_get (&target_array, i + 1);
if (i < (int)target_array.len - 1)
crossing.new_descendent = gtk_array_index (&target_array, i + 1);
else
crossing.new_descendent = NULL;
@@ -1422,7 +1417,7 @@ gtk_synthesize_crossing_events (GtkRoot *toplevel,
gtk_widget_set_state_flags (widget, GTK_STATE_FLAG_PRELIGHT, FALSE);
}
gtk_widget_stack_clear (&target_array);
gtk_array_free (&target_array, NULL);
}
static GtkWidget *
@@ -1999,12 +1994,13 @@ gtk_propagate_event_internal (GtkWidget *widget,
{
gint handled_event = FALSE;
GtkWidget *target = widget;
GtkWidgetStack widget_array;
GtkArray widget_array;
GtkWidget *stack_widgets[16];
int i;
/* First, propagate event down */
gtk_widget_stack_init (&widget_array);
gtk_widget_stack_append (&widget_array, g_object_ref (widget));
gtk_array_init (&widget_array, (void**)stack_widgets, 16);
gtk_array_add (&widget_array, g_object_ref (widget));
for (;;)
{
@@ -2012,16 +2008,16 @@ gtk_propagate_event_internal (GtkWidget *widget,
if (!widget)
break;
gtk_widget_stack_append (&widget_array, g_object_ref (widget));
gtk_array_add (&widget_array, g_object_ref (widget));
if (widget == topmost)
break;
}
i = gtk_widget_stack_get_size (&widget_array) - 1;
i = widget_array.len - 1;
for (;;)
{
widget = gtk_widget_stack_get (&widget_array, i);
widget = gtk_array_index (&widget_array, i);
if (!_gtk_widget_is_sensitive (widget))
{
@@ -2054,9 +2050,9 @@ gtk_propagate_event_internal (GtkWidget *widget,
* parents can see the button and motion
* events of the children.
*/
for (i = 0; i < gtk_widget_stack_get_size (&widget_array); i++)
for (i = 0; i < widget_array.len; i++)
{
widget = gtk_widget_stack_get (&widget_array, i);
widget = gtk_array_index (&widget_array, i);
/* Scroll events are special cased here because it
* feels wrong when scrolling a GtkViewport, say,
@@ -2075,7 +2071,7 @@ gtk_propagate_event_internal (GtkWidget *widget,
}
}
gtk_widget_stack_clear (&widget_array);
gtk_array_free (&widget_array, g_object_unref);
return handled_event;
}
+35 -2
View File
@@ -63,6 +63,7 @@
enum {
PROP_0,
PROP_HAS_MAP,
PROP_ITEM_TYPE,
PROP_MODEL,
NUM_PROPERTIES
};
@@ -85,6 +86,7 @@ struct _GtkMapListModel
{
GObject parent_instance;
GType item_type;
GListModel *model;
GtkMapListModelMapFunc map_func;
gpointer user_data;
@@ -143,7 +145,9 @@ gtk_map_list_model_get_nth (GtkRbTree *tree,
static GType
gtk_map_list_model_get_item_type (GListModel *list)
{
return G_TYPE_OBJECT;
GtkMapListModel *self = GTK_MAP_LIST_MODEL (list);
return self->item_type;
}
static guint
@@ -195,6 +199,11 @@ gtk_map_list_model_get_item (GListModel *list,
}
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);
return node->item;
@@ -284,6 +293,10 @@ gtk_map_list_model_set_property (GObject *object,
switch (prop_id)
{
case PROP_ITEM_TYPE:
self->item_type = g_value_get_gtype (value);
break;
case PROP_MODEL:
gtk_map_list_model_set_model (self, g_value_get_object (value));
break;
@@ -308,6 +321,10 @@ gtk_map_list_model_get_property (GObject *object,
g_value_set_boolean (value, self->items != NULL);
break;
case PROP_ITEM_TYPE:
g_value_set_gtype (value, self->item_type);
break;
case PROP_MODEL:
g_value_set_object (value, self->model);
break;
@@ -365,6 +382,18 @@ gtk_map_list_model_class_init (GtkMapListModelClass *class)
FALSE,
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:
*
@@ -412,6 +441,7 @@ gtk_map_list_model_augment (GtkRbTree *map,
/**
* 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
* @map_func: (allow-none): map function or %NULL to not map items
* @user_data: (closure): user data passed to @map_func
@@ -422,16 +452,19 @@ gtk_map_list_model_augment (GtkRbTree *map,
* Returns: a new #GtkMapListModel
**/
GtkMapListModel *
gtk_map_list_model_new (GListModel *model,
gtk_map_list_model_new (GType item_type,
GListModel *model,
GtkMapListModelMapFunc map_func,
gpointer user_data,
GDestroyNotify user_destroy)
{
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);
result = g_object_new (GTK_TYPE_MAP_LIST_MODEL,
"item-type", item_type,
"model", model,
NULL);
+2 -1
View File
@@ -53,7 +53,8 @@ G_DECLARE_FINAL_TYPE (GtkMapListModel, gtk_map_list_model, GTK, MAP_LIST_MODEL,
typedef gpointer (* GtkMapListModelMapFunc) (gpointer item, gpointer user_data);
GDK_AVAILABLE_IN_ALL
GtkMapListModel * gtk_map_list_model_new (GListModel *model,
GtkMapListModel * gtk_map_list_model_new (GType item_type,
GListModel *model,
GtkMapListModelMapFunc map_func,
gpointer user_data,
GDestroyNotify user_destroy);
+12 -57
View File
@@ -62,7 +62,9 @@ static GParamSpec *properties[N_PROPS] = { NULL, };
static GType
gtk_multi_selection_get_item_type (GListModel *list)
{
return G_TYPE_OBJECT;
GtkMultiSelection *self = GTK_MULTI_SELECTION (list);
return g_list_model_get_item_type (self->model);
}
static guint
@@ -70,9 +72,6 @@ gtk_multi_selection_get_n_items (GListModel *list)
{
GtkMultiSelection *self = GTK_MULTI_SELECTION (list);
if (self->model == NULL)
return 0;
return g_list_model_get_n_items (self->model);
}
@@ -82,9 +81,6 @@ gtk_multi_selection_get_item (GListModel *list,
{
GtkMultiSelection *self = GTK_MULTI_SELECTION (list);
if (self->model == NULL)
return NULL;
return g_list_model_get_item (self->model, position);
}
@@ -178,7 +174,7 @@ gtk_multi_selection_set_selection (GtkSelectionModel *model,
max = gtk_bitset_get_maximum (changes);
/* sanity check */
n_items = self->model ? g_list_model_get_n_items (self->model) : 0;
n_items = g_list_model_get_n_items (self->model);
if (max >= n_items)
{
gtk_bitset_remove_range_closed (changes, n_items, max);
@@ -222,7 +218,7 @@ gtk_multi_selection_items_changed_cb (GListModel *model,
GHashTable *pending = NULL;
guint i;
gtk_bitset_splice (self->selected, position, removed, added);
gtk_bitset_slice (self->selected, position, removed, added);
g_hash_table_iter_init (&iter, self->items);
while (g_hash_table_iter_next (&iter, &item, &pos_pointer))
@@ -295,7 +291,12 @@ gtk_multi_selection_set_property (GObject *object,
switch (prop_id)
{
case PROP_MODEL:
gtk_multi_selection_set_model (self, g_value_get_object (value));
self->model = g_value_dup_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;
default:
@@ -356,7 +357,7 @@ gtk_multi_selection_class_init (GtkMultiSelectionClass *klass)
P_("Model"),
P_("List managed by this selection"),
G_TYPE_LIST_MODEL,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (gobject_class, N_PROPS, properties);
}
@@ -401,49 +402,3 @@ gtk_multi_selection_get_model (GtkMultiSelection *self)
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]);
}
-3
View File
@@ -35,9 +35,6 @@ GListModel * gtk_multi_selection_new (GListModel *mo
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
+12 -50
View File
@@ -60,7 +60,9 @@ static GParamSpec *properties[N_PROPS] = { NULL, };
static GType
gtk_no_selection_get_item_type (GListModel *list)
{
return G_TYPE_OBJECT;
GtkNoSelection *self = GTK_NO_SELECTION (list);
return g_list_model_get_item_type (self->model);
}
static guint
@@ -68,21 +70,15 @@ gtk_no_selection_get_n_items (GListModel *list)
{
GtkNoSelection *self = GTK_NO_SELECTION (list);
if (self->model == NULL)
return 0;
return g_list_model_get_n_items (self->model);
}
static gpointer
gtk_no_selection_get_item (GListModel *list,
guint position)
guint position)
{
GtkNoSelection *self = GTK_NO_SELECTION (list);
if (self->model == NULL)
return NULL;
return g_list_model_get_item (self->model, position);
}
@@ -136,9 +132,9 @@ gtk_no_selection_clear_model (GtkNoSelection *self)
static void
gtk_no_selection_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkNoSelection *self = GTK_NO_SELECTION (object);
@@ -146,7 +142,10 @@ gtk_no_selection_set_property (GObject *object,
switch (prop_id)
{
case PROP_MODEL:
gtk_no_selection_set_model (self, g_value_get_object (value));
gtk_no_selection_clear_model (self);
self->model = g_value_dup_object (value);
g_signal_connect_swapped (self->model, "items-changed",
G_CALLBACK (g_list_model_items_changed), self);
break;
default:
@@ -204,7 +203,7 @@ gtk_no_selection_class_init (GtkNoSelectionClass *klass)
P_("The model"),
P_("The model being managed"),
G_TYPE_LIST_MODEL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (gobject_class, N_PROPS, properties);
}
@@ -248,40 +247,3 @@ gtk_no_selection_get_model (GtkNoSelection *self)
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]);
}
-3
View File
@@ -34,9 +34,6 @@ GtkNoSelection * gtk_no_selection_new (GListModel
GDK_AVAILABLE_IN_ALL
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
+2 -2
View File
@@ -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->custom_paper_list);
g_list_store_append (store, dialog->manage_papers_list);
paper_size_list = G_LIST_MODEL (gtk_flatten_list_model_new (G_LIST_MODEL (store)));
paper_size_list = G_LIST_MODEL (gtk_flatten_list_model_new (GTK_TYPE_PAGE_SETUP, G_LIST_MODEL (store)));
gtk_drop_down_set_model (GTK_DROP_DOWN (dialog->paper_size_combo), paper_size_list);
g_object_unref (store);
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_object_unref (printer_list);
full_list = G_LIST_MODEL (gtk_flatten_list_model_new (G_LIST_MODEL (printer_list_list)));
full_list = G_LIST_MODEL (gtk_flatten_list_model_new (GTK_TYPE_PRINTER, G_LIST_MODEL (printer_list_list)));
filter = gtk_custom_filter_new (match_func, NULL, NULL);
dialog->printer_list = G_LIST_MODEL (gtk_filter_list_model_new (full_list, filter));
+56 -47
View File
@@ -162,7 +162,7 @@ struct _GtkPlacesSidebar {
GtkWidget *popover;
GtkSidebarRow *context_row;
GListStore *shortcuts;
GSList *shortcuts;
GDBusProxy *hostnamed_proxy;
GCancellable *hostnamed_cancellable;
@@ -709,25 +709,15 @@ file_is_shown (GtkPlacesSidebar *sidebar,
return found;
}
typedef struct
{
GtkPlacesSidebar *sidebar;
guint position;
} ShortcutData;
static void
on_app_shortcuts_query_complete (GObject *source,
GAsyncResult *result,
gpointer data)
{
ShortcutData *sdata = data;
GtkPlacesSidebar *sidebar = sdata->sidebar;
guint pos = sdata->position;
GtkPlacesSidebar *sidebar = data;
GFile *file = G_FILE (source);
GFileInfo *info;
g_free (sdata);
info = g_file_query_info_finish (file, result, NULL);
if (info)
@@ -736,12 +726,20 @@ on_app_shortcuts_query_complete (GObject *source,
gchar *tooltip;
const gchar *name;
GIcon *start_icon;
int pos = 0;
name = g_file_info_get_display_name (info);
start_icon = g_file_info_get_symbolic_icon (info);
uri = g_file_get_uri (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,
SECTION_COMPUTER,
name, start_icon, NULL, uri,
@@ -759,13 +757,11 @@ on_app_shortcuts_query_complete (GObject *source,
static void
add_application_shortcuts (GtkPlacesSidebar *sidebar)
{
guint i, n;
GSList *l;
n = g_list_model_get_n_items (G_LIST_MODEL (sidebar->shortcuts));
for (i = 0; i < n; i++)
for (l = sidebar->shortcuts; l; l = l->next)
{
GFile *file = g_list_model_get_item (G_LIST_MODEL (sidebar->shortcuts), i);
ShortcutData *data;
GFile *file = l->data;
if (!should_show_file (sidebar, file))
continue;
@@ -773,16 +769,13 @@ add_application_shortcuts (GtkPlacesSidebar *sidebar)
if (file_is_shown (sidebar, file))
continue;
data = g_new (ShortcutData, 1);
data->sidebar = sidebar;
data->position = i;
g_file_query_info_async (file,
"standard::display-name,standard::symbolic-icon",
G_FILE_QUERY_INFO_NONE,
G_PRIORITY_DEFAULT,
sidebar->cancellable,
on_app_shortcuts_query_complete,
data);
sidebar);
}
}
@@ -3755,8 +3748,6 @@ gtk_places_sidebar_init (GtkPlacesSidebar *sidebar)
sidebar->show_recent = TRUE;
sidebar->show_desktop = TRUE;
sidebar->shortcuts = g_list_store_new (G_TYPE_FILE);
create_volume_monitor (sidebar);
sidebar->open_flags = GTK_PLACES_OPEN_NORMAL;
@@ -4027,7 +4018,9 @@ gtk_places_sidebar_dispose (GObject *object)
g_clear_object (&sidebar->current_location);
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
for (l = cloud_providers_collector_get_providers (sidebar->cloud_manager);
@@ -4789,6 +4782,24 @@ gtk_places_sidebar_get_show_trash (GtkPlacesSidebar *sidebar)
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:
* @sidebar: a places sidebar
@@ -4812,7 +4823,8 @@ gtk_places_sidebar_add_shortcut (GtkPlacesSidebar *sidebar,
g_return_if_fail (GTK_IS_PLACES_SIDEBAR (sidebar));
g_return_if_fail (G_IS_FILE (location));
g_list_store_append (sidebar->shortcuts, location);
g_object_ref (location);
sidebar->shortcuts = g_slist_append (sidebar->shortcuts, location);
update_places (sidebar);
}
@@ -4830,46 +4842,43 @@ void
gtk_places_sidebar_remove_shortcut (GtkPlacesSidebar *sidebar,
GFile *location)
{
guint i, n;
GSList *link;
GFile *shortcut;
g_return_if_fail (GTK_IS_PLACES_SIDEBAR (sidebar));
g_return_if_fail (G_IS_FILE (location));
n = g_list_model_get_n_items (G_LIST_MODEL (sidebar->shortcuts));
for (i = 0; i < n; i++)
{
GFile *shortcut = g_list_model_get_item (G_LIST_MODEL (sidebar->shortcuts), i);
link = find_shortcut_link (sidebar, location);
if (!link)
return;
if (shortcut == location)
{
g_list_store_remove (sidebar->shortcuts, i);
g_object_unref (shortcut);
update_places (sidebar);
return;
}
shortcut = G_FILE (link->data);
g_object_unref (shortcut);
g_object_unref (shortcut);
}
sidebar->shortcuts = g_slist_delete_link (sidebar->shortcuts, link);
update_places (sidebar);
}
/*
* gtk_places_sidebar_list_shortcuts:
* @sidebar: a places sidebar
*
* Gets the list of shortcuts, as a list model containing #GFile objects.
* Gets the list of shortcuts.
*
* You should not modify the returned list model. Future changes to
* @sidebar may or may not affect the returned model.
*
* Returns: (transfer full): a list model of #GFiles that have been added as
* Returns: (element-type GFile) (transfer full):
* A #GSList of #GFile of the locations that have been added as
* 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);
* ]|
*/
GListModel *
gtk_places_sidebar_get_shortcuts (GtkPlacesSidebar *sidebar)
GSList *
gtk_places_sidebar_list_shortcuts (GtkPlacesSidebar *sidebar)
{
g_return_val_if_fail (GTK_IS_PLACES_SIDEBAR (sidebar), NULL);
return G_LIST_MODEL (g_object_ref (sidebar->shortcuts));
return g_slist_copy_deep (sidebar->shortcuts, (GCopyFunc) g_object_ref, NULL);
}
/*
+1 -1
View File
@@ -92,7 +92,7 @@ void gtk_places_sidebar_add_shortcut (GtkPlacesSideb
GFile *location);
void gtk_places_sidebar_remove_shortcut (GtkPlacesSidebar *sidebar,
GFile *location);
GListModel * gtk_places_sidebar_get_shortcuts (GtkPlacesSidebar *sidebar);
GSList * gtk_places_sidebar_list_shortcuts (GtkPlacesSidebar *sidebar);
GFile * gtk_places_sidebar_get_nth_bookmark (GtkPlacesSidebar *sidebar,
gint n);
+2 -2
View File
@@ -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->custom_paper_list);
g_list_store_append (store, dialog->manage_papers_list);
paper_size_list = G_LIST_MODEL (gtk_flatten_list_model_new (G_LIST_MODEL (store)));
paper_size_list = G_LIST_MODEL (gtk_flatten_list_model_new (GTK_TYPE_PAGE_SETUP, G_LIST_MODEL (store)));
gtk_drop_down_set_model (GTK_DROP_DOWN (dialog->paper_size_combo), paper_size_list);
g_object_unref (store);
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));
}
model = G_LIST_MODEL (gtk_flatten_list_model_new (G_LIST_MODEL (lists)));
model = G_LIST_MODEL (gtk_flatten_list_model_new (GTK_TYPE_PRINTER, G_LIST_MODEL (lists)));
g_object_unref (lists);
+10 -10
View File
@@ -110,7 +110,7 @@ static GParamSpec *properties[N_PROPS] = { NULL, };
static GType
gtk_shortcut_controller_list_model_get_item_type (GListModel *list)
{
return G_TYPE_OBJECT;
return GTK_TYPE_SHORTCUT;
}
static guint
@@ -198,6 +198,12 @@ gtk_shortcut_controller_set_property (GObject *object,
case PROP_MODEL:
{
GListModel *model = g_value_get_object (value);
if (model && g_list_model_get_item_type (model) != GTK_TYPE_SHORTCUT)
{
g_warning ("Setting a model with type '%s' on a shortcut controller that requires 'GtkShortcut'",
g_type_name (g_list_model_get_item_type (model)));
model = NULL;
}
if (model == NULL)
{
self->shortcuts = G_LIST_MODEL (g_list_store_new (GTK_TYPE_SHORTCUT));
@@ -303,11 +309,6 @@ gtk_shortcut_controller_run_controllers (GtkEventController *controller,
index = (self->last_activated + 1 + i) % g_list_model_get_n_items (self->shortcuts);
shortcut = g_list_model_get_item (self->shortcuts, index);
if (!GTK_IS_SHORTCUT (shortcut))
{
g_object_unref (shortcut);
continue;
}
switch (gtk_shortcut_trigger_trigger (gtk_shortcut_get_trigger (shortcut), event, enable_mnemonics))
{
@@ -483,8 +484,7 @@ gtk_shortcut_controller_set_widget (GtkEventController *controller,
for (i = 0, p = g_list_model_get_n_items (G_LIST_MODEL (controller)); i < p; i++)
{
GtkShortcut *shortcut = g_list_model_get_item (G_LIST_MODEL (controller), i);
if (GTK_IS_SHORTCUT (shortcut))
update_accel (shortcut, widget, TRUE);
update_accel (shortcut, widget, TRUE);
g_object_unref (shortcut);
}
@@ -506,8 +506,7 @@ gtk_shortcut_controller_unset_widget (GtkEventController *controller)
for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (controller)); i++)
{
GtkShortcut *shortcut = g_list_model_get_item (G_LIST_MODEL (controller), i);
if (GTK_IS_SHORTCUT (shortcut))
update_accel (shortcut, widget, FALSE);
update_accel (shortcut, widget, FALSE);
g_object_unref (shortcut);
}
#endif
@@ -698,6 +697,7 @@ GtkEventController *
gtk_shortcut_controller_new_for_model (GListModel *model)
{
g_return_val_if_fail (G_IS_LIST_MODEL (model), NULL);
g_return_val_if_fail (g_list_model_get_item_type (model) == GTK_TYPE_SHORTCUT, NULL);
return g_object_new (GTK_TYPE_SHORTCUT_CONTROLLER,
"model", model,
+2 -2
View File
@@ -49,7 +49,7 @@ gtk_shortcut_manager_create_controllers (GtkWidget *widget)
GtkEventController *controller;
store = g_list_store_new (GTK_TYPE_SHORTCUT_CONTROLLER);
model = gtk_flatten_list_model_new (G_LIST_MODEL (store));
model = gtk_flatten_list_model_new (GTK_TYPE_SHORTCUT, G_LIST_MODEL (store));
g_object_unref (store);
g_object_set_data_full (G_OBJECT (widget), "gtk-shortcut-manager-bubble", model, g_object_unref);
controller = gtk_shortcut_controller_new_for_model (G_LIST_MODEL (model));
@@ -57,7 +57,7 @@ gtk_shortcut_manager_create_controllers (GtkWidget *widget)
gtk_widget_add_controller (widget, controller);
store = g_list_store_new (GTK_TYPE_SHORTCUT_CONTROLLER);
model = gtk_flatten_list_model_new (G_LIST_MODEL (store));
model = gtk_flatten_list_model_new (GTK_TYPE_SHORTCUT, G_LIST_MODEL (store));
g_object_unref (store);
g_object_set_data_full (G_OBJECT (widget), "gtk-shortcut-manager-capture", model, g_object_unref);
controller = gtk_shortcut_controller_new_for_model (G_LIST_MODEL (model));
+10 -65
View File
@@ -72,7 +72,9 @@ static GParamSpec *properties[N_PROPS] = { NULL, };
static GType
gtk_single_selection_get_item_type (GListModel *list)
{
return G_TYPE_OBJECT;
GtkSingleSelection *self = GTK_SINGLE_SELECTION (list);
return g_list_model_get_item_type (self->model);
}
static guint
@@ -80,9 +82,6 @@ gtk_single_selection_get_n_items (GListModel *list)
{
GtkSingleSelection *self = GTK_SINGLE_SELECTION (list);
if (self->model == NULL)
return 0;
return g_list_model_get_n_items (self->model);
}
@@ -92,9 +91,6 @@ gtk_single_selection_get_item (GListModel *list,
{
GtkSingleSelection *self = GTK_SINGLE_SELECTION (list);
if (self->model == NULL)
return NULL;
return g_list_model_get_item (self->model, position);
}
@@ -311,7 +307,12 @@ gtk_single_selection_set_property (GObject *object,
break;
case PROP_MODEL:
gtk_single_selection_set_model (self, g_value_get_object (value));
gtk_single_selection_clear_model (self);
self->model = g_value_dup_object (value);
g_signal_connect (self->model, "items-changed",
G_CALLBACK (gtk_single_selection_items_changed_cb), self);
if (self->autoselect)
gtk_single_selection_set_selected (self, 0);
break;
case PROP_SELECTED:
@@ -439,7 +440,7 @@ gtk_single_selection_class_init (GtkSingleSelectionClass *klass)
P_("The model"),
P_("The model being managed"),
G_TYPE_LIST_MODEL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (gobject_class, N_PROPS, properties);
}
@@ -485,62 +486,6 @@ gtk_single_selection_get_model (GtkSingleSelection *self)
return self->model;
}
/**
* gtk_single_selection_set_model:
* @self: a #GtkSingleSelection
* @model: (allow-none): A #GListModel to wrap
*
* Sets the model that @self should wrap. If @model is %NULL, @self
* will be empty.
**/
void
gtk_single_selection_set_model (GtkSingleSelection *self,
GListModel *model)
{
guint n_items_before;
g_return_if_fail (GTK_IS_SINGLE_SELECTION (self));
g_return_if_fail (model == NULL || G_IS_LIST_MODEL (model));
if (self->model == model)
return;
g_object_freeze_notify (G_OBJECT (self));
n_items_before = self->model ? g_list_model_get_n_items (self->model) : 0;
gtk_single_selection_clear_model (self);
if (model)
{
self->model = g_object_ref (model);
g_signal_connect (self->model, "items-changed",
G_CALLBACK (gtk_single_selection_items_changed_cb), self);
gtk_single_selection_items_changed_cb (self->model,
0,
n_items_before,
g_list_model_get_n_items (model),
self);
}
else
{
if (self->selected != GTK_INVALID_LIST_POSITION)
{
self->selected = GTK_INVALID_LIST_POSITION;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SELECTED]);
}
if (self->selected_item)
{
g_clear_object (&self->selected_item);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SELECTED_ITEM]);
}
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]);
g_object_thaw_notify (G_OBJECT (self));
}
/**
* gtk_single_selection_get_selected:
* @self: a #GtkSingleSelection
+10 -13
View File
@@ -35,25 +35,22 @@ GtkSingleSelection * gtk_single_selection_new (GListModel
GDK_AVAILABLE_IN_ALL
GListModel * gtk_single_selection_get_model (GtkSingleSelection *self);
GDK_AVAILABLE_IN_ALL
void gtk_single_selection_set_model (GtkSingleSelection *self,
GListModel *model);
guint gtk_single_selection_get_selected (GtkSingleSelection *self);
GDK_AVAILABLE_IN_ALL
guint gtk_single_selection_get_selected (GtkSingleSelection *self);
void gtk_single_selection_set_selected (GtkSingleSelection *self,
guint position);
GDK_AVAILABLE_IN_ALL
void gtk_single_selection_set_selected (GtkSingleSelection *self,
guint position);
gpointer gtk_single_selection_get_selected_item (GtkSingleSelection *self);
GDK_AVAILABLE_IN_ALL
gpointer gtk_single_selection_get_selected_item (GtkSingleSelection *self);
gboolean gtk_single_selection_get_autoselect (GtkSingleSelection *self);
GDK_AVAILABLE_IN_ALL
gboolean gtk_single_selection_get_autoselect (GtkSingleSelection *self);
void gtk_single_selection_set_autoselect (GtkSingleSelection *self,
gboolean autoselect);
GDK_AVAILABLE_IN_ALL
void gtk_single_selection_set_autoselect (GtkSingleSelection *self,
gboolean autoselect);
gboolean gtk_single_selection_get_can_unselect (GtkSingleSelection *self);
GDK_AVAILABLE_IN_ALL
gboolean gtk_single_selection_get_can_unselect (GtkSingleSelection *self);
GDK_AVAILABLE_IN_ALL
void gtk_single_selection_set_can_unselect (GtkSingleSelection *self,
gboolean can_unselect);
void gtk_single_selection_set_can_unselect (GtkSingleSelection *self,
gboolean can_unselect);
G_END_DECLS
+47 -3
View File
@@ -41,6 +41,7 @@
enum {
PROP_0,
PROP_ITEM_TYPE,
PROP_MODEL,
PROP_OFFSET,
PROP_SIZE,
@@ -51,6 +52,7 @@ struct _GtkSliceListModel
{
GObject parent_instance;
GType item_type;
GListModel *model;
guint offset;
guint size;
@@ -68,7 +70,9 @@ static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
static GType
gtk_slice_list_model_get_item_type (GListModel *list)
{
return G_TYPE_OBJECT;
GtkSliceListModel *self = GTK_SLICE_LIST_MODEL (list);
return self->item_type;
}
static guint
@@ -178,6 +182,10 @@ gtk_slice_list_model_set_property (GObject *object,
switch (prop_id)
{
case PROP_ITEM_TYPE:
self->item_type = g_value_get_gtype (value);
break;
case PROP_MODEL:
gtk_slice_list_model_set_model (self, g_value_get_object (value));
break;
@@ -206,6 +214,10 @@ gtk_slice_list_model_get_property (GObject *object,
switch (prop_id)
{
case PROP_ITEM_TYPE:
g_value_set_gtype (value, self->item_type);
break;
case PROP_MODEL:
g_value_set_object (value, self->model);
break;
@@ -253,6 +265,18 @@ gtk_slice_list_model_class_init (GtkSliceListModelClass *class)
gobject_class->get_property = gtk_slice_list_model_get_property;
gobject_class->dispose = gtk_slice_list_model_dispose;
/**
* GtkSliceListModel: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);
/**
* GtkSliceListModel:model:
*
@@ -300,7 +324,7 @@ gtk_slice_list_model_init (GtkSliceListModel *self)
/**
* gtk_slice_list_model_new:
* @model: (transfer none) (allow-none): The model to use
* @model: (transfer none): The model to use
* @offset: the offset of the slice
* @size: maximum size of the slice
*
@@ -314,15 +338,35 @@ gtk_slice_list_model_new (GListModel *model,
guint offset,
guint size)
{
g_return_val_if_fail (model == NULL || G_IS_LIST_MODEL (model), NULL);
g_return_val_if_fail (G_IS_LIST_MODEL (model), NULL);
return g_object_new (GTK_TYPE_SLICE_LIST_MODEL,
"item-type", g_list_model_get_item_type (model),
"model", model,
"offset", offset,
"size", size,
NULL);
}
/**
* gtk_slice_list_model_new_for_type:
* @item_type: the type of items
*
* Creates a new empty #GtkSliceListModel for the given @item_type that
* can be set up later.
*
* Returns: a new empty #GtkSliceListModel
**/
GtkSliceListModel *
gtk_slice_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_SLICE_LIST_MODEL,
"item-type", item_type,
NULL);
}
/**
* gtk_slice_list_model_set_model:
* @self: a #GtkSliceListModel
+2
View File
@@ -40,6 +40,8 @@ GDK_AVAILABLE_IN_ALL
GtkSliceListModel * gtk_slice_list_model_new (GListModel *model,
guint offset,
guint size);
GDK_AVAILABLE_IN_ALL
GtkSliceListModel * gtk_slice_list_model_new_for_type (GType item_type);
GDK_AVAILABLE_IN_ALL
void gtk_slice_list_model_set_model (GtkSliceListModel *self,
+32 -115
View File
@@ -34,11 +34,6 @@
#include "gtk/gskpango.h"
#define GTK_VECTOR_NAME gtk_snapshot_nodes
#define GTK_VECTOR_TYPE_NAME GtkSnapshotNodes
#define GTK_VECTOR_ELEMENT_TYPE GskRenderNode *
#define GTK_VECTOR_FREE_FUNC gsk_render_node_unref
#include "gtkvectorimpl.c"
/**
* SECTION:gtksnapshot
@@ -59,85 +54,6 @@
* use gtk_snapshot_new().
*/
typedef struct _GtkSnapshotState GtkSnapshotState;
typedef GskRenderNode * (* GtkSnapshotCollectFunc) (GtkSnapshot *snapshot,
GtkSnapshotState *state,
GskRenderNode **nodes,
guint n_nodes);
struct _GtkSnapshotState {
guint start_node_index;
guint n_nodes;
GskTransform * transform;
GtkSnapshotCollectFunc collect_func;
union {
struct {
double opacity;
} opacity;
struct {
double radius;
} blur;
struct {
graphene_matrix_t matrix;
graphene_vec4_t offset;
} color_matrix;
struct {
graphene_rect_t bounds;
graphene_rect_t child_bounds;
} repeat;
struct {
graphene_rect_t bounds;
} clip;
struct {
GskRoundedRect bounds;
} rounded_clip;
struct {
gsize n_shadows;
GskShadow *shadows;
GskShadow a_shadow; /* Used if n_shadows == 1 */
} shadow;
struct {
GskBlendMode blend_mode;
GskRenderNode *bottom_node;
} blend;
struct {
double progress;
GskRenderNode *start_node;
} cross_fade;
struct {
char *message;
} debug;
} data;
};
static void gtk_snapshot_state_clear (GtkSnapshotState *state);
#define GTK_VECTOR_NAME gtk_snapshot_states
#define GTK_VECTOR_TYPE_NAME GtkSnapshotStates
#define GTK_VECTOR_ELEMENT_TYPE GtkSnapshotState
#define GTK_VECTOR_FREE_FUNC gtk_snapshot_state_clear
#define GTK_VECTOR_BY_VALUE 1
#include "gtkvectorimpl.c"
/* This is a nasty little hack. We typedef GtkSnapshot to the fake object GdkSnapshot
* so that we don't need to typecast between them.
* After all, the GdkSnapshot only exist so poor language bindings don't trip. Hardcore
* C code can just blatantly ignore such layering violations with a typedef.
*/
struct _GdkSnapshot {
GObject parent_instance; /* it's really GdkSnapshot, but don't tell anyone! */
GtkSnapshotStates state_stack;
GtkSnapshotNodes nodes;
};
struct _GtkSnapshotClass {
GObjectClass parent_class; /* it's really GdkSnapshotClass, but don't tell anyone! */
};
G_DEFINE_TYPE (GtkSnapshot, gtk_snapshot, GDK_TYPE_SNAPSHOT)
static void
@@ -145,11 +61,11 @@ gtk_snapshot_dispose (GObject *object)
{
GtkSnapshot *snapshot = GTK_SNAPSHOT (object);
if (!gtk_snapshot_states_is_empty (&snapshot->state_stack))
if (snapshot->state_stack)
gsk_render_node_unref (gtk_snapshot_to_node (snapshot));
g_assert (gtk_snapshot_states_is_empty (&snapshot->state_stack));
g_assert (gtk_snapshot_nodes_is_empty (&snapshot->nodes));
g_assert (snapshot->state_stack == NULL);
g_assert (snapshot->nodes == NULL);
G_OBJECT_CLASS (gtk_snapshot_parent_class)->dispose (object);
}
@@ -196,15 +112,15 @@ gtk_snapshot_push_state (GtkSnapshot *snapshot,
GskTransform *transform,
GtkSnapshotCollectFunc collect_func)
{
const gsize n_states = gtk_snapshot_states_get_size (&snapshot->state_stack);
const gsize n_states = snapshot->state_stack->len;
GtkSnapshotState *state;
gtk_snapshot_states_set_size (&snapshot->state_stack, n_states + 1);
state = gtk_snapshot_states_get (&snapshot->state_stack, n_states);
g_array_set_size (snapshot->state_stack, n_states + 1);
state = &g_array_index (snapshot->state_stack, GtkSnapshotState, n_states);
state->transform = gsk_transform_ref (transform);
state->collect_func = collect_func;
state->start_node_index = gtk_snapshot_nodes_get_size (&snapshot->nodes);
state->start_node_index = snapshot->nodes->len;
state->n_nodes = 0;
return state;
@@ -213,21 +129,17 @@ gtk_snapshot_push_state (GtkSnapshot *snapshot,
static GtkSnapshotState *
gtk_snapshot_get_current_state (const GtkSnapshot *snapshot)
{
gsize size = gtk_snapshot_states_get_size (&snapshot->state_stack);
g_assert (snapshot->state_stack->len > 0);
g_assert (size > 0);
return gtk_snapshot_states_get (&snapshot->state_stack, size - 1);
return &g_array_index (snapshot->state_stack, GtkSnapshotState, snapshot->state_stack->len - 1);
}
static GtkSnapshotState *
gtk_snapshot_get_previous_state (const GtkSnapshot *snapshot)
{
gsize size = gtk_snapshot_states_get_size (&snapshot->state_stack);
g_assert (snapshot->state_stack->len > 1);
g_assert (size > 1);
return gtk_snapshot_states_get (&snapshot->state_stack, size - 2);
return &g_array_index (snapshot->state_stack, GtkSnapshotState, snapshot->state_stack->len - 2);
}
static void
@@ -250,8 +162,9 @@ gtk_snapshot_new (void)
snapshot = g_object_new (GTK_TYPE_SNAPSHOT, NULL);
gtk_snapshot_states_init (&snapshot->state_stack);
gtk_snapshot_nodes_init (&snapshot->nodes);
snapshot->state_stack = g_array_new (FALSE, TRUE, sizeof (GtkSnapshotState));
g_array_set_clear_func (snapshot->state_stack, (GDestroyNotify)gtk_snapshot_state_clear);
snapshot->nodes = g_ptr_array_new_with_free_func ((GDestroyNotify)gsk_render_node_unref);
gtk_snapshot_push_state (snapshot,
NULL,
@@ -1116,28 +1029,30 @@ gtk_snapshot_pop_one (GtkSnapshot *snapshot)
guint state_index;
GskRenderNode *node;
if (gtk_snapshot_states_is_empty (&snapshot->state_stack))
if (snapshot->state_stack->len == 0)
{
g_warning ("Too many gtk_snapshot_pop() calls.");
return NULL;
}
state = gtk_snapshot_get_current_state (snapshot);
state_index = gtk_snapshot_states_get_size (&snapshot->state_stack) - 1;
state_index = snapshot->state_stack->len - 1;
if (state->collect_func)
{
node = state->collect_func (snapshot,
state,
(GskRenderNode **) gtk_snapshot_nodes_index (&snapshot->nodes, state->start_node_index),
(GskRenderNode **) snapshot->nodes->pdata + state->start_node_index,
state->n_nodes);
/* The collect func may not modify the state stack... */
g_assert (state_index == gtk_snapshot_states_get_size (&snapshot->state_stack) - 1);
g_assert (state_index == snapshot->state_stack->len - 1);
/* Remove all the state's nodes from the list of nodes */
g_assert (state->start_node_index + state->n_nodes == gtk_snapshot_nodes_get_size (&snapshot->nodes));
gtk_snapshot_nodes_splice (&snapshot->nodes, state->start_node_index, state->n_nodes, NULL, 0);
g_assert (state->start_node_index + state->n_nodes == snapshot->nodes->len);
g_ptr_array_remove_range (snapshot->nodes,
snapshot->nodes->len - state->n_nodes,
state->n_nodes);
}
else
{
@@ -1148,10 +1063,10 @@ gtk_snapshot_pop_one (GtkSnapshot *snapshot)
/* move the nodes to the parent */
previous_state = gtk_snapshot_get_previous_state (snapshot);
previous_state->n_nodes += state->n_nodes;
g_assert (previous_state->start_node_index + previous_state->n_nodes == gtk_snapshot_nodes_get_size (&snapshot->nodes));
g_assert (previous_state->start_node_index + previous_state->n_nodes == snapshot->nodes->len);
}
gtk_snapshot_states_splice (&snapshot->state_stack, state_index, 1, NULL, 0);
g_array_remove_index (snapshot->state_stack, state_index);
return node;
}
@@ -1166,7 +1081,7 @@ gtk_snapshot_append_node_internal (GtkSnapshot *snapshot,
if (current_state)
{
gtk_snapshot_nodes_append (&snapshot->nodes, node);
g_ptr_array_add (snapshot->nodes, node);
current_state->n_nodes ++;
}
else
@@ -1247,14 +1162,16 @@ gtk_snapshot_to_node (GtkSnapshot *snapshot)
result = gtk_snapshot_pop_internal (snapshot);
/* We should have exactly our initial state */
if (!gtk_snapshot_states_is_empty (&snapshot->state_stack))
if (snapshot->state_stack->len > 0)
{
g_warning ("Too many gtk_snapshot_push() calls. %zu states remaining.",
gtk_snapshot_states_get_size (&snapshot->state_stack));
g_warning ("Too many gtk_snapshot_push() calls. %u states remaining.", snapshot->state_stack->len);
}
gtk_snapshot_states_clear (&snapshot->state_stack);
gtk_snapshot_nodes_clear (&snapshot->nodes);
g_array_free (snapshot->state_stack, TRUE);
g_ptr_array_free (snapshot->nodes, TRUE);
snapshot->state_stack = NULL;
snapshot->nodes = NULL;
return result;
}
+70
View File
@@ -24,6 +24,76 @@
G_BEGIN_DECLS
typedef struct _GtkSnapshotState GtkSnapshotState;
typedef GskRenderNode * (* GtkSnapshotCollectFunc) (GtkSnapshot *snapshot,
GtkSnapshotState *state,
GskRenderNode **nodes,
guint n_nodes);
struct _GtkSnapshotState {
guint start_node_index;
guint n_nodes;
GskTransform * transform;
GtkSnapshotCollectFunc collect_func;
union {
struct {
double opacity;
} opacity;
struct {
double radius;
} blur;
struct {
graphene_matrix_t matrix;
graphene_vec4_t offset;
} color_matrix;
struct {
graphene_rect_t bounds;
graphene_rect_t child_bounds;
} repeat;
struct {
graphene_rect_t bounds;
} clip;
struct {
GskRoundedRect bounds;
} rounded_clip;
struct {
gsize n_shadows;
GskShadow *shadows;
GskShadow a_shadow; /* Used if n_shadows == 1 */
} shadow;
struct {
GskBlendMode blend_mode;
GskRenderNode *bottom_node;
} blend;
struct {
double progress;
GskRenderNode *start_node;
} cross_fade;
struct {
char *message;
} debug;
} data;
};
/* This is a nasty little hack. We typedef GtkSnapshot to the fake object GdkSnapshot
* so that we don't need to typecast between them.
* After all, the GdkSnapshot only exist so poor language bindings don't trip. Hardcore
* C code can just blatantly ignore such layering violations with a typedef.
*/
struct _GdkSnapshot {
GObject parent_instance; /* it's really GdkSnapshot, but don't tell anyone! */
GArray *state_stack;
GPtrArray *nodes;
};
struct _GtkSnapshotClass {
GObjectClass parent_class; /* it's really GdkSnapshotClass, but don't tell anyone! */
};
void gtk_snapshot_append_text (GtkSnapshot *snapshot,
PangoFont *font,
PangoGlyphString *glyphs,
-443
View File
@@ -1,443 +0,0 @@
/*
* Copyright © 2018 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 "gtksor2listmodel.h"
#include "gtkintl.h"
#include "gtkprivate.h"
#define GTK_VECTOR_ELEMENT_TYPE GObject *
#define GTK_VECTOR_TYPE_NAME SortArray
#define GTK_VECTOR_NAME sort_array
#define GTK_VECTOR_FREE_FUNC g_object_unref
#include "gtkvectorimpl.c"
/**
* SECTION:gtksor2listmodel
* @title: GtkSor2ListModel
* @short_description: A list model that sorts its items
* @see_also: #GListModel, #GtkSorter
*
* #GtkSor2ListModel is a list model that takes a list model and
* sorts its elements according to a #GtkSorter.
*
* #GtkSor2ListModel is a generic model and because of that it
* cannot take advantage of any external knowledge when sorting.
* If you run into performance issues with #GtkSor2ListModel, it
* is strongly recommended that you write your own sorting list
* model.
*/
enum {
PROP_0,
PROP_MODEL,
PROP_SORTER,
NUM_PROPERTIES
};
struct _GtkSor2ListModel
{
GObject parent_instance;
GListModel *model;
GtkSorter *sorter;
SortArray items; /* empty if known unsorted */
};
struct _GtkSor2ListModelClass
{
GObjectClass parent_class;
};
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
static GType
gtk_sor2_list_model_get_item_type (GListModel *list)
{
return G_TYPE_OBJECT;
}
static guint
gtk_sor2_list_model_get_n_items (GListModel *list)
{
GtkSor2ListModel *self = GTK_SOR2_LIST_MODEL (list);
if (self->model == NULL)
return 0;
return g_list_model_get_n_items (self->model);
}
static gpointer
gtk_sor2_list_model_get_item (GListModel *list,
guint position)
{
GtkSor2ListModel *self = GTK_SOR2_LIST_MODEL (list);
if (self->model == NULL)
return NULL;
if (sort_array_is_empty (&self->items))
return g_list_model_get_item (self->model, position);
if (position >= sort_array_get_size (&self->items))
return NULL;
return g_object_ref (sort_array_get (&self->items, position));
}
static void
gtk_sor2_list_model_model_init (GListModelInterface *iface)
{
iface->get_item_type = gtk_sor2_list_model_get_item_type;
iface->get_n_items = gtk_sor2_list_model_get_n_items;
iface->get_item = gtk_sor2_list_model_get_item;
}
G_DEFINE_TYPE_WITH_CODE (GtkSor2ListModel, gtk_sor2_list_model, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, gtk_sor2_list_model_model_init))
static void
gtk_sor2_list_model_clear_items (GtkSor2ListModel *self)
{
sort_array_clear (&self->items);
}
static void
gtk_sor2_list_model_create_items (GtkSor2ListModel *self)
{
guint i, n_items;
if (self->sorter == NULL ||
self->model == NULL ||
gtk_sorter_get_order (self->sorter) == GTK_SORTER_ORDER_NONE)
return;
n_items = g_list_model_get_n_items (self->model);
sort_array_reserve (&self->items, n_items);
for (i = 0; i < n_items; i++)
{
sort_array_append (&self->items, g_list_model_get_item (self->model, i));
}
}
static int
sort_func (gconstpointer a,
gconstpointer b,
gpointer data)
{
return gtk_sorter_compare (data, *(GObject **) a, *(GObject **) b);
}
static void
gtk_sor2_list_model_resort (GtkSor2ListModel *self)
{
g_qsort_with_data (sort_array_get_data (&self->items),
sort_array_get_size (&self->items),
sizeof (GObject *),
sort_func,
self->sorter);
}
static void
gtk_sor2_list_model_items_changed_cb (GListModel *model,
guint position,
guint removed,
guint added,
GtkSor2ListModel *self)
{
guint n_items;
/* doesn't free() the array */
sort_array_set_size (&self->items, 0);
gtk_sor2_list_model_create_items (self);
gtk_sor2_list_model_resort (self);
n_items = g_list_model_get_n_items (model);
g_list_model_items_changed (G_LIST_MODEL (self), 0, n_items - added + removed, n_items);
}
static void
gtk_sor2_list_model_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkSor2ListModel *self = GTK_SOR2_LIST_MODEL (object);
switch (prop_id)
{
case PROP_MODEL:
gtk_sor2_list_model_set_model (self, g_value_get_object (value));
break;
case PROP_SORTER:
gtk_sor2_list_model_set_sorter (self, g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_sor2_list_model_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkSor2ListModel *self = GTK_SOR2_LIST_MODEL (object);
switch (prop_id)
{
case PROP_MODEL:
g_value_set_object (value, self->model);
break;
case PROP_SORTER:
g_value_set_object (value, self->sorter);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_sor2_list_model_sorter_changed_cb (GtkSorter *sorter,
int change,
GtkSor2ListModel *self)
{
guint n_items;
if (gtk_sorter_get_order (sorter) == GTK_SORTER_ORDER_NONE)
gtk_sor2_list_model_clear_items (self);
else if (sort_array_is_empty (&self->items))
gtk_sor2_list_model_create_items (self);
gtk_sor2_list_model_resort (self);
n_items = g_list_model_get_n_items (G_LIST_MODEL (self));
if (n_items > 1)
g_list_model_items_changed (G_LIST_MODEL (self), 0, n_items, n_items);
}
static void
gtk_sor2_list_model_clear_model (GtkSor2ListModel *self)
{
if (self->model == NULL)
return;
g_signal_handlers_disconnect_by_func (self->model, gtk_sor2_list_model_items_changed_cb, self);
g_clear_object (&self->model);
gtk_sor2_list_model_clear_items (self);
}
static void
gtk_sor2_list_model_clear_sorter (GtkSor2ListModel *self)
{
if (self->sorter == NULL)
return;
g_signal_handlers_disconnect_by_func (self->sorter, gtk_sor2_list_model_sorter_changed_cb, self);
g_clear_object (&self->sorter);
gtk_sor2_list_model_clear_items (self);
}
static void
gtk_sor2_list_model_dispose (GObject *object)
{
GtkSor2ListModel *self = GTK_SOR2_LIST_MODEL (object);
gtk_sor2_list_model_clear_model (self);
gtk_sor2_list_model_clear_sorter (self);
G_OBJECT_CLASS (gtk_sor2_list_model_parent_class)->dispose (object);
};
static void
gtk_sor2_list_model_class_init (GtkSor2ListModelClass *class)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
gobject_class->set_property = gtk_sor2_list_model_set_property;
gobject_class->get_property = gtk_sor2_list_model_get_property;
gobject_class->dispose = gtk_sor2_list_model_dispose;
/**
* GtkSor2ListModel:sorter:
*
* The sorter for this model
*/
properties[PROP_SORTER] =
g_param_spec_object ("sorter",
P_("Sorter"),
P_("The sorter for this model"),
GTK_TYPE_SORTER,
GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkSor2ListModel:model:
*
* The model being sorted
*/
properties[PROP_MODEL] =
g_param_spec_object ("model",
P_("Model"),
P_("The model being sorted"),
G_TYPE_LIST_MODEL,
GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY);
g_object_class_install_properties (gobject_class, NUM_PROPERTIES, properties);
}
static void
gtk_sor2_list_model_init (GtkSor2ListModel *self)
{
}
/**
* gtk_sor2_list_model_new:
* @model: (allow-none): the model to sort
* @sorter: (allow-none): the #GtkSorter to sort @model with
*
* Creates a new sort list model that uses the @sorter to sort @model.
*
* Returns: a new #GtkSor2ListModel
**/
GtkSor2ListModel *
gtk_sor2_list_model_new (GListModel *model,
GtkSorter *sorter)
{
GtkSor2ListModel *result;
g_return_val_if_fail (model == NULL || G_IS_LIST_MODEL (model), NULL);
g_return_val_if_fail (sorter == NULL || GTK_IS_SORTER (sorter), NULL);
result = g_object_new (GTK_TYPE_SOR2_LIST_MODEL,
"model", model,
"sorter", sorter,
NULL);
return result;
}
/**
* gtk_sor2_list_model_set_model:
* @self: a #GtkSor2ListModel
* @model: (allow-none): The model to be sorted
*
* Sets the model to be sorted. The @model's item type must conform to
* the item type of @self.
**/
void
gtk_sor2_list_model_set_model (GtkSor2ListModel *self,
GListModel *model)
{
guint removed, added;
g_return_if_fail (GTK_IS_SOR2_LIST_MODEL (self));
g_return_if_fail (model == NULL || G_IS_LIST_MODEL (model));
if (self->model == model)
return;
removed = g_list_model_get_n_items (G_LIST_MODEL (self));
gtk_sor2_list_model_clear_model (self);
if (model)
{
self->model = g_object_ref (model);
g_signal_connect (model, "items-changed", G_CALLBACK (gtk_sor2_list_model_items_changed_cb), self);
added = g_list_model_get_n_items (model);
gtk_sor2_list_model_create_items (self);
gtk_sor2_list_model_resort (self);
}
else
added = 0;
if (removed > 0 || added > 0)
g_list_model_items_changed (G_LIST_MODEL (self), 0, removed, added);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MODEL]);
}
/**
* gtk_sor2_list_model_get_model:
* @self: a #GtkSor2ListModel
*
* Gets the model currently sorted or %NULL if none.
*
* Returns: (nullable) (transfer none): The model that gets sorted
**/
GListModel *
gtk_sor2_list_model_get_model (GtkSor2ListModel *self)
{
g_return_val_if_fail (GTK_IS_SOR2_LIST_MODEL (self), NULL);
return self->model;
}
/**
* gtk_sor2_list_model_set_sorter:
* @self: a #GtkSor2ListModel
* @sorter: (allow-none): the #GtkSorter to sort @model with
*
* Sets a new sorter on @self.
*/
void
gtk_sor2_list_model_set_sorter (GtkSor2ListModel *self,
GtkSorter *sorter)
{
g_return_if_fail (GTK_IS_SOR2_LIST_MODEL (self));
g_return_if_fail (sorter == NULL || GTK_IS_SORTER (sorter));
gtk_sor2_list_model_clear_sorter (self);
if (sorter)
{
self->sorter = g_object_ref (sorter);
g_signal_connect (sorter, "changed", G_CALLBACK (gtk_sor2_list_model_sorter_changed_cb), self);
gtk_sor2_list_model_sorter_changed_cb (sorter, GTK_SORTER_CHANGE_DIFFERENT, self);
}
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SORTER]);
}
/**
* gtk_sor2_list_model_get_sorter:
* @self: a #GtkSor2LisTModel
*
* Gets the sorter that is used to sort @self.
*
* Returns: (nullable) (transfer none): the sorter of #self
*/
GtkSorter *
gtk_sor2_list_model_get_sorter (GtkSor2ListModel *self)
{
g_return_val_if_fail (GTK_IS_SOR2_LIST_MODEL (self), NULL);
return self->sorter;
}
-57
View File
@@ -1,57 +0,0 @@
/*
* Copyright © 2018 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_SOR2_LIST_MODEL_H__
#define __GTK_SOR2_LIST_MODEL_H__
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gtk/gtk.h> can be included directly."
#endif
#include <gio/gio.h>
#include <gtk/gtkwidget.h>
#include <gtk/gtksorter.h>
G_BEGIN_DECLS
#define GTK_TYPE_SOR2_LIST_MODEL (gtk_sor2_list_model_get_type ())
GDK_AVAILABLE_IN_ALL
G_DECLARE_FINAL_TYPE (GtkSor2ListModel, gtk_sor2_list_model, GTK, SOR2_LIST_MODEL, GObject)
GDK_AVAILABLE_IN_ALL
GtkSor2ListModel * gtk_sor2_list_model_new (GListModel *model,
GtkSorter *sorter);
GDK_AVAILABLE_IN_ALL
void gtk_sor2_list_model_set_sorter (GtkSor2ListModel *self,
GtkSorter *sorter);
GDK_AVAILABLE_IN_ALL
GtkSorter * gtk_sor2_list_model_get_sorter (GtkSor2ListModel *self);
GDK_AVAILABLE_IN_ALL
void gtk_sor2_list_model_set_model (GtkSor2ListModel *self,
GListModel *model);
GDK_AVAILABLE_IN_ALL
GListModel * gtk_sor2_list_model_get_model (GtkSor2ListModel *self);
G_END_DECLS
#endif /* __GTK_SOR2_LIST_MODEL_H__ */
-604
View File
@@ -1,604 +0,0 @@
/*
* Copyright © 2018 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 "gtksor3listmodel.h"
#include "gtkintl.h"
#include "gtkprivate.h"
#define GTK_VECTOR_ELEMENT_TYPE GObject *
#define GTK_VECTOR_TYPE_NAME SortArray
#define GTK_VECTOR_NAME sort_array
#define GTK_VECTOR_FREE_FUNC g_object_unref
#define GTK_VECTOR_PREALLOC 16
#include "gtkvectorimpl.c"
#undef GTK_VECTOR_ELEMENT_TYPE
#undef GTK_VECTOR_TYPE_NAME
#undef GTK_VECTOR_NAME
#undef GTK_VECTOR_FREE_FUNC
#undef GTK_VECTOR_PREALLOC
#define GTK_VECTOR_ELEMENT_TYPE guint
#define GTK_VECTOR_TYPE_NAME PivotStack
#define GTK_VECTOR_NAME pivot_stack
#define GTK_VECTOR_BY_VALUE
#define GTK_VECTOR_PREALLOC 16
#include "gtkvectorimpl.c"
#undef GTK_VECTOR_ELEMENT_TYPE
#undef GTK_VECTOR_TYPE_NAME
#undef GTK_VECTOR_NAME
#undef GTK_VECTOR_BY_VALUE
#undef GTK_VECTOR_FREE_FUNC
#undef GTK_VECTOR_PREALLOC
static inline void
pivot_stack_push (PivotStack *stack,
guint pos)
{
gsize size = pivot_stack_get_size (stack);
pivot_stack_set_size (stack, size + 1);
*pivot_stack_get (stack, size) = pos;
}
static inline guint
pivot_stack_top (PivotStack *stack)
{
return *pivot_stack_get (stack, pivot_stack_get_size (stack) - 1);
}
static inline guint
pivot_stack_pop (PivotStack *stack)
{
gsize size = pivot_stack_get_size (stack);
guint top = *pivot_stack_get (stack, size - 1);
pivot_stack_set_size (stack, size - 1);
return top;
}
/**
* SECTION:gtksor3listmodel
* @title: GtkSor3ListModel
* @short_description: A list model that sorts its items
* @see_also: #GListModel, #GtkSorter
*
* #GtkSor3ListModel is a list model that takes a list model and
* sorts its elements according to a #GtkSorter.
*
* #GtkSor3ListModel is a generic model and because of that it
* cannot take advantage of any external knowledge when sorting.
* If you run into performance issues with #GtkSor3ListModel, it
* is strongly recommended that you write your own sorting list
* model.
*/
enum {
PROP_0,
PROP_MODEL,
PROP_SORTER,
NUM_PROPERTIES
};
struct _GtkSor3ListModel
{
GObject parent_instance;
GListModel *model;
GtkSorter *sorter;
SortArray items; /* empty if known unsorted */
guint sorting_cb;
guint sorted_to;
PivotStack stack;
};
struct _GtkSor3ListModelClass
{
GObjectClass parent_class;
};
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
static GType
gtk_sor3_list_model_get_item_type (GListModel *list)
{
return G_TYPE_OBJECT;
}
static guint
gtk_sor3_list_model_get_n_items (GListModel *list)
{
GtkSor3ListModel *self = GTK_SOR3_LIST_MODEL (list);
if (self->model == NULL)
return 0;
return g_list_model_get_n_items (self->model);
}
static gpointer
gtk_sor3_list_model_get_item (GListModel *list,
guint position)
{
GtkSor3ListModel *self = GTK_SOR3_LIST_MODEL (list);
if (self->model == NULL)
return NULL;
if (sort_array_is_empty (&self->items))
return g_list_model_get_item (self->model, position);
if (position >= sort_array_get_size (&self->items))
return NULL;
return g_object_ref (sort_array_get (&self->items, position));
}
static void
gtk_sor3_list_model_model_init (GListModelInterface *iface)
{
iface->get_item_type = gtk_sor3_list_model_get_item_type;
iface->get_n_items = gtk_sor3_list_model_get_n_items;
iface->get_item = gtk_sor3_list_model_get_item;
}
G_DEFINE_TYPE_WITH_CODE (GtkSor3ListModel, gtk_sor3_list_model, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, gtk_sor3_list_model_model_init))
static void
gtk_sor3_list_model_clear_items (GtkSor3ListModel *self)
{
sort_array_clear (&self->items);
}
static void
gtk_sor3_list_model_create_items (GtkSor3ListModel *self)
{
guint i, n_items;
if (self->sorter == NULL ||
self->model == NULL ||
gtk_sorter_get_order (self->sorter) == GTK_SORTER_ORDER_NONE)
return;
n_items = g_list_model_get_n_items (self->model);
sort_array_reserve (&self->items, n_items);
for (i = 0; i < n_items; i++)
sort_array_append (&self->items, g_list_model_get_item (self->model, i));
}
static void
gtk_sor3_list_model_stop_sorting (GtkSor3ListModel *self)
{
g_clear_handle_id (&self->sorting_cb, g_source_remove);
pivot_stack_set_size (&self->stack, 0);
}
static inline int
compare (GtkSorter *sorter, GObject *a, GObject *b)
{
return gtk_sorter_compare (sorter, a, b);
}
static inline void
swap (SortArray *items, guint i, guint j)
{
GObject *tmp = sort_array_get (items, i);
*sort_array_index (items, i) = sort_array_get (items, j);
*sort_array_index (items, j) = tmp;
}
/* This is pretty much the incremental quicksort that is described
* in the wikipedia article about it. Calling iqs repeatedly for
* each position from 0..k gives you that k smallest elements, in
* order. Which is what we do. As a side-effect, the array ends up
* getting sorted. The nice thing is that we simply remember how
* far we've enumerated (in sorted_to), and interrupt the sorting,
* which is the incremental part.
*/
static guint
partition (SortArray *items, guint first, guint end, GtkSorter *sorter)
{
guint mid;
guint i, j;
GObject *pivot;
mid = first + (end - first) / 2;
if (compare (sorter, sort_array_get (items, mid),
sort_array_get (items, first)) < 0)
swap (items, mid, first);
if (compare (sorter, sort_array_get (items, end),
sort_array_get (items, first)) < 0)
swap (items, end, first);
if (compare (sorter, sort_array_get (items, mid),
sort_array_get (items, end)) < 0)
swap (items, mid, end);
pivot = sort_array_get (items, end);
i = first;
j = end;
while (1)
{
while (compare (sorter, sort_array_get (items, i), pivot) < 0) i++;
while (j > i && compare (sorter, sort_array_get (items, j), pivot) >= 0) j--;
if (i >= j) return j;
swap (items, i, j);
}
return j;
}
static gpointer
iqs (SortArray *items, guint pos, PivotStack *stack, GtkSorter *sorter)
{
guint top;
guint pivot;
top = pivot_stack_top (stack);
if (top == pos)
{
pivot_stack_pop (stack);
return sort_array_get (items, pos);
}
pivot = partition (items, pos, top, sorter);
pivot_stack_push (stack, pivot);
return iqs (items, pos, stack, sorter);
}
static gboolean
gtk_sor3_list_model_sort_cb (gpointer data)
{
GtkSor3ListModel *self = GTK_SOR3_LIST_MODEL (data);
guint start;
guint end;
guint n_items;
guint i;
start = self->sorted_to;
n_items = sort_array_get_size (&self->items);
end = MIN (512, n_items - start);
for (i = 0; i < end; i++)
{
iqs (&self->items, self->sorted_to, &self->stack, self->sorter);
self->sorted_to++;
}
if (self->sorted_to >= n_items)
gtk_sor3_list_model_stop_sorting (self);
g_list_model_items_changed (G_LIST_MODEL (self), start, n_items - start, n_items - start);
return G_SOURCE_CONTINUE;
}
static void
gtk_sor3_list_model_start_sorting (GtkSor3ListModel *self)
{
if (sort_array_get_size (&self->items) == 0)
return;
g_assert (pivot_stack_get_size (&self->stack) == 0);
g_assert (self->sorting_cb == 0);
pivot_stack_push (&self->stack, (guint)sort_array_get_size (&self->items) - 1);
self->sorted_to = 0;
self->sorting_cb = g_idle_add (gtk_sor3_list_model_sort_cb, self);
g_source_set_name_by_id (self->sorting_cb, "[gtk] gtk_sor3_list_model_sort_cb");
}
static void
gtk_sor3_list_model_resort (GtkSor3ListModel *self)
{
gtk_sor3_list_model_stop_sorting (self);
gtk_sor3_list_model_start_sorting (self);
}
static void
gtk_sor3_list_model_items_changed_cb (GListModel *model,
guint position,
guint removed,
guint added,
GtkSor3ListModel *self)
{
guint n_items;
/* doesn't free() the array */
sort_array_set_size (&self->items, 0);
gtk_sor3_list_model_create_items (self);
gtk_sor3_list_model_resort (self);
n_items = g_list_model_get_n_items (model);
g_list_model_items_changed (G_LIST_MODEL (self), 0, n_items - added + removed, n_items);
}
static void
gtk_sor3_list_model_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkSor3ListModel *self = GTK_SOR3_LIST_MODEL (object);
switch (prop_id)
{
case PROP_MODEL:
gtk_sor3_list_model_set_model (self, g_value_get_object (value));
break;
case PROP_SORTER:
gtk_sor3_list_model_set_sorter (self, g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_sor3_list_model_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkSor3ListModel *self = GTK_SOR3_LIST_MODEL (object);
switch (prop_id)
{
case PROP_MODEL:
g_value_set_object (value, self->model);
break;
case PROP_SORTER:
g_value_set_object (value, self->sorter);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_sor3_list_model_sorter_changed_cb (GtkSorter *sorter,
int change,
GtkSor3ListModel *self)
{
guint n_items;
if (gtk_sorter_get_order (sorter) == GTK_SORTER_ORDER_NONE)
gtk_sor3_list_model_clear_items (self);
else if (sort_array_is_empty (&self->items))
gtk_sor3_list_model_create_items (self);
gtk_sor3_list_model_resort (self);
n_items = g_list_model_get_n_items (G_LIST_MODEL (self));
if (n_items > 1)
g_list_model_items_changed (G_LIST_MODEL (self), 0, n_items, n_items);
}
static void
gtk_sor3_list_model_clear_model (GtkSor3ListModel *self)
{
if (self->model == NULL)
return;
g_signal_handlers_disconnect_by_func (self->model, gtk_sor3_list_model_items_changed_cb, self);
g_clear_object (&self->model);
gtk_sor3_list_model_stop_sorting (self);
gtk_sor3_list_model_clear_items (self);
}
static void
gtk_sor3_list_model_clear_sorter (GtkSor3ListModel *self)
{
if (self->sorter == NULL)
return;
g_signal_handlers_disconnect_by_func (self->sorter, gtk_sor3_list_model_sorter_changed_cb, self);
g_clear_object (&self->sorter);
gtk_sor3_list_model_stop_sorting (self);
gtk_sor3_list_model_clear_items (self);
}
static void
gtk_sor3_list_model_dispose (GObject *object)
{
GtkSor3ListModel *self = GTK_SOR3_LIST_MODEL (object);
gtk_sor3_list_model_stop_sorting (self);
gtk_sor3_list_model_clear_model (self);
gtk_sor3_list_model_clear_sorter (self);
G_OBJECT_CLASS (gtk_sor3_list_model_parent_class)->dispose (object);
};
static void
gtk_sor3_list_model_class_init (GtkSor3ListModelClass *class)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
gobject_class->set_property = gtk_sor3_list_model_set_property;
gobject_class->get_property = gtk_sor3_list_model_get_property;
gobject_class->dispose = gtk_sor3_list_model_dispose;
/**
* GtkSor3ListModel:sorter:
*
* The sorter for this model
*/
properties[PROP_SORTER] =
g_param_spec_object ("sorter",
P_("Sorter"),
P_("The sorter for this model"),
GTK_TYPE_SORTER,
GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkSor3ListModel:model:
*
* The model being sorted
*/
properties[PROP_MODEL] =
g_param_spec_object ("model",
P_("Model"),
P_("The model being sorted"),
G_TYPE_LIST_MODEL,
GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY);
g_object_class_install_properties (gobject_class, NUM_PROPERTIES, properties);
}
static void
gtk_sor3_list_model_init (GtkSor3ListModel *self)
{
}
/**
* gtk_sor3_list_model_new:
* @model: (allow-none): the model to sort
* @sorter: (allow-none): the #GtkSorter to sort @model with
*
* Creates a new sort list model that uses the @sorter to sort @model.
*
* Returns: a new #GtkSor3ListModel
**/
GtkSor3ListModel *
gtk_sor3_list_model_new (GListModel *model,
GtkSorter *sorter)
{
GtkSor3ListModel *result;
g_return_val_if_fail (model == NULL || G_IS_LIST_MODEL (model), NULL);
g_return_val_if_fail (sorter == NULL || GTK_IS_SORTER (sorter), NULL);
result = g_object_new (GTK_TYPE_SOR3_LIST_MODEL,
"model", model,
"sorter", sorter,
NULL);
return result;
}
/**
* gtk_sor3_list_model_set_model:
* @self: a #GtkSor3ListModel
* @model: (allow-none): The model to be sorted
*
* Sets the model to be sorted. The @model's item type must conform to
* the item type of @self.
**/
void
gtk_sor3_list_model_set_model (GtkSor3ListModel *self,
GListModel *model)
{
guint removed, added;
g_return_if_fail (GTK_IS_SOR3_LIST_MODEL (self));
g_return_if_fail (model == NULL || G_IS_LIST_MODEL (model));
if (self->model == model)
return;
removed = g_list_model_get_n_items (G_LIST_MODEL (self));
gtk_sor3_list_model_clear_model (self);
if (model)
{
self->model = g_object_ref (model);
g_signal_connect (model, "items-changed", G_CALLBACK (gtk_sor3_list_model_items_changed_cb), self);
added = g_list_model_get_n_items (model);
gtk_sor3_list_model_create_items (self);
gtk_sor3_list_model_resort (self);
}
else
added = 0;
if (removed > 0 || added > 0)
g_list_model_items_changed (G_LIST_MODEL (self), 0, removed, added);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MODEL]);
}
/**
* gtk_sor3_list_model_get_model:
* @self: a #GtkSor3ListModel
*
* Gets the model currently sorted or %NULL if none.
*
* Returns: (nullable) (transfer none): The model that gets sorted
**/
GListModel *
gtk_sor3_list_model_get_model (GtkSor3ListModel *self)
{
g_return_val_if_fail (GTK_IS_SOR3_LIST_MODEL (self), NULL);
return self->model;
}
/**
* gtk_sor3_list_model_set_sorter:
* @self: a #GtkSor3ListModel
* @sorter: (allow-none): the #GtkSorter to sort @model with
*
* Sets a new sorter on @self.
*/
void
gtk_sor3_list_model_set_sorter (GtkSor3ListModel *self,
GtkSorter *sorter)
{
g_return_if_fail (GTK_IS_SOR3_LIST_MODEL (self));
g_return_if_fail (sorter == NULL || GTK_IS_SORTER (sorter));
gtk_sor3_list_model_clear_sorter (self);
if (sorter)
{
self->sorter = g_object_ref (sorter);
g_signal_connect (sorter, "changed", G_CALLBACK (gtk_sor3_list_model_sorter_changed_cb), self);
gtk_sor3_list_model_sorter_changed_cb (sorter, GTK_SORTER_CHANGE_DIFFERENT, self);
}
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SORTER]);
}
/**
* gtk_sor3_list_model_get_sorter:
* @self: a #GtkSor3LisTModel
*
* Gets the sorter that is used to sort @self.
*
* Returns: (nullable) (transfer none): the sorter of #self
*/
GtkSorter *
gtk_sor3_list_model_get_sorter (GtkSor3ListModel *self)
{
g_return_val_if_fail (GTK_IS_SOR3_LIST_MODEL (self), NULL);
return self->sorter;
}
-57
View File
@@ -1,57 +0,0 @@
/*
* Copyright © 2018 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_SOR3_LIST_MODEL_H__
#define __GTK_SOR3_LIST_MODEL_H__
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gtk/gtk.h> can be included directly."
#endif
#include <gio/gio.h>
#include <gtk/gtkwidget.h>
#include <gtk/gtksorter.h>
G_BEGIN_DECLS
#define GTK_TYPE_SOR3_LIST_MODEL (gtk_sor3_list_model_get_type ())
GDK_AVAILABLE_IN_ALL
G_DECLARE_FINAL_TYPE (GtkSor3ListModel, gtk_sor3_list_model, GTK, SOR3_LIST_MODEL, GObject)
GDK_AVAILABLE_IN_ALL
GtkSor3ListModel * gtk_sor3_list_model_new (GListModel *model,
GtkSorter *sorter);
GDK_AVAILABLE_IN_ALL
void gtk_sor3_list_model_set_sorter (GtkSor3ListModel *self,
GtkSorter *sorter);
GDK_AVAILABLE_IN_ALL
GtkSorter * gtk_sor3_list_model_get_sorter (GtkSor3ListModel *self);
GDK_AVAILABLE_IN_ALL
void gtk_sor3_list_model_set_model (GtkSor3ListModel *self,
GListModel *model);
GDK_AVAILABLE_IN_ALL
GListModel * gtk_sor3_list_model_get_model (GtkSor3ListModel *self);
G_END_DECLS
#endif /* __GTK_SOR3_LIST_MODEL_H__ */
+1 -2
View File
@@ -142,8 +142,7 @@ gtk_sorter_compare (GtkSorter *self,
{
GtkOrdering result;
/* We turn this off because gtk_sorter_compare() is called so much that it's too expensive */
/* g_return_val_if_fail (GTK_IS_SORTER (self), GTK_ORDERING_EQUAL); */
g_return_val_if_fail (GTK_IS_SORTER (self), GTK_ORDERING_EQUAL);
g_return_val_if_fail (item1 && item2, GTK_ORDERING_EQUAL);
if (item1 == item2)
+52 -3
View File
@@ -42,6 +42,7 @@
enum {
PROP_0,
PROP_ITEM_TYPE,
PROP_MODEL,
PROP_SORTER,
NUM_PROPERTIES
@@ -53,6 +54,7 @@ struct _GtkSortListModel
{
GObject parent_instance;
GType item_type;
GListModel *model;
GtkSorter *sorter;
@@ -87,7 +89,9 @@ gtk_sort_list_entry_free (gpointer data)
static GType
gtk_sort_list_model_get_item_type (GListModel *list)
{
return G_TYPE_OBJECT;
GtkSortListModel *self = GTK_SORT_LIST_MODEL (list);
return self->item_type;
}
static guint
@@ -258,6 +262,10 @@ gtk_sort_list_model_set_property (GObject *object,
switch (prop_id)
{
case PROP_ITEM_TYPE:
self->item_type = g_value_get_gtype (value);
break;
case PROP_MODEL:
gtk_sort_list_model_set_model (self, g_value_get_object (value));
break;
@@ -282,6 +290,10 @@ gtk_sort_list_model_get_property (GObject *object,
switch (prop_id)
{
case PROP_ITEM_TYPE:
g_value_set_gtype (value, self->item_type);
break;
case PROP_MODEL:
g_value_set_object (value, self->model);
break;
@@ -393,6 +405,18 @@ gtk_sort_list_model_class_init (GtkSortListModelClass *class)
GTK_TYPE_SORTER,
GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkSortListModel:item-type:
*
* The #GType for items of this model
*/
properties[PROP_ITEM_TYPE] =
g_param_spec_gtype ("item-type",
P_("Item type"),
P_("The type of items of this list"),
G_TYPE_OBJECT,
GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkSortListModel:model:
*
@@ -415,7 +439,7 @@ gtk_sort_list_model_init (GtkSortListModel *self)
/**
* gtk_sort_list_model_new:
* @model: (allow-none): the model to sort
* @model: the model to sort
* @sorter: (allow-none): the #GtkSorter to sort @model with
*
* Creates a new sort list model that uses the @sorter to sort @model.
@@ -428,10 +452,11 @@ gtk_sort_list_model_new (GListModel *model,
{
GtkSortListModel *result;
g_return_val_if_fail (model == NULL || G_IS_LIST_MODEL (model), NULL);
g_return_val_if_fail (G_IS_LIST_MODEL (model), NULL);
g_return_val_if_fail (sorter == NULL || GTK_IS_SORTER (sorter), NULL);
result = g_object_new (GTK_TYPE_SORT_LIST_MODEL,
"item-type", g_list_model_get_item_type (model),
"model", model,
"sorter", sorter,
NULL);
@@ -439,6 +464,26 @@ gtk_sort_list_model_new (GListModel *model,
return result;
}
/**
* gtk_sort_list_model_new_for_type:
* @item_type: the type of the items that will be returned
*
* Creates a new empty sort list model set up to return items of type @item_type.
* It is up to the application to set a proper sort function and model to ensure
* the item type is matched.
*
* Returns: a new #GtkSortListModel
**/
GtkSortListModel *
gtk_sort_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_SORT_LIST_MODEL,
"item-type", item_type,
NULL);
}
/**
* gtk_sort_list_model_set_model:
* @self: a #GtkSortListModel
@@ -455,6 +500,10 @@ gtk_sort_list_model_set_model (GtkSortListModel *self,
g_return_if_fail (GTK_IS_SORT_LIST_MODEL (self));
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), self->item_type));
}
if (self->model == model)
return;
+3
View File
@@ -40,6 +40,9 @@ G_DECLARE_FINAL_TYPE (GtkSortListModel, gtk_sort_list_model, GTK, SORT_LIST_MODE
GDK_AVAILABLE_IN_ALL
GtkSortListModel * gtk_sort_list_model_new (GListModel *model,
GtkSorter *sorter);
GDK_AVAILABLE_IN_ALL
GtkSortListModel * gtk_sort_list_model_new_for_type (GType item_type);
GDK_AVAILABLE_IN_ALL
void gtk_sort_list_model_set_sorter (GtkSortListModel *self,
GtkSorter *sorter);
+2 -2
View File
@@ -110,9 +110,9 @@ gtk_string_filter_match (GtkFilter *filter,
!gtk_expression_evaluate (self->expression, item, &value))
return FALSE;
s = g_value_get_string (&value);
prepared = gtk_string_filter_prepare (self, s);
if (prepared == NULL)
if (s == NULL)
return FALSE;
prepared = gtk_string_filter_prepare (self, s);
switch (self->match_mode)
{
+30 -34
View File
@@ -138,13 +138,20 @@ gtk_string_object_class_init (GtkStringObjectClass *class)
pspec = g_param_spec_string ("string", "String", "String",
NULL,
G_PARAM_READABLE |
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_STRING, pspec);
}
static GtkStringObject *
gtk_string_object_new (const char *string)
{
return g_object_new (GTK_TYPE_STRING_OBJECT, "string", string, NULL);
}
static GtkStringObject *
gtk_string_object_new_take (char *string)
{
@@ -156,20 +163,6 @@ gtk_string_object_new_take (char *string)
return obj;
}
/**
* gtk_string_object_new:
* @string: (non-nullable): The string to wrap
*
* Wraps a string in an object for use with #GListModel
*
* Returns: a new #GtkStringObject
**/
GtkStringObject *
gtk_string_object_new (const char *string)
{
return gtk_string_object_new_take (g_strdup (string));
}
/**
* gtk_string_object_get_string:
* @self: a #GtkStringObject
@@ -439,13 +432,15 @@ gtk_string_list_init (GtkStringList *self)
* Returns: a new #GtkStringList
*/
GtkStringList *
gtk_string_list_new (const char * const *strings)
gtk_string_list_new (const char **strings)
{
GtkStringList *self;
guint i;
self = g_object_new (GTK_TYPE_STRING_LIST, NULL);
gtk_string_list_splice (self, 0, 0, strings);
for (i = 0; strings[i]; i++)
g_sequence_append (self->items, gtk_string_object_new (strings[i]));
return self;
}
@@ -455,10 +450,11 @@ gtk_string_list_new (const char * const *strings)
* @self: a #GtkStringList
* @position: the position at which to make the change
* @n_removals: the number of strings to remove
* @additions: (array zero-terminated=1) (nullable): The strings to add
* @additions: (array length=n_additions): the strings to add
* @n_additions: the number of items to add
*
* Changes @self by removing @n_removals strings and adding @additions
* to it.
* Changes @self by removing @n_removals strings and adding @n_additions
* strings to it.
*
* This function is more efficient than gtk_string_list_insert() and
* gtk_string_list_remove(), because it only emits
@@ -471,13 +467,14 @@ gtk_string_list_new (const char * const *strings)
* of the list at the time this function is called).
*/
void
gtk_string_list_splice (GtkStringList *self,
guint position,
guint n_removals,
const char * const *additions)
gtk_string_list_splice (GtkStringList *self,
guint position,
guint n_removals,
const char **additions,
guint n_additions)
{
GSequenceIter *it;
guint add, n_items;
guint n_items;
g_return_if_fail (GTK_IS_STRING_LIST (self));
g_return_if_fail (position + n_removals >= position); /* overflow */
@@ -497,18 +494,17 @@ gtk_string_list_splice (GtkStringList *self,
it = end;
}
if (additions)
if (n_additions)
{
for (add = 0; additions[add]; add++)
gint i;
for (i = 0; i < n_additions; i++)
{
g_sequence_insert_before (it, gtk_string_object_new (additions[add]));
g_sequence_insert_before (it, gtk_string_object_new (additions[i]));
}
}
else
add = 0;
if (n_removals || add)
g_list_model_items_changed (G_LIST_MODEL (self), position, n_removals, add);
g_list_model_items_changed (G_LIST_MODEL (self), position, n_removals, n_additions);
}
/**
@@ -593,8 +589,8 @@ gtk_string_list_remove (GtkStringList *self,
* @self: a #GtkStringList
* @position: the position to get the string for
*
* Gets the string that is at @position in @self. If @self
* does not contain @position items, %NULL is returned.
* Gets the string that is at @position in @self. @position
* must be smaller than the current length of the list.
*
* This function returns the const char *. To get the
* object wrapping it, use g_list_model_get_item().
+15 -16
View File
@@ -37,9 +37,7 @@ GDK_AVAILABLE_IN_ALL
G_DECLARE_FINAL_TYPE (GtkStringObject, gtk_string_object, GTK, STRING_OBJECT, GObject)
GDK_AVAILABLE_IN_ALL
GtkStringObject * gtk_string_object_new (const char *string);
GDK_AVAILABLE_IN_ALL
const char * gtk_string_object_get_string (GtkStringObject *self);
const char * gtk_string_object_get_string (GtkStringObject *self);
#define GTK_TYPE_STRING_LIST (gtk_string_list_get_type ())
@@ -47,29 +45,30 @@ GDK_AVAILABLE_IN_ALL
G_DECLARE_FINAL_TYPE (GtkStringList, gtk_string_list, GTK, STRING_LIST, GObject)
GDK_AVAILABLE_IN_ALL
GtkStringList * gtk_string_list_new (const char * const *strings);
GtkStringList * gtk_string_list_new (const char **strings);
GDK_AVAILABLE_IN_ALL
void gtk_string_list_append (GtkStringList *self,
const char *string);
void gtk_string_list_append (GtkStringList *self,
const char *string);
GDK_AVAILABLE_IN_ALL
void gtk_string_list_take (GtkStringList *self,
char *string);
void gtk_string_list_take (GtkStringList *self,
char *string);
GDK_AVAILABLE_IN_ALL
void gtk_string_list_remove (GtkStringList *self,
guint position);
void gtk_string_list_remove (GtkStringList *self,
guint position);
GDK_AVAILABLE_IN_ALL
void gtk_string_list_splice (GtkStringList *self,
guint position,
guint n_removals,
const char * const *additions);
void gtk_string_list_splice (GtkStringList *self,
guint position,
guint n_removals,
const char **additions,
guint n_additions);
GDK_AVAILABLE_IN_ALL
const char * gtk_string_list_get_string (GtkStringList *self,
guint position);
const char * gtk_string_list_get_string (GtkStringList *self,
guint position);
G_END_DECLS
+11 -1
View File
@@ -533,6 +533,16 @@ gtk_tree_list_model_expand_node (GtkTreeListModel *self,
if (model == NULL)
return 0;
if (!g_type_is_a (g_list_model_get_item_type (model), g_list_model_get_item_type (self->root_node.model)))
{
g_critical ("The GtkTreeListModelCreateModelFunc for %p returned a model with item type \"%s\" "
"but \"%s\" is required.",
self,
g_type_name (g_list_model_get_item_type (model)),
g_type_name (g_list_model_get_item_type (self->root_node.model)));
return 0;
}
gtk_tree_list_model_init_node (self, node, model);
tree_node_mark_dirty (node);
@@ -566,7 +576,7 @@ gtk_tree_list_model_get_item_type (GListModel *list)
GtkTreeListModel *self = GTK_TREE_LIST_MODEL (list);
if (self->passthrough)
return G_TYPE_OBJECT;
return g_list_model_get_item_type (self->root_node.model);
else
return GTK_TYPE_TREE_LIST_ROW;
}
-283
View File
@@ -1,283 +0,0 @@
/*
* Copyright © 2020 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 <glib.h>
G_BEGIN_DECLS
#ifndef GTK_VECTOR_TYPE_NAME
#define GTK_VECTOR_TYPE_NAME GtkVector
#endif
#ifndef GTK_VECTOR_NAME
#define GTK_VECTOR_NAME gtk_vector
#endif
#ifndef GTK_VECTOR_ELEMENT_TYPE
#define GTK_VECTOR_ELEMENT_TYPE gpointer
#endif
#ifdef GTK_VECTOR_PREALLOC
#if GTK_VECTOR_PREALLOC == 0
#undef GTK_VECTOR_PREALLOC
#endif
#endif
#ifdef GTK_VECTOR_NULL_TERMINATED
#define GTK_VECTOR_REAL_SIZE(_size) ((_size) + 1)
#else
#define GTK_VECTOR_REAL_SIZE(_size) (_size)
#endif
/* make this readable */
#define _T_ GTK_VECTOR_ELEMENT_TYPE
#define GtkVector GTK_VECTOR_TYPE_NAME
#define gtk_vector_paste_more(GTK_VECTOR_NAME, func_name) GTK_VECTOR_NAME ## _ ## func_name
#define gtk_vector_paste(GTK_VECTOR_NAME, func_name) gtk_vector_paste_more (GTK_VECTOR_NAME, func_name)
#define gtk_vector(func_name) gtk_vector_paste (GTK_VECTOR_NAME, func_name)
typedef struct GtkVector GtkVector;
struct GtkVector
{
_T_ *start;
_T_ *end;
_T_ *end_allocation;
#ifdef GTK_VECTOR_PREALLOC
_T_ preallocated[GTK_VECTOR_REAL_SIZE(GTK_VECTOR_PREALLOC)];
#endif
};
/* no G_GNUC_UNUSED here, if you don't use an array type, remove it. */
static inline void
gtk_vector(init) (GtkVector *self)
{
#ifdef GTK_VECTOR_PREALLOC
self->start = self->preallocated;
self->end = self->start;
self->end_allocation = self->start + GTK_VECTOR_PREALLOC;
#ifdef GTK_VECTOR_NULL_TERMINATED
*self->start = *(_T_[1]) {};
#endif
#else
self->start = NULL;
self->end = NULL;
self->end_allocation = NULL;
#endif
}
static inline void
gtk_vector(free_elements) (_T_ *start,
_T_ *end)
{
#ifdef GTK_VECTOR_FREE_FUNC
_T_ *e;
for (e = start; e < end; e++)
#ifdef GTK_VECTOR_BY_VALUE
GTK_VECTOR_FREE_FUNC (e);
#else
GTK_VECTOR_FREE_FUNC (*e);
#endif
#endif
}
/* no G_GNUC_UNUSED here */
static inline void
gtk_vector(clear) (GtkVector *self)
{
gtk_vector(free_elements) (self->start, self->end);
#ifdef GTK_VECTOR_PREALLOC
if (self->start != self->preallocated)
g_free (self->start);
#endif
gtk_vector(init) (self);
}
G_GNUC_UNUSED static inline _T_ *
gtk_vector(get_data) (const GtkVector *self)
{
return self->start;
}
G_GNUC_UNUSED static inline _T_ *
gtk_vector(index) (const GtkVector *self,
gsize pos)
{
return self->start + pos;
}
G_GNUC_UNUSED static inline gsize
gtk_vector(get_capacity) (const GtkVector *self)
{
return self->end_allocation - self->start;
}
G_GNUC_UNUSED static inline gsize
gtk_vector(get_size) (const GtkVector *self)
{
return self->end - self->start;
}
G_GNUC_UNUSED static inline gboolean
gtk_vector(is_empty) (const GtkVector *self)
{
return self->end == self->start;
}
G_GNUC_UNUSED static void
gtk_vector(reserve) (GtkVector *self,
gsize n)
{
gsize new_size, size;
if (n <= gtk_vector(get_capacity) (self))
return;
size = gtk_vector(get_size) (self);
new_size = 1 << g_bit_storage (MAX (GTK_VECTOR_REAL_SIZE (n), 16) - 1);
#ifdef GTK_VECTOR_PREALLOC
if (self->start == self->preallocated)
{
self->start = g_new (_T_, new_size);
memcpy (self->start, self->preallocated, sizeof (_T_) * GTK_VECTOR_REAL_SIZE (size));
}
else
#endif
#ifdef GTK_VECTOR_NULL_TERMINATED
if (self->start == NULL)
{
self->start = g_new (_T_, new_size);
*self->start = *(_T_[1]) {};
}
else
#endif
self->start = g_renew (_T_, self->start, new_size);
self->end = self->start + size;
self->end_allocation = self->start + new_size;
#ifdef GTK_VECTOR_NULL_TERMINATED
self->end_allocation--;
#endif
}
G_GNUC_UNUSED static void
gtk_vector(splice) (GtkVector *self,
gsize pos,
gsize removed,
_T_ *additions,
gsize added)
{
gsize size;
gsize remaining;
size = gtk_vector(get_size) (self);
g_assert (pos + removed <= size);
remaining = size - pos - removed;
gtk_vector(free_elements) (gtk_vector(index) (self, pos),
gtk_vector(index) (self, pos + removed));
gtk_vector(reserve) (self, size - removed + added);
if (GTK_VECTOR_REAL_SIZE (remaining) && removed != added)
memmove (gtk_vector(index) (self, pos + added),
gtk_vector(index) (self, pos + removed),
GTK_VECTOR_REAL_SIZE (remaining) * sizeof (_T_));
if (added)
{
if (additions)
memcpy (gtk_vector(index) (self, pos),
additions,
added * sizeof (_T_));
else
memset (gtk_vector(index) (self, pos), 0, added * sizeof (_T_));
}
/* might overflow, but does the right thing */
self->end += added - removed;
}
G_GNUC_UNUSED static void
gtk_vector(set_size) (GtkVector *self,
gsize new_size)
{
gsize old_size = gtk_vector(get_size) (self);
if (new_size > old_size)
gtk_vector(splice) (self, old_size, 0, NULL, new_size - old_size);
else
gtk_vector(splice) (self, new_size, old_size - new_size, NULL, 0);
}
G_GNUC_UNUSED static void
gtk_vector(append) (GtkVector *self,
#ifdef GTK_VECTOR_BY_VALUE
_T_ *value)
#else
_T_ value)
#endif
{
gtk_vector(splice) (self,
gtk_vector(get_size) (self),
0,
#ifdef GTK_VECTOR_BY_VALUE
value,
#else
&value,
#endif
1);
}
#ifdef GTK_VECTOR_BY_VALUE
G_GNUC_UNUSED static _T_ *
gtk_vector(get) (const GtkVector *self,
gsize pos)
{
return gtk_vector(index) (self, pos);
}
#else
G_GNUC_UNUSED static _T_
gtk_vector(get) (const GtkVector *self,
gsize pos)
{
return *gtk_vector(index) (self, pos);
}
#endif
#ifndef GTK_VECTOR_NO_UNDEF
#undef _T_
#undef GtkVector
#undef gtk_vector_paste_more
#undef gtk_vector_paste
#undef gtk_vector
#undef GTK_VECTOR_REAL_SIZE
#undef GTK_VECTOR_BY_VALUE
#undef GTK_VECTOR_ELEMENT_TYPE
#undef GTK_VECTOR_FREE_FUNC
#undef GTK_VECTOR_NAME
#undef GTK_VECTOR_NULL_TERMINATED
#undef GTK_VECTOR_PREALLOC
#undef GTK_VECTOR_TYPE_NAME
#endif
+2 -2
View File
@@ -245,10 +245,10 @@ gtk_inspector_controllers_set_object (GtkInspectorControllers *self,
self->model = gtk_property_lookup_list_model_new (GTK_TYPE_WIDGET, "parent");
gtk_property_lookup_list_model_set_object (self->model, object);
map_model = gtk_map_list_model_new (G_LIST_MODEL (self->model), map_to_controllers, NULL, NULL);
map_model = gtk_map_list_model_new (G_TYPE_LIST_MODEL, G_LIST_MODEL (self->model), map_to_controllers, NULL, NULL);
g_object_unref (self->model);
flatten_model = gtk_flatten_list_model_new (G_LIST_MODEL (map_model));
flatten_model = gtk_flatten_list_model_new (GTK_TYPE_EVENT_CONTROLLER, G_LIST_MODEL (map_model));
sorter = gtk_custom_sorter_new (compare_controllers, NULL, NULL);
sort_model = gtk_sort_list_model_new (G_LIST_MODEL (flatten_model), sorter);
+7 -7
View File
@@ -130,7 +130,7 @@ object_tree_widget_get_children (GObject *object)
g_list_store_append (list, sublist);
g_object_unref (sublist);
flatten = gtk_flatten_list_model_new (G_LIST_MODEL (list));
flatten = gtk_flatten_list_model_new (G_TYPE_OBJECT, G_LIST_MODEL (list));
g_object_unref (list);
return G_LIST_MODEL (flatten);
@@ -225,7 +225,7 @@ list_model_for_properties (GObject *object,
g_object_unref (tmp);
}
result = G_LIST_MODEL (gtk_flatten_list_model_new (G_LIST_MODEL (concat)));
result = G_LIST_MODEL (gtk_flatten_list_model_new (G_TYPE_OBJECT, G_LIST_MODEL (concat)));
g_object_unref (concat);
return result;
}
@@ -330,7 +330,7 @@ object_tree_tree_view_get_children (GObject *object)
g_object_unref (selection);
g_list_store_append (result_list, columns);
g_object_unref (columns);
result = gtk_flatten_list_model_new (G_LIST_MODEL (result_list));
result = gtk_flatten_list_model_new (G_TYPE_OBJECT, G_LIST_MODEL (result_list));
g_object_unref (result_list);
return G_LIST_MODEL (result);
@@ -353,7 +353,7 @@ object_tree_column_view_get_children (GObject *object)
g_list_store_append (result_list, sublist);
g_object_unref (sublist);
result = gtk_flatten_list_model_new (G_LIST_MODEL (result_list));
result = gtk_flatten_list_model_new (G_TYPE_OBJECT, G_LIST_MODEL (result_list));
g_object_unref (result_list);
return G_LIST_MODEL (result);
@@ -640,7 +640,7 @@ object_get_children (GObject *object)
if (result_list)
{
result = G_LIST_MODEL (gtk_flatten_list_model_new (G_LIST_MODEL (result_list)));
result = G_LIST_MODEL (gtk_flatten_list_model_new (G_TYPE_OBJECT, G_LIST_MODEL (result_list)));
g_object_unref (result_list);
}
@@ -1179,7 +1179,7 @@ create_root_model (GdkDisplay *display)
g_list_store_append (list, special);
g_object_unref (special);
filter = gtk_filter_list_model_new (NULL, NULL);
filter = gtk_filter_list_model_new_for_type (G_TYPE_OBJECT);
custom_filter = gtk_custom_filter_new (toplevel_filter_func,
display, NULL);
gtk_filter_list_model_set_filter (filter, custom_filter);
@@ -1187,7 +1187,7 @@ create_root_model (GdkDisplay *display)
g_list_store_append (list, filter);
g_object_unref (filter);
flatten = gtk_flatten_list_model_new (G_LIST_MODEL (list));
flatten = gtk_flatten_list_model_new (G_TYPE_OBJECT, G_LIST_MODEL (list));
g_object_unref (list);
return G_LIST_MODEL (flatten);
}
-4
View File
@@ -371,8 +371,6 @@ gtk_public_sources = files([
'gtkslicelistmodel.c',
'gtksnapshot.c',
'gtksorter.c',
'gtksor2listmodel.c',
'gtksor3listmodel.c',
'gtksortlistmodel.c',
'gtkspinbutton.c',
'gtkspinner.c',
@@ -642,8 +640,6 @@ gtk_public_headers = files([
'gtkslicelistmodel.h',
'gtksnapshot.h',
'gtksorter.h',
'gtksor2listmodel.h',
'gtksor3listmodel.h',
'gtksortlistmodel.h',
'gtkspinbutton.h',
'gtkspinner.h',
-1
View File
@@ -268,7 +268,6 @@ gtk/gtkscrolledwindow.c
gtk/gtksearchbar.c
gtk/gtksearchengine.c
gtk/gtksearchentry.c
gtk/gtkselectionfiltermodel.c
gtk/gtkseparator.c
gtk/gtksettings.c
gtk/gtkshortcutaction.c
+1 -2
View File
@@ -49,7 +49,6 @@ demos/gtk-demo/stack.ui
demos/gtk-demo/themes.ui
demos/gtk-demo/theming.ui
demos/icon-browser/window.ui
demos/node-editor/help-window.ui
demos/node-editor/node-editor-window.ui
demos/widget-factory/menus.ui
demos/widget-factory/widget-factory.c
@@ -91,6 +90,7 @@ gtk/inspector/actions.ui.h
gtk/inspector/css-editor.ui
gtk/inspector/css-editor.ui.h
gtk/inspector/css-node-tree.ui
gtk/inspector/data-list.ui
gtk/inspector/data-list.ui.h
gtk/inspector/general.ui
gtk/inspector/general.ui.h
@@ -116,7 +116,6 @@ gtk/inspector/statistics.ui
gtk/inspector/statistics.ui.h
gtk/inspector/style-prop-list.ui
gtk/inspector/style-prop-list.ui.h
gtk/inspector/tree-data.ui
gtk/inspector/type-info.ui
gtk/inspector/visual.ui
gtk/inspector/visual.ui.h
+1421 -1992
View File
File diff suppressed because it is too large Load Diff
+394 -416
View File
File diff suppressed because it is too large Load Diff
+339 -338
View File
File diff suppressed because it is too large Load Diff
+1 -2
View File
@@ -270,7 +270,6 @@ gtk/gtkscrolledwindow.c
gtk/gtksearchbar.c
gtk/gtksearchengine.c
gtk/gtksearchentry.c
gtk/gtkselectionfiltermodel.c
gtk/gtkseparator.c
gtk/gtksettings.c
gtk/gtkshortcutaction.c
@@ -346,6 +345,7 @@ gtk/inspector/css-editor.c
gtk/inspector/css-editor.ui
gtk/inspector/css-node-tree.c
gtk/inspector/css-node-tree.ui
gtk/inspector/data-list.ui
gtk/inspector/general.c
gtk/inspector/general.ui
gtk/inspector/inspect-button.c
@@ -364,7 +364,6 @@ gtk/inspector/shortcuts.ui
gtk/inspector/size-groups.c
gtk/inspector/statistics.c
gtk/inspector/statistics.ui
gtk/inspector/tree-data.ui
gtk/inspector/type-info.ui
gtk/inspector/visual.c
gtk/inspector/visual.ui
-1
View File
@@ -49,7 +49,6 @@ demos/gtk-demo/stack.ui
demos/gtk-demo/themes.ui
demos/gtk-demo/theming.ui
demos/icon-browser/window.ui
demos/node-editor/help-window.ui
demos/node-editor/node-editor-window.ui
demos/widget-factory/menus.ui
demos/widget-factory/widget-factory.c
+433 -408
View File
File diff suppressed because it is too large Load Diff
+222 -210
View File
File diff suppressed because it is too large Load Diff
+19
View File
@@ -118,6 +118,17 @@ response_cb (GtkDialog *dialog,
g_main_context_wakeup (NULL);
}
static gboolean
no_backup_files_filter (const GtkFileFilterInfo *filter_info,
gpointer data)
{
gsize len = filter_info->display_name ? strlen (filter_info->display_name) : 0;
if (len > 0 && filter_info->display_name[len - 1] == '~')
return 0;
else
return 1;
}
static void
filter_changed (GtkFileChooserDialog *dialog,
gpointer data)
@@ -384,6 +395,14 @@ main (int argc, char **argv)
gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), filter);
g_object_unref (filter);
filter = gtk_file_filter_new ();
gtk_file_filter_set_name (filter, "No backup files");
gtk_file_filter_add_custom (filter, GTK_FILE_FILTER_DISPLAY_NAME,
no_backup_files_filter, NULL, NULL);
gtk_file_filter_add_mime_type (filter, "image/png");
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
g_object_unref (filter);
filter = gtk_file_filter_new ();
gtk_file_filter_set_name (filter, "Starts with D");
gtk_file_filter_add_pattern (filter, "D*");
+5 -9
View File
@@ -5672,19 +5672,15 @@ native_filter_changed (GtkWidget *combo,
GtkFileChooserNative *native)
{
int i;
GListModel *filters;
GSList *filters, *l;
GtkFileFilter *filter;
i = gtk_combo_box_get_active (GTK_COMBO_BOX (combo));
filters = gtk_file_chooser_get_filters (GTK_FILE_CHOOSER (native));
while (g_list_model_get_n_items (filters) > 0)
{
GtkFileFilter *f = g_list_model_get_item (filters, 0);
gtk_file_chooser_remove_filter (GTK_FILE_CHOOSER (native), f);
g_object_unref (f);
}
g_object_unref (filters);
filters = gtk_file_chooser_list_filters (GTK_FILE_CHOOSER (native));
for (l = filters; l != NULL; l = l->next)
gtk_file_chooser_remove_filter (GTK_FILE_CHOOSER (native), l->data);
g_slist_free (filters);
switch (i)
{
+2 -2
View File
@@ -621,7 +621,7 @@ main (int argc, char *argv[])
factory = gtk_signal_list_item_factory_new ();
g_signal_connect (factory, "setup", G_CALLBACK (setup_widget), NULL);
listview = gtk_list_view_new_with_factory (factory);
listview = gtk_grid_view_new_with_factory (factory);
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), listview);
if (argc > 1)
@@ -645,7 +645,7 @@ main (int argc, char *argv[])
selectionmodel = file_info_selection_new (G_LIST_MODEL (filter));
g_object_unref (filter);
gtk_list_view_set_model (GTK_LIST_VIEW (listview), G_LIST_MODEL (selectionmodel));
gtk_grid_view_set_model (GTK_GRID_VIEW (listview), G_LIST_MODEL (selectionmodel));
statusbar = gtk_statusbar_new ();
gtk_widget_add_tick_callback (statusbar, (GtkTickCallback) update_statusbar, NULL, NULL);
+2 -15
View File
@@ -424,13 +424,13 @@ test_slice (void)
gtk_bitset_add_range (set, 10, 30);
gtk_bitset_splice (set, 20, 10, 20);
gtk_bitset_slice (set, 20, 10, 20);
for (i = 0; i < 60; i++)
g_assert_cmpint (gtk_bitset_contains (set, i), ==, (i >= 10 && i < 20) ||
(i >= 40 && i < 50));
gtk_bitset_splice (set, 25, 10, 0);
gtk_bitset_slice (set, 25, 10, 0);
for (i = 0; i < 60; i++)
g_assert_cmpint (gtk_bitset_contains (set, i), ==, (i >= 10 && i < 20) ||
@@ -543,18 +543,6 @@ test_iter (void)
gtk_bitset_unref (set);
}
static void
test_splice_overflow (void)
{
GtkBitset *set, *compare;
set = gtk_bitset_new_range (3, 1);
gtk_bitset_splice (set, 0, 0, 13);
compare = gtk_bitset_new_range (16, 1);
g_assert_true (gtk_bitset_equals (set, compare));
}
int
main (int argc, char *argv[])
{
@@ -574,7 +562,6 @@ main (int argc, char *argv[])
g_test_add_func ("/bitset/slice", test_slice);
g_test_add_func ("/bitset/rectangle", test_rectangle);
g_test_add_func ("/bitset/iter", test_iter);
g_test_add_func ("/bitset/splice-overflow", test_splice_overflow);
return g_test_run ();
}
+12 -2
View File
@@ -2387,6 +2387,7 @@ test_file_filter (void)
GtkBuilder *builder;
GObject *obj;
GtkFileFilter *filter;
GtkFileFilterInfo info;
const gchar buffer[] =
"<interface>"
@@ -2408,8 +2409,17 @@ test_file_filter (void)
g_assert (GTK_IS_FILE_FILTER (obj));
filter = GTK_FILE_FILTER (obj);
g_assert_cmpstr (gtk_file_filter_get_name (filter), ==, "Text and Images");
g_assert_true (g_strv_contains (gtk_file_filter_get_attributes (filter), G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE));
g_assert_true (g_strv_contains (gtk_file_filter_get_attributes (filter), G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME));
g_assert (gtk_file_filter_get_needed (filter) & GTK_FILE_FILTER_MIME_TYPE);
g_assert (gtk_file_filter_get_needed (filter) & GTK_FILE_FILTER_DISPLAY_NAME);
info.filename = "test1.txt";
info.display_name = "test1.txt";
info.contains = GTK_FILE_FILTER_FILENAME | GTK_FILE_FILTER_DISPLAY_NAME;
g_assert (gtk_file_filter_filter (filter, &info));
info.mime_type = "application/x-pdf";
info.contains = GTK_FILE_FILTER_MIME_TYPE;
g_assert (!gtk_file_filter_filter (filter, &info));
g_object_unref (builder);
}
+1 -1
View File
@@ -492,7 +492,7 @@ test_bind_child (void)
"filter");
filter = gtk_string_filter_new ();
child = gtk_filter_list_model_new (NULL, NULL);
child = gtk_filter_list_model_new_for_type (G_TYPE_OBJECT);
gtk_filter_list_model_set_filter (child, filter);
target = gtk_filter_list_model_new (G_LIST_MODEL (child), NULL);
g_object_unref (child);
-479
View File
@@ -1,479 +0,0 @@
/* GtkRBTree tests.
*
* Copyright (C) 2011, Red Hat, Inc.
* Authors: Benjamin Otte <otte@gnome.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include <locale.h>
#include <gtk/gtk.h>
#define ensure_updated() G_STMT_START{ \
while (g_main_context_pending (NULL)) \
g_main_context_iteration (NULL, TRUE); \
}G_STMT_END
#define assert_model_equal(model1, model2) G_STMT_START{ \
guint _i, _n; \
g_assert_cmpint (g_list_model_get_n_items (model1), ==, g_list_model_get_n_items (model2)); \
_n = g_list_model_get_n_items (model1); \
for (_i = 0; _i < _n; _i++) \
{ \
gpointer o1 = g_list_model_get_item (model1, _i); \
gpointer o2 = g_list_model_get_item (model2, _i); \
if (o1 != o2) \
{ \
char *_s = g_strdup_printf ("Objects differ at index %u out of %u", _i, _n); \
g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, _s); \
g_free (_s); \
} \
} \
}G_STMT_END
G_GNUC_UNUSED static char *
model_to_string (GListModel *model)
{
GString *string;
guint i, n;
n = g_list_model_get_n_items (model);
string = g_string_new (NULL);
/* Check that all unchanged items are indeed unchanged */
for (i = 0; i < n; i++)
{
gpointer item = g_list_model_get_item (model, i);
if (i > 0)
g_string_append (string, ", ");
g_string_append (string, gtk_string_object_get_string (item));
g_object_unref (item);
}
return g_string_free (string, FALSE);
}
static void
assert_items_changed_correctly (GListModel *model,
guint position,
guint removed,
guint added,
GListModel *compare)
{
guint i, n_items;
//g_print ("%s => %u -%u +%u => %s\n", model_to_string (compare), position, removed, added, model_to_string (model));
g_assert_cmpint (g_list_model_get_n_items (model), ==, g_list_model_get_n_items (compare) - removed + added);
n_items = g_list_model_get_n_items (model);
/* Check that all unchanged items are indeed unchanged */
for (i = 0; i < position; i++)
{
gpointer o1 = g_list_model_get_item (model, i);
gpointer o2 = g_list_model_get_item (compare, i);
g_assert_cmphex (GPOINTER_TO_SIZE (o1), ==, GPOINTER_TO_SIZE (o2));
g_object_unref (o1);
g_object_unref (o2);
}
for (i = position + added; i < n_items; i++)
{
gpointer o1 = g_list_model_get_item (model, i);
gpointer o2 = g_list_model_get_item (compare, i - added + removed);
g_assert_cmphex (GPOINTER_TO_SIZE (o1), ==, GPOINTER_TO_SIZE (o2));
g_object_unref (o1);
g_object_unref (o2);
}
/* Check that the first and last added item are different from
* first and last removed item.
* Otherwise we could have kept them as-is
*/
if (removed > 0 && added > 0)
{
gpointer o1 = g_list_model_get_item (model, position);
gpointer o2 = g_list_model_get_item (compare, position);
g_assert_cmphex (GPOINTER_TO_SIZE (o1), !=, GPOINTER_TO_SIZE (o2));
g_object_unref (o1);
g_object_unref (o2);
o1 = g_list_model_get_item (model, position + added - 1);
o2 = g_list_model_get_item (compare, position + removed - 1);
g_assert_cmphex (GPOINTER_TO_SIZE (o1), !=, GPOINTER_TO_SIZE (o2));
g_object_unref (o1);
g_object_unref (o2);
}
/* Finally, perform the same change as the signal indicates */
g_list_store_splice (G_LIST_STORE (compare), position, removed, NULL, 0);
for (i = position; i < position + added; i++)
{
gpointer item = g_list_model_get_item (G_LIST_MODEL (model), i);
g_list_store_insert (G_LIST_STORE (compare), i, item);
g_object_unref (item);
}
}
static GtkFilterListModel *
filter_list_model_new (GListModel *source,
GtkFilter *filter)
{
GtkFilterListModel *model;
GListStore *check;
guint i;
model = gtk_filter_list_model_new (source, filter);
check = g_list_store_new (G_TYPE_OBJECT);
for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (model)); i++)
{
gpointer item = g_list_model_get_item (G_LIST_MODEL (model), i);
g_list_store_append (check, item);
g_object_unref (item);
}
g_signal_connect_data (model,
"items-changed",
G_CALLBACK (assert_items_changed_correctly),
check,
(GClosureNotify) g_object_unref,
0);
return model;
}
#define N_MODELS 8
static GtkFilterListModel *
create_filter_list_model (gconstpointer model_id,
GListModel *source,
GtkFilter *filter)
{
GtkFilterListModel *model;
guint id = GPOINTER_TO_UINT (model_id);
model = filter_list_model_new (id & 1 ? NULL : source, id & 2 ? NULL : filter);
switch (id >> 2)
{
case 0:
break;
case 1:
gtk_filter_list_model_set_incremental (model, TRUE);
break;
default:
g_assert_not_reached ();
break;
}
if (id & 1)
gtk_filter_list_model_set_model (model, source);
if (id & 2)
gtk_filter_list_model_set_filter (model, filter);
return model;
}
static GListModel *
create_source_model (guint min_size, guint max_size)
{
GtkStringList *list;
guint i, size;
size = g_test_rand_int_range (min_size, max_size + 1);
list = gtk_string_list_new (NULL);
for (i = 0; i < size; i++)
gtk_string_list_append (list, g_test_rand_bit () ? "A" : "B");
return G_LIST_MODEL (list);
}
#define N_FILTERS 5
static GtkFilter *
create_filter (gsize id)
{
GtkFilter *filter;
GtkExpression *expr;
switch (id)
{
case 0:
/* GTK_FILTER_MATCH_ALL */
return gtk_string_filter_new ();
case 1:
/* GTK_FILTER_MATCH_NONE */
filter = gtk_string_filter_new ();
gtk_string_filter_set_search (GTK_STRING_FILTER (filter), "does not matter, because no expression");
return filter;
case 2:
case 3:
case 4:
/* match all As, Bs and nothing */
filter = gtk_string_filter_new ();
expr = gtk_property_expression_new (GTK_TYPE_STRING_OBJECT, NULL, "string");
gtk_string_filter_set_expression (GTK_STRING_FILTER (filter), expr);
gtk_expression_unref (expr);
if (id == 2)
gtk_string_filter_set_search (GTK_STRING_FILTER (filter), "A");
else if (id == 3)
gtk_string_filter_set_search (GTK_STRING_FILTER (filter), "B");
else
gtk_string_filter_set_search (GTK_STRING_FILTER (filter), "does-not-match");
return filter;
default:
g_assert_not_reached ();
return NULL;
}
}
static GtkFilter *
create_random_filter (gboolean allow_null)
{
guint n;
if (allow_null)
n = g_test_rand_int_range (0, N_FILTERS + 1);
else
n = g_test_rand_int_range (0, N_FILTERS);
if (n >= N_FILTERS)
return NULL;
return create_filter (n);
}
static void
test_no_filter (gconstpointer model_id)
{
GtkFilterListModel *model;
GListModel *source;
GtkFilter *filter;
source = create_source_model (10, 10);
model = create_filter_list_model (model_id, source, NULL);
ensure_updated ();
assert_model_equal (G_LIST_MODEL (model), source);
filter = create_random_filter (FALSE);
gtk_filter_list_model_set_filter (model, filter);
g_object_unref (filter);
gtk_filter_list_model_set_filter (model, NULL);
ensure_updated ();
assert_model_equal (G_LIST_MODEL (model), source);
g_object_unref (model);
g_object_unref (source);
}
/* Compare this:
* source => filter1 => filter2
* with:
* source => multifilter(filter1, filter2)
* and randomly change the source and filters and see if the
* two continue agreeing.
*/
static void
test_two_filters (gconstpointer model_id)
{
GtkFilterListModel *compare;
GtkFilterListModel *model1, *model2;
GListModel *source;
GtkFilter *every, *filter;
guint i, j, k;
source = create_source_model (10, 10);
model1 = create_filter_list_model (model_id, source, NULL);
model2 = create_filter_list_model (model_id, G_LIST_MODEL (model1), NULL);
every = gtk_every_filter_new ();
compare = create_filter_list_model (model_id, source, every);
g_object_unref (every);
g_object_unref (source);
for (i = 0; i < N_FILTERS; i++)
{
filter = create_filter (i);
gtk_filter_list_model_set_filter (model1, filter);
gtk_multi_filter_append (GTK_MULTI_FILTER (every), filter);
for (j = 0; j < N_FILTERS; j++)
{
filter = create_filter (i);
gtk_filter_list_model_set_filter (model2, filter);
gtk_multi_filter_append (GTK_MULTI_FILTER (every), filter);
ensure_updated ();
assert_model_equal (G_LIST_MODEL (model2), G_LIST_MODEL (compare));
for (k = 0; k < 10; k++)
{
source = create_source_model (0, 20);
gtk_filter_list_model_set_model (compare, source);
gtk_filter_list_model_set_model (model1, source);
g_object_unref (source);
ensure_updated ();
assert_model_equal (G_LIST_MODEL (model2), G_LIST_MODEL (compare));
}
gtk_multi_filter_remove (GTK_MULTI_FILTER (every), 1);
}
gtk_multi_filter_remove (GTK_MULTI_FILTER (every), 0);
}
g_object_unref (compare);
g_object_unref (model2);
g_object_unref (model1);
}
/* Compare this:
* (source => filter) * => flatten
* with:
* source * => flatten => filter
* and randomly add/remove sources and change the filters and
* see if the two agree.
*
* We use a multifilter for the top chain so that changing the filter
* is easy.
*/
static void
test_model_changes (gconstpointer model_id)
{
GListStore *store1, *store2;
GtkFlattenListModel *flatten1, *flatten2;
GtkFilterListModel *model2;
GtkFilter *multi, *filter;
gsize i;
filter = create_random_filter (TRUE);
multi = gtk_every_filter_new ();
if (filter)
gtk_multi_filter_append (GTK_MULTI_FILTER (multi), filter);
store1 = g_list_store_new (G_TYPE_OBJECT);
store2 = g_list_store_new (G_TYPE_OBJECT);
flatten1 = gtk_flatten_list_model_new (G_LIST_MODEL (store1));
flatten2 = gtk_flatten_list_model_new (G_LIST_MODEL (store2));
model2 = create_filter_list_model (model_id, G_LIST_MODEL (flatten2), filter);
for (i = 0; i < 500; i++)
{
gboolean add = FALSE, remove = FALSE;
guint position;
switch (g_test_rand_int_range (0, 4))
{
case 0:
/* change the filter */
filter = create_random_filter (TRUE);
gtk_multi_filter_remove (GTK_MULTI_FILTER (multi), 0); /* no-op if no filter */
if (filter)
gtk_multi_filter_append (GTK_MULTI_FILTER (multi), filter);
gtk_filter_list_model_set_filter (model2, filter);
break;
case 1:
/* remove a model */
remove = TRUE;
break;
case 2:
/* add a model */
add = TRUE;
break;
case 3:
/* replace a model */
remove = TRUE;
add = TRUE;
break;
default:
g_assert_not_reached ();
break;
}
position = g_test_rand_int_range (0, g_list_model_get_n_items (G_LIST_MODEL (store1)) + 1);
if (g_list_model_get_n_items (G_LIST_MODEL (store1)) == position)
remove = FALSE;
if (add)
{
/* We want at least one element, otherwise the filters will see no changes */
GListModel *source = create_source_model (1, 20);
GtkFilterListModel *model1 = create_filter_list_model (model_id, source, multi);
g_list_store_splice (store1,
position,
remove ? 1 : 0,
(gpointer *) &model1, 1);
g_list_store_splice (store2,
position,
remove ? 1 : 0,
(gpointer *) &source, 1);
g_object_unref (source);
}
else if (remove)
{
g_list_store_remove (store1, position);
g_list_store_remove (store2, position);
}
if (g_test_rand_bit ())
{
ensure_updated ();
assert_model_equal (G_LIST_MODEL (flatten1), G_LIST_MODEL (model2));
}
}
g_object_unref (model2);
g_object_unref (flatten2);
g_object_unref (flatten1);
g_object_unref (store2);
g_object_unref (store1);
g_object_unref (multi);
}
static void
add_test_for_all_models (const char *name,
GTestDataFunc test_func)
{
guint i;
for (i = 0; i < N_MODELS; i++)
{
char *path = g_strdup_printf ("/filterlistmodel/model%u/%s", i, name);
g_test_add_data_func (path, GUINT_TO_POINTER (i), test_func);
g_free (path);
}
}
int
main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
setlocale (LC_ALL, "C");
add_test_for_all_models ("no-filter", test_no_filter);
add_test_for_all_models ("two-filters", test_two_filters);
add_test_for_all_models ("model-changes", test_model_changes);
return g_test_run ();
}
+1 -1
View File
@@ -210,7 +210,7 @@ new_model (GListStore *store)
GtkFlattenListModel *result;
GString *changes;
result = gtk_flatten_list_model_new (G_LIST_MODEL (store));
result = gtk_flatten_list_model_new (G_TYPE_OBJECT, G_LIST_MODEL (store));
changes = g_string_new ("");
g_object_set_qdata_full (G_OBJECT(result), changes_quark, changes, free_changes);
g_signal_connect (result, "items-changed", G_CALLBACK (items_changed), changes);
+1 -1
View File
@@ -196,7 +196,7 @@ new_model (GListStore *store)
GtkMapListModel *result;
GString *changes;
result = gtk_map_list_model_new (G_LIST_MODEL (store), map_multiply, GUINT_TO_POINTER (2), NULL);
result = gtk_map_list_model_new (G_TYPE_OBJECT, G_LIST_MODEL (store), map_multiply, GUINT_TO_POINTER (2), NULL);
changes = g_string_new ("");
g_object_set_qdata_full (G_OBJECT(result), changes_quark, changes, free_changes);
g_signal_connect (result, "items-changed", G_CALLBACK (items_changed), changes);
-3
View File
@@ -30,7 +30,6 @@ tests = [
['expression'],
['filter'],
['filterlistmodel'],
['filterlistmodel-exhaustive'],
['flattenlistmodel'],
['floating'],
['flowbox'],
@@ -75,8 +74,6 @@ tests = [
['typename'],
['displayclose'],
['revealer-size'],
['vector'],
['vector-performance'],
['widgetorder'],
['widget-refcount'],
]
-54
View File
@@ -613,59 +613,6 @@ test_selection_filter (void)
g_object_unref (store);
g_object_unref (selection);
}
static void
test_set_model (void)
{
GtkSelectionModel *selection;
GListStore *store;
GListModel *m1, *m2;
gboolean ret;
store = new_store (1, 5, 1);
m1 = G_LIST_MODEL (store);
m2 = G_LIST_MODEL (gtk_slice_list_model_new (m1, 0, 3));
selection = new_model (store);
assert_selection (selection, "");
assert_selection_changes (selection, "");
ret = gtk_selection_model_select_range (selection, 1, 3, FALSE);
g_assert_true (ret);
assert_selection (selection, "2 3 4");
assert_selection_changes (selection, "1:3");
/* we retain the selected item across model changes */
gtk_multi_selection_set_model (GTK_MULTI_SELECTION (selection), m2);
assert_changes (selection, "0-5+3");
assert_selection (selection, "2 3");
assert_selection_changes (selection, "");
gtk_multi_selection_set_model (GTK_MULTI_SELECTION (selection), NULL);
assert_changes (selection, "0-3");
assert_selection (selection, "");
assert_selection_changes (selection, "");
gtk_multi_selection_set_model (GTK_MULTI_SELECTION (selection), m2);
assert_changes (selection, "0+3");
assert_selection (selection, "");
assert_selection_changes (selection, "");
ret = gtk_selection_model_select_all (selection);
g_assert_true (ret);
assert_selection (selection, "1 2 3");
assert_selection_changes (selection, "0:3");
/* we retain no selected item across model changes */
gtk_multi_selection_set_model (GTK_MULTI_SELECTION (selection), m1);
assert_changes (selection, "0-3+5");
assert_selection (selection, "1 2 3");
assert_selection_changes (selection, "");
g_object_unref (m2);
g_object_unref (m1);
g_object_unref (selection);
}
int
main (int argc, char *argv[])
{
@@ -686,7 +633,6 @@ main (int argc, char *argv[])
g_test_add_func ("/multiselection/readd", test_readd);
g_test_add_func ("/multiselection/set_selection", test_set_selection);
g_test_add_func ("/multiselection/selection-filter", test_selection_filter);
g_test_add_func ("/multiselection/set-model", test_set_model);
return g_test_run ();
}
-52
View File
@@ -644,57 +644,6 @@ test_query_range (void)
g_object_unref (selection);
}
static void
test_set_model (void)
{
GtkSelectionModel *selection;
GListStore *store;
GListModel *m1, *m2;
store = new_store (1, 5, 1);
m1 = G_LIST_MODEL (store);
m2 = G_LIST_MODEL (gtk_slice_list_model_new (m1, 0, 3));
selection = new_model (store, TRUE, TRUE);
assert_selection (selection, "1");
assert_selection_changes (selection, "");
/* we retain the selected item across model changes */
gtk_single_selection_set_model (GTK_SINGLE_SELECTION (selection), m2);
assert_changes (selection, "0-5+3");
assert_selection (selection, "1");
assert_selection_changes (selection, "");
gtk_single_selection_set_model (GTK_SINGLE_SELECTION (selection), NULL);
assert_changes (selection, "0-3");
assert_selection (selection, "");
assert_selection_changes (selection, "");
gtk_single_selection_set_autoselect (GTK_SINGLE_SELECTION (selection), FALSE);
gtk_single_selection_set_model (GTK_SINGLE_SELECTION (selection), m2);
assert_changes (selection, "0+3");
assert_selection (selection, "");
assert_selection_changes (selection, "");
/* we retain no selected item across model changes */
gtk_single_selection_set_model (GTK_SINGLE_SELECTION (selection), m1);
assert_changes (selection, "0-3+5");
assert_selection (selection, "");
assert_selection_changes (selection, "");
gtk_single_selection_set_selected (GTK_SINGLE_SELECTION (selection), 4);
assert_selection (selection, "5");
assert_selection_changes (selection, "4:1");
gtk_single_selection_set_model (GTK_SINGLE_SELECTION (selection), m2);
assert_changes (selection, "0-5+3");
assert_selection (selection, "");
assert_selection_changes (selection, "");
g_object_unref (m2);
g_object_unref (m1);
g_object_unref (selection);
}
int
main (int argc, char *argv[])
{
@@ -713,7 +662,6 @@ main (int argc, char *argv[])
g_test_add_func ("/singleselection/persistence", test_persistence);
g_test_add_func ("/singleselection/query-range", test_query_range);
g_test_add_func ("/singleselection/changes", test_changes);
g_test_add_func ("/singleselection/set-model", test_set_model);
return g_test_run ();
}
+5 -1
View File
@@ -191,7 +191,11 @@ new_model (GListStore *store, guint offset, guint size)
GtkSliceListModel *result;
GString *changes;
result = gtk_slice_list_model_new (G_LIST_MODEL (store), offset, size);
result = gtk_slice_list_model_new_for_type (G_TYPE_OBJECT);
if (store)
gtk_slice_list_model_set_model (result, G_LIST_MODEL (store));
gtk_slice_list_model_set_offset (result, offset);
gtk_slice_list_model_set_size (result, size);
changes = g_string_new ("");
g_object_set_qdata_full (G_OBJECT(result), changes_quark, changes, free_changes);
+1 -1
View File
@@ -203,7 +203,7 @@ new_model (gpointer model)
g_object_unref (sorter);
}
else
result = gtk_sort_list_model_new (NULL, NULL);
result = gtk_sort_list_model_new_for_type (G_TYPE_OBJECT);
changes = g_string_new ("");
g_object_set_qdata_full (G_OBJECT(result), changes_quark, changes, free_changes);
+1 -1
View File
@@ -184,7 +184,7 @@ test_splice (void)
assert_model (list, "a b c d e");
gtk_string_list_splice (list, 2, 2, (const char *[]){ "x", "y", "z", NULL });
gtk_string_list_splice (list, 2, 2, (const char *[]){ "x", "y", "z" }, 3);
assert_model (list, "a b x y z e");
assert_changes (list, "2-2+3");
-443
View File
@@ -1,443 +0,0 @@
#include <gtk/gtk.h>
#define GTK_VECTOR_ELEMENT_TYPE gpointer
#define GTK_VECTOR_NAME pointer_vector
#define GTK_VECTOR_TYPE_NAME PointerVector
#include "../../gtk/gtkvectorimpl.c"
#define GTK_VECTOR_ELEMENT_TYPE gpointer
#define GTK_VECTOR_NAME prealloc_vector
#define GTK_VECTOR_TYPE_NAME PreallocVector
#define GTK_VECTOR_PREALLOC 1024
#include "../../gtk/gtkvectorimpl.c"
static inline guint
quick_random (guint prev)
{
prev ^= prev << 13;
prev ^= prev >> 17;
prev ^= prev << 5;
return prev;
}
typedef struct {
const char *name;
gsize stack_space;
gpointer (* create) (gpointer space, gsize size);
void (* free) (gpointer array);
void (* reserve) (gpointer array, gsize size);
gpointer (* get) (gpointer array, gsize pos);
void (* append) (gpointer array, gpointer data);
void (* insert) (gpointer array, gsize pos, gpointer data);
} Array;
static gpointer
create_ptrarray (gpointer space,
gsize size)
{
return g_ptr_array_sized_new (size);
}
static void
free_ptrarray (gpointer array)
{
g_ptr_array_free (array, TRUE);
}
static void
reserve_ptrarray (gpointer array,
gsize size)
{
gsize length = ((GPtrArray *) array)->len;
if (length >= size)
return;
g_ptr_array_set_size (array, size);
g_ptr_array_set_size (array, length);
}
static gpointer
get_ptrarray (gpointer array,
gsize pos)
{
return g_ptr_array_index ((GPtrArray *) array, pos);
}
static void
append_ptrarray (gpointer array,
gpointer data)
{
g_ptr_array_add (array, data);
}
static void
insert_ptrarray (gpointer array,
gsize pos,
gpointer data)
{
g_ptr_array_insert (array, pos, data);
}
static gpointer
create_vector (gpointer space,
gsize size)
{
pointer_vector_init (space);
if (size)
pointer_vector_reserve ((PointerVector *) space, size);
return space;
}
static void
free_vector (gpointer array)
{
pointer_vector_clear (array);
}
static void
reserve_vector (gpointer array,
gsize size)
{
pointer_vector_reserve (array, size);
}
static gpointer
get_vector (gpointer array,
gsize pos)
{
return pointer_vector_get (array, pos);
}
static void
append_vector (gpointer array,
gpointer data)
{
pointer_vector_append (array, data);
}
static void
insert_vector (gpointer array,
gsize pos,
gpointer data)
{
pointer_vector_splice (array, pos, 0, &data, 1);
}
static gpointer
create_prealloc (gpointer space,
gsize size)
{
prealloc_vector_init (space);
if (size)
prealloc_vector_reserve ((PreallocVector *) space, size);
return space;
}
static void
free_prealloc (gpointer array)
{
prealloc_vector_clear (array);
}
static void
reserve_prealloc (gpointer array,
gsize size)
{
prealloc_vector_reserve (array, size);
}
static gpointer
get_prealloc (gpointer array,
gsize pos)
{
return prealloc_vector_get (array, pos);
}
static void
append_prealloc (gpointer array,
gpointer data)
{
prealloc_vector_append (array, data);
}
static void
insert_prealloc (gpointer array,
gsize pos,
gpointer data)
{
prealloc_vector_splice (array, pos, 0, &data, 1);
}
static void
do_random_access (const Array *klass,
guint random,
gsize size,
gsize max_size)
{
gpointer stack;
gpointer array;
guint i;
guint position;
gint64 start, end;
guint iterations = 10000000;
size = pow (100 * 100 * 100 * 100, (double) size / max_size);
if (klass->stack_space)
stack = g_alloca (klass->stack_space);
else
stack = NULL;
array = klass->create (stack, size);
for (i = 0; i < size; i++)
klass->append (array, GSIZE_TO_POINTER (i));
start = g_get_monotonic_time ();
for (i = 0; i < iterations; i++)
{
position = random % size;
random = quick_random (random);
g_assert_cmpint (position, ==, GPOINTER_TO_SIZE (klass->get (array, position)));
}
end = g_get_monotonic_time ();
g_print ("\"random access\",\"%s\", %zu, %g\n",
klass->name,
size,
((double)(end - start)) / iterations);
klass->free (array);
}
static void
do_linear_access (const Array *klass,
guint random,
gsize size,
gsize max_size)
{
gpointer stack;
gpointer array;
guint i;
gint64 start, end;
guint iterations = 1000000;
size = pow (100 * 100 * 100 * 100, (double) size / max_size);
if (klass->stack_space)
stack = g_alloca (klass->stack_space);
else
stack = NULL;
array = klass->create (stack, size);
for (i = 0; i < size; i++)
klass->append (array, GSIZE_TO_POINTER (i));
start = g_get_monotonic_time ();
for (i = 0; i < iterations; i++)
{
g_assert_cmpint (i % size, ==, GPOINTER_TO_SIZE (klass->get (array, i % size)));
}
end = g_get_monotonic_time ();
g_print ("\"linear access\", \"%s\", %zu, %g\n",
klass->name,
size,
((double)(end - start)) / iterations);
klass->free (array);
}
static void
do_append (const Array *klass,
guint random,
gsize size,
gsize max_size)
{
gpointer stack;
gpointer array;
guint i;
gint64 start, end;
int iterations = 10000;
size = pow (100 * 1000 * 1000, (double) size / max_size);
if (klass->stack_space)
stack = g_alloca (klass->stack_space);
else
stack = NULL;
array = klass->create (stack, size);
for (i = 0; i < size; i++)
klass->append (array, GSIZE_TO_POINTER (i));
start = g_get_monotonic_time ();
for (i = size; i < size + iterations; i++)
{
klass->append (array, GSIZE_TO_POINTER (i));
}
end = g_get_monotonic_time ();
klass->free (array);
g_print ("\"append\", \"%s\", %zu, %g\n",
klass->name,
size,
((double) (end - start)) / iterations);
}
static void
do_insert (const Array *klass,
guint random,
gsize size,
gsize max_size)
{
gpointer stack;
gpointer array;
guint i;
gint64 start, end;
int iterations = 10000;
size = pow (25 * 25 * 25 * 25, (double) size / max_size);
if (klass->stack_space)
stack = g_alloca (klass->stack_space);
else
stack = NULL;
array = klass->create (stack, size);
for (i = 0; i < size; i++)
klass->append (array, GSIZE_TO_POINTER (i));
start = g_get_monotonic_time ();
for (i = size; i < size + iterations; i++)
{
gsize position = random % size;
random = quick_random (random);
klass->insert (array, position, GSIZE_TO_POINTER (i));
}
end = g_get_monotonic_time ();
klass->free (array);
g_print ("\"insert\", \"%s\", %zu, %g\n",
klass->name,
size,
((double) (end - start)) / iterations);
}
static void
do_create (const Array *klass,
guint random,
gsize size,
gsize max_size)
{
gpointer stack;
gpointer array;
gsize i, j;
gint64 start, end;
gsize iterations = 100000;
size = pow (4 * 4 * 4 * 4, (double) size / max_size);
if (klass->stack_space)
stack = g_alloca (klass->stack_space);
else
stack = NULL;
start = g_get_monotonic_time ();
for (i = 0; i < iterations; i++)
{
gsize position = random % size;
random = quick_random (random);
array = klass->create (stack, size);
for (j = 0; j < size; j++)
klass->append (array, GSIZE_TO_POINTER (i));
klass->insert (array, position, GSIZE_TO_POINTER (i));
klass->free (array);
}
end = g_get_monotonic_time ();
g_print ("\"create\", \"%s\", %zu, %g\n",
klass->name,
size,
((double) (end - start)) / iterations);
}
const Array all_arrays[] = {
{
"ptrarray",
0,
create_ptrarray,
free_ptrarray,
reserve_ptrarray,
get_ptrarray,
append_ptrarray,
insert_ptrarray
},
{
"vector",
sizeof (PointerVector),
create_vector,
free_vector,
reserve_vector,
get_vector,
append_vector,
insert_vector
},
{
"preallocated-vector",
sizeof (PreallocVector),
create_prealloc,
free_prealloc,
reserve_prealloc,
get_prealloc,
append_prealloc,
insert_prealloc
}
};
static void
run_test (void (* test_func) (const Array *klass, guint random, gsize size, gsize max_size))
{
int max_size = 4;
int size;
int i;
guint random = g_random_int ();
for (i = 0; i < G_N_ELEMENTS (all_arrays); i++)
{
for (size = 1; size <= max_size; size++)
{
test_func (&all_arrays[i], random, size, max_size);
}
}
}
int
main (int argc, char *argv[])
{
gtk_test_init (&argc, &argv);
g_print ("\"test\",\"model\",\"model size\",\"time\"\n");
run_test (do_random_access);
run_test (do_linear_access);
run_test (do_append);
run_test (do_insert);
run_test (do_create);
return g_test_run ();
}
-105
View File
@@ -1,105 +0,0 @@
/*
* Copyright © 2020 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 <locale.h>
#include <gtk/gtk.h>
static void
int_free_func (int data)
{
}
#define GTK_VECTOR_ELEMENT_TYPE int
#define GTK_VECTOR_NAME int_vector
#define GTK_VECTOR_TYPE_NAME IntVector
#include "vectorimpl.c"
#define GTK_VECTOR_ELEMENT_TYPE int
#define GTK_VECTOR_NAME pre_int_vector
#define GTK_VECTOR_TYPE_NAME PreIntVector
#define GTK_VECTOR_PREALLOC 100
#include "vectorimpl.c"
#define GTK_VECTOR_ELEMENT_TYPE int
#define GTK_VECTOR_NAME free_int_vector
#define GTK_VECTOR_TYPE_NAME FreeIntVector
#define GTK_VECTOR_FREE_FUNC int_free_func
#include "vectorimpl.c"
#define GTK_VECTOR_ELEMENT_TYPE int
#define GTK_VECTOR_NAME pre_free_int_vector
#define GTK_VECTOR_TYPE_NAME PreFreeIntVector
#define GTK_VECTOR_PREALLOC 100
#define GTK_VECTOR_FREE_FUNC int_free_func
#include "vectorimpl.c"
#define GTK_VECTOR_ELEMENT_TYPE int
#define GTK_VECTOR_NAME null_int_vector
#define GTK_VECTOR_TYPE_NAME NullIntVector
#define GTK_VECTOR_NULL_TERMINATED 1
#include "vectorimpl.c"
#define GTK_VECTOR_ELEMENT_TYPE int
#define GTK_VECTOR_NAME null_pre_int_vector
#define GTK_VECTOR_TYPE_NAME NullPreIntVector
#define GTK_VECTOR_PREALLOC 100
#define GTK_VECTOR_NULL_TERMINATED 1
#include "vectorimpl.c"
#define GTK_VECTOR_ELEMENT_TYPE int
#define GTK_VECTOR_NAME null_free_int_vector
#define GTK_VECTOR_TYPE_NAME NullFreeIntVector
#define GTK_VECTOR_FREE_FUNC int_free_func
#define GTK_VECTOR_NULL_TERMINATED 1
#include "vectorimpl.c"
#define GTK_VECTOR_ELEMENT_TYPE int
#define GTK_VECTOR_NAME null_pre_free_int_vector
#define GTK_VECTOR_TYPE_NAME NullPreFreeIntVector
#define GTK_VECTOR_PREALLOC 100
#define GTK_VECTOR_FREE_FUNC int_free_func
#define GTK_VECTOR_NULL_TERMINATED 1
#include "vectorimpl.c"
int
main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
setlocale (LC_ALL, "C");
g_test_add_func ("/intvector/simple", int_vector_test_simple);
g_test_add_func ("/intvector/prealloc/simple", pre_int_vector_test_simple);
g_test_add_func ("/intvector/freefunc/simple", free_int_vector_test_simple);
g_test_add_func ("/intvector/prealloc/freefunc/simple", pre_free_int_vector_test_simple);
g_test_add_func ("/intvector/null/simple", null_int_vector_test_simple);
g_test_add_func ("/intvector/null/prealloc/simple", null_pre_int_vector_test_simple);
g_test_add_func ("/intvector/null/freefunc/simple", null_free_int_vector_test_simple);
g_test_add_func ("/intvector/null/prealloc/freefunc/simple", null_pre_free_int_vector_test_simple);
g_test_add_func ("/intvector/splice", int_vector_test_splice);
g_test_add_func ("/intvector/prealloc/splice", pre_int_vector_test_splice);
g_test_add_func ("/intvector/freefunc/splice", free_int_vector_test_splice);
g_test_add_func ("/intvector/prealloc/freefunc/splice", pre_free_int_vector_test_splice);
g_test_add_func ("/intvector/null/splice", null_int_vector_test_splice);
g_test_add_func ("/intvector/null/prealloc/splice", null_pre_int_vector_test_splice);
g_test_add_func ("/intvector/null/freefunc/splice", null_free_int_vector_test_splice);
g_test_add_func ("/intvector/null/prealloc/freefunc/splice", null_pre_free_int_vector_test_splice);
return g_test_run ();
}

Some files were not shown because too many files have changed in this diff Show More