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
228 changed files with 11490 additions and 13579 deletions
+2 -18
View File
@@ -19,8 +19,8 @@ variables:
COMMON_MESON_FLAGS: "--fatal-meson-warnings --werror"
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true -Dvulkan=yes"
FEATURE_FLAGS: "-Dcloudproviders=true"
MESON_TEST_TIMEOUT_MULTIPLIER: 3
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v20"
MESON_TEST_TIMEOUT_MULTIPLIER: 2
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v17"
FLATPAK_IMAGE: "registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master"
DOCS_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora-docs:v19"
@@ -180,22 +180,6 @@ static-scan:
- _scan_build/meson-logs
allow_failure: true
# Run tests with the address sanitizer. We need to turn off introspection,
# since it is incompatible with asan
asan-build:
image: $FEDORA_IMAGE
tags: [ privileged ]
stage: analysis
variables:
script:
- CC=clang meson --buildtype=debugoptimized -Db_sanitize=address -Db_lundef=false -Dintrospection=false _build
- ninja -C _build
- .gitlab-ci/run-tests.sh _build wayland
artifacts:
paths:
- _build/meson-logs
allow_failure: true
reference:
image: $DOCS_IMAGE
stage: docs
View File
-9
View File
@@ -35,13 +35,4 @@ branch, as well as their available versions.
- [ ] Add the new job to `.gitlab-ci.yml` referencing the image
- [ ] Open a merge request with your changes and let it run
### Checklist for Adding a new dependency to a CI image
Our images are layered, and the base (called fedora-base) contains
all the rpm payload. Therefore, adding a new dependency is a 2-step
process:
1. [ ] Build and upload fedora-base:$version+1
1. [ ] Build and upload fedora:$version+1 based on fedora-base:version+1
[registry]: https://gitlab.gnome.org/GNOME/gtk/container_registry
-2
View File
@@ -41,14 +41,12 @@ RUN dnf -y install \
itstool \
json-glib-devel \
lcov \
libasan \
libattr-devel \
libepoxy-devel \
libffi-devel \
libmount-devel \
librsvg2 \
libselinux-devel \
libubsan \
libXcomposite-devel \
libXcursor-devel \
libXcursor-devel \
+1 -1
View File
@@ -1,4 +1,4 @@
FROM registry.gitlab.gnome.org/gnome/gtk/fedora-base:v20
FROM registry.gitlab.gnome.org/gnome/gtk/fedora-base:v19
ARG HOST_USER_ID=5555
ENV HOST_USER_ID ${HOST_USER_ID}
-6
View File
@@ -7,14 +7,10 @@ srcdir=$( pwd )
builddir=$1
backend=$2
# Ignore memory leaks lower in dependencies
export LSAN_OPTIONS=suppressions=$srcdir/lsan.supp
case "${backend}" in
x11)
xvfb-run -a -s "-screen 0 1024x768x24" \
meson test -C ${builddir} \
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
--print-errorlogs \
--setup=${backend} \
--suite=gtk \
@@ -34,7 +30,6 @@ case "${backend}" in
export WAYLAND_DISPLAY=wayland-5
meson test -C ${builddir} \
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
--print-errorlogs \
--setup=${backend} \
--suite=gtk \
@@ -53,7 +48,6 @@ case "${backend}" in
export BROADWAY_DISPLAY=:5
meson test -C ${builddir} \
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
--print-errorlogs \
--setup=${backend} \
--suite=gtk \
-77
View File
@@ -1,80 +1,3 @@
Overview of Changes in GTK 3.99.0
=================================
* Add GtkEditableLabel
* Add GtkBookmarkList, a list model for bookmarks
* Add GtkStringList, a list model for strings
* Add GtkBitset, and use it for representing selections
* GtkTreeView:
- Make cell editing work again
* GtkSpinButton:
- Make autosizing work again
* Printing:
- Use GtkDropDown in the print dialog
* GtkApplication
- Support opening files on OS X
* GtkFileChooser:
- Fix libcloudproviders support
- Turn GtkFileFilter into a GtkFilter
- Simplify the api
* GtkGridView, GtkListView:
- Improve scrolling behavior
- Autoscroll and autoexpand during DND
* GtkScrolledWindow:
- Make autoscrolling work again
* GtkFilterListModel:
- Add incremental filtering
* GtkEntry:
- Make entry completion work again
- Drop action support from GtkEntryCompletion
* Inspector:
- Improve list model support
- Add direct navigation between objects
* GDK:
- Compress scroll events
- Keep a scroll history
- Clean up GdkDevice api
- Improve frame clock accuracy
* GSK:
- Use GL_ARB_framebuffer_object
* gtk-demo:
- Add incremental refill to the color grid
- Improve performance of the color grid
- Add an incrementally filtering word list
- Improve the sidebar
* Install print-editor as another demo
* Translation updates
Basque
Catalan
Chinese
Japanese
Kazakh
Lithuanian
Polish
Romanian
Spanish
Turkish
Ukrainian
Overview of Changes in GTK 3.98.5
=================================
+31 -45
View File
@@ -1,38 +1,29 @@
{
"app-id" : "org.gtk.WidgetFactory4",
"runtime" : "org.gnome.Platform",
"runtime-version" : "master",
"sdk" : "org.gnome.Sdk",
"command" : "gtk4-widget-factory",
"tags" : [
"devel",
"development",
"nightly"
],
"desktop-file-name-prefix" : "(Development) ",
"finish-args" : [
"app-id": "org.gtk.WidgetFactory4",
"runtime": "org.gnome.Platform",
"runtime-version": "master",
"sdk": "org.gnome.Sdk",
"command": "gtk4-widget-factory",
"tags": ["devel", "development", "nightly"],
"desktop-file-name-prefix": "(Development) ",
"finish-args": [
"--device=dri",
"--share=ipc",
"--socket=fallback-x11",
"--socket=wayland",
"--talk-name=org.gtk.vfs",
"--talk-name=org.gtk.vfs.*"
"--talk-name=org.gtk.vfs", "--talk-name=org.gtk.vfs.*"
],
"cleanup" : [
"cleanup": [
"/include",
"/lib/pkgconfig",
"/share/pkgconfig",
"/lib/pkgconfig", "/share/pkgconfig",
"/share/aclocal",
"/man",
"/share/man",
"/share/gtk-doc",
"*.la",
".a",
"/man", "/share/man", "/share/gtk-doc",
"*.la", ".a",
"/lib/girepository-1.0",
"/share/gir-1.0",
"/share/doc"
],
"modules" : [
"modules": [
{
"name" : "wayland",
"buildsystem" : "autotools",
@@ -48,18 +39,18 @@
]
},
{
"name" : "graphene",
"buildsystem" : "meson",
"builddir" : true,
"config-opts" : [
"name": "graphene",
"buildsystem": "meson",
"builddir": true,
"config-opts": [
"--libdir=/app/lib",
"-Dtests=false",
"-Dbenchmarks=false"
],
"sources" : [
"sources": [
{
"type" : "git",
"url" : "https://github.com/ebassi/graphene.git"
"type": "git",
"url": "https://github.com/ebassi/graphene.git"
}
]
},
@@ -67,7 +58,7 @@
"name" : "libsass",
"buildsystem" : "meson",
"builddir" : true,
"config-opts" : [
"config-opts": [
"--libdir=/app/lib"
],
"sources" : [
@@ -82,7 +73,7 @@
"name" : "sassc",
"buildsystem" : "meson",
"builddir" : true,
"config-opts" : [
"config-opts": [
"--libdir=/app/lib"
],
"sources" : [
@@ -94,23 +85,18 @@
]
},
{
"name" : "gtk",
"buildsystem" : "meson",
"builddir" : true,
"config-opts" : [
"name": "gtk",
"buildsystem": "meson",
"builddir": true,
"config-opts": [
"--libdir=/app/lib"
],
"sources" : [
"sources": [
{
"type" : "git",
"url" : "https://gitlab.gnome.org/GNOME/gtk.git"
"type": "git",
"url": "https://gitlab.gnome.org/GNOME/gtk.git"
}
]
}
],
"build-options" : {
"env" : {
"DBUS_SESSION_BUS_ADDRESS" : "''"
}
}
]
}
+3 -15
View File
@@ -15,13 +15,7 @@ if 'DESTDIR' not in os.environ:
gtk_immodule_dir = os.path.join(gtk_moduledir, 'immodules')
print('Compiling GSettings schemas...')
glib_compile_schemas = subprocess.check_output(['pkg-config',
'--variable=glib_compile_schemas',
'gio-2.0']).strip()
if not os.path.exists(glib_compile_schemas):
# pkg-config variables only available since GLib 2.62.0.
glib_compile_schemas = 'glib-compile-schemas'
subprocess.call([glib_compile_schemas,
subprocess.call(['glib-compile-schemas',
os.path.join(gtk_datadir, 'glib-2.0', 'schemas')])
print('Updating icon cache...')
@@ -30,14 +24,8 @@ if 'DESTDIR' not in os.environ:
print('Updating module cache for print backends...')
os.makedirs(gtk_printmodule_dir, exist_ok=True)
gio_querymodules = subprocess.check_output(['pkg-config',
'--variable=gio_querymodules',
'gio-2.0']).strip()
if not os.path.exists(gio_querymodules):
# pkg-config variables only available since GLib 2.62.0.
gio_querymodules = 'gio-querymodules'
subprocess.call([gio_querymodules, gtk_printmodule_dir])
subprocess.call(['gio-querymodules', gtk_printmodule_dir])
print('Updating module cache for input methods...')
os.makedirs(gtk_immodule_dir, exist_ok=True)
subprocess.call([gio_querymodules, gtk_immodule_dir])
subprocess.call(['gio-querymodules', gtk_immodule_dir])
+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>
+1 -4
View File
@@ -144,7 +144,6 @@ do_listview_applauncher (GtkWidget *do_widget)
{
GtkWidget *list, *sw;
GListModel *model;
GtkSelectionModel *selection;
GtkListItemFactory *factory;
/* Create a window and set a few defaults */
@@ -182,10 +181,8 @@ do_listview_applauncher (GtkWidget *do_widget)
* to create as many listitems as it needs to show itself to the user.
*/
model = create_application_list ();
selection = GTK_SELECTION_MODEL (gtk_single_selection_new (model));
gtk_list_view_set_model (GTK_LIST_VIEW (list), selection);
gtk_list_view_set_model (GTK_LIST_VIEW (list), model);
g_object_unref (model);
g_object_unref (selection);
/* List widgets should always be contained in a #GtkScrolledWindow,
* because otherwise they might get too large or they might not
+1 -1
View File
@@ -491,7 +491,7 @@ do_listview_clocks (GtkWidget *do_widget)
model = create_clocks_model ();
selection = gtk_no_selection_new (model);
gtk_grid_view_set_model (GTK_GRID_VIEW (gridview), GTK_SELECTION_MODEL (selection));
gtk_grid_view_set_model (GTK_GRID_VIEW (gridview), G_LIST_MODEL (selection));
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), gridview);
g_object_unref (selection);
g_object_unref (model);
+7 -9
View File
@@ -662,8 +662,7 @@ create_color_grid (void)
{
GtkWidget *gridview;
GtkListItemFactory *factory;
GListModel *model;
GtkSelectionModel *selection;
GListModel *model, *selection;
gridview = gtk_grid_view_new ();
gtk_scrollable_set_hscroll_policy (GTK_SCROLLABLE (gridview), GTK_SCROLL_NATURAL);
@@ -679,7 +678,7 @@ create_color_grid (void)
model = G_LIST_MODEL (gtk_sort_list_model_new (gtk_color_list_new (0), NULL));
selection = GTK_SELECTION_MODEL (gtk_multi_selection_new (model));
selection = G_LIST_MODEL (gtk_multi_selection_new (model));
gtk_grid_view_set_model (GTK_GRID_VIEW (gridview), selection);
g_object_unref (selection);
g_object_unref (model);
@@ -858,7 +857,7 @@ do_listview_colors (GtkWidget *do_widget)
guint len;
GtkWidget *selection_view;
GListModel *selection_filter;
GtkSelectionModel *selection;
GListModel *no_selection;
GtkWidget *grid;
GtkWidget *selection_size_label;
GtkWidget *selection_average_picture;
@@ -946,13 +945,12 @@ do_listview_colors (GtkWidget *do_widget)
g_signal_connect (selection_filter, "items-changed", G_CALLBACK (update_selection_count), selection_size_label);
g_signal_connect (selection_filter, "items-changed", G_CALLBACK (update_selection_average), selection_average_picture);
selection = GTK_SELECTION_MODEL (gtk_no_selection_new (selection_filter));
gtk_grid_view_set_model (GTK_GRID_VIEW (selection_view), selection);
no_selection = G_LIST_MODEL (gtk_no_selection_new (selection_filter));
gtk_grid_view_set_model (GTK_GRID_VIEW (selection_view), no_selection);
g_object_unref (selection_filter);
g_object_unref (selection);
g_object_unref (no_selection);
model = gtk_multi_selection_get_model (GTK_MULTI_SELECTION (model));
g_object_ref (model);
g_object_get (model, "model", &model, NULL);
selection_info_toggle = gtk_toggle_button_new ();
gtk_button_set_icon_name (GTK_BUTTON (selection_info_toggle), "emblem-important-symbolic");
+3 -3
View File
@@ -1,11 +1,11 @@
listview.viewswitcher {
list.viewswitcher {
border: 1px solid gray;
}
listview.viewswitcher > row {
list.viewswitcher > row {
padding: 5px;
}
listview.viewswitcher row:selected {
list.viewswitcher row:selected {
background: gray;
}
+8 -4
View File
@@ -215,6 +215,7 @@ transform_settings_to_keys (GBinding *binding,
GtkFilterListModel *filter_model;
GtkFilter *filter;
GtkNoSelection *selection_model;
GtkExpression *expression;
char **keys;
guint i;
@@ -245,8 +246,11 @@ transform_settings_to_keys (GBinding *binding,
gtk_column_view_get_sorter (GTK_COLUMN_VIEW (data)));
g_object_unref (store);
filter = gtk_string_filter_new (gtk_property_expression_new (SETTINGS_TYPE_KEY, NULL, "name"));
expression = gtk_property_expression_new (SETTINGS_TYPE_KEY, NULL, "name");
filter = gtk_string_filter_new ();
gtk_string_filter_set_expression (GTK_STRING_FILTER (filter), expression);
filter_model = gtk_filter_list_model_new (G_LIST_MODEL (sort_model), filter);
gtk_expression_unref (expression);
g_object_unref (sort_model);
g_set_object (&current_filter, filter);
@@ -345,7 +349,7 @@ do_listview_settings (GtkWidget *do_widget)
GtkWidget *listview, *columnview;
GListModel *model;
GtkTreeListModel *treemodel;
GtkSelectionModel *selection;
GtkSingleSelection *selection;
GtkBuilderScope *scope;
GtkBuilder *builder;
GtkColumnViewColumn *name_column;
@@ -409,14 +413,14 @@ do_listview_settings (GtkWidget *do_widget)
create_settings_model,
NULL,
NULL);
selection = GTK_SELECTION_MODEL (gtk_single_selection_new (G_LIST_MODEL (treemodel)));
selection = gtk_single_selection_new (G_LIST_MODEL (treemodel));
g_object_bind_property_full (selection, "selected-item",
columnview, "model",
G_BINDING_SYNC_CREATE,
transform_settings_to_keys,
NULL,
columnview, NULL);
gtk_list_view_set_model (GTK_LIST_VIEW (listview), selection);
gtk_list_view_set_model (GTK_LIST_VIEW (listview), G_LIST_MODEL (selection));
g_object_unref (selection);
g_object_unref (treemodel);
g_object_unref (model);
+2 -3
View File
@@ -281,8 +281,7 @@ GtkWidget *
create_weather_view (void)
{
GtkWidget *listview;
GListModel *model;
GtkSelectionModel *selection;
GListModel *model, *selection;
GtkListItemFactory *factory;
factory = gtk_signal_list_item_factory_new ();
@@ -292,7 +291,7 @@ create_weather_view (void)
gtk_orientable_set_orientation (GTK_ORIENTABLE (listview), GTK_ORIENTATION_HORIZONTAL);
gtk_list_view_set_show_separators (GTK_LIST_VIEW (listview), TRUE);
model = create_weather_model ();
selection = GTK_SELECTION_MODEL (gtk_no_selection_new (model));
selection = G_LIST_MODEL (gtk_no_selection_new (model));
gtk_list_view_set_model (GTK_LIST_VIEW (listview), selection);
g_object_unref (selection);
g_object_unref (model);
-238
View File
@@ -1,238 +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;
GtkSelectionModel *selection;
GtkStringList *stringlist;
GtkFilter *filter;
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 (gtk_property_expression_new (GTK_TYPE_STRING_OBJECT, NULL, "string"));
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_widget_set_vexpand (sw, TRUE);
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_SELECTION_MODEL (gtk_no_selection_new (G_LIST_MODEL (filter_model)));
gtk_list_view_set_model (GTK_LIST_VIEW (listview), 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;
}
+9 -118
View File
@@ -16,9 +16,8 @@ static GtkWidget *source_view;
static gchar *current_file = NULL;
static GtkWidget *notebook;
static GtkSelectionModel *selection;
static GtkSingleSelection *selection;
static GtkWidget *toplevel;
static char **search_needle;
typedef struct _GtkDemo GtkDemo;
struct _GtkDemo
@@ -220,7 +219,7 @@ activate_run (GSimpleAction *action,
GVariant *parameter,
gpointer window)
{
GtkTreeListRow *row = gtk_single_selection_get_selected_item (GTK_SINGLE_SELECTION (selection));
GtkTreeListRow *row = gtk_single_selection_get_selected_item (selection);
GtkDemo *demo = gtk_tree_list_row_get_item (row);
gtk_demo_run (demo, window);
@@ -932,7 +931,7 @@ activate_cb (GtkWidget *widget,
guint position,
gpointer window)
{
GtkTreeListRow *row = g_list_model_get_item (G_LIST_MODEL (gtk_list_view_get_model (GTK_LIST_VIEW (widget))), position);
GtkTreeListRow *row = g_list_model_get_item (gtk_list_view_get_model (GTK_LIST_VIEW (widget)), position);
GtkDemo *demo = gtk_tree_list_row_get_item (row);
gtk_demo_run (demo, window);
@@ -946,18 +945,7 @@ selection_cb (GtkSingleSelection *sel,
gpointer user_data)
{
GtkTreeListRow *row = gtk_single_selection_get_selected_item (sel);
GtkDemo *demo;
gtk_widget_set_sensitive (GTK_WIDGET (notebook), !!row);
if (!row)
{
gtk_window_set_title (GTK_WINDOW (toplevel), "No match");
return;
}
demo = gtk_tree_list_row_get_item (row);
GtkDemo *demo = gtk_tree_list_row_get_item (row);
if (demo->filename)
load_file (demo->name, demo->filename);
@@ -965,84 +953,6 @@ selection_cb (GtkSingleSelection *sel,
gtk_window_set_title (GTK_WINDOW (toplevel), demo->title);
}
static gboolean
filter_demo (GtkDemo *demo)
{
int i;
/* Show only if the name maches every needle */
for (i = 0; search_needle[i]; i++)
{
if (!demo->title)
return FALSE;
if (g_str_match_string (search_needle[i], demo->title, TRUE))
continue;
return FALSE;
}
return TRUE;
}
static gboolean
demo_filter_by_name (GtkTreeListRow *row,
GtkFilterListModel *model)
{
GListModel *children;
GtkDemo *demo;
guint i, n;
/* Show all items if search is empty */
if (!search_needle || !search_needle[0] || !*search_needle[0])
return TRUE;
g_assert (GTK_IS_TREE_LIST_ROW (row));
g_assert (GTK_IS_FILTER_LIST_MODEL (model));
children = gtk_tree_list_row_get_children (row);
if (children)
{
n = g_list_model_get_n_items (children);
for (i = 0; i < n; i++)
{
demo = g_list_model_get_item (children, i);
g_assert (GTK_IS_DEMO (demo));
if (filter_demo (demo))
{
g_object_unref (demo);
return TRUE;
}
g_object_unref (demo);
}
}
demo = gtk_tree_list_row_get_item (row);
g_assert (GTK_IS_DEMO (demo));
return filter_demo (demo);
}
static void
demo_search_changed_cb (GtkSearchEntry *entry,
GtkFilter *filter)
{
const char *text;
g_assert (GTK_IS_SEARCH_ENTRY (entry));
g_assert (GTK_IS_FILTER (filter));
text = gtk_editable_get_text (GTK_EDITABLE (entry));
g_clear_pointer (&search_needle, g_strfreev);
if (text && *text)
search_needle = g_strsplit (text, " ", 0);
gtk_filter_changed (filter, GTK_FILTER_CHANGE_DIFFERENT);
}
static GListModel *
create_demo_model (void)
{
@@ -1097,25 +1007,13 @@ get_child_model (gpointer item,
return NULL;
}
static void
clear_search (GtkSearchBar *bar)
{
if (!gtk_search_bar_get_search_mode (bar))
{
GtkWidget *entry = gtk_search_bar_get_child (GTK_SEARCH_BAR (bar));
gtk_editable_set_text (GTK_EDITABLE (entry), "");
}
}
static void
activate (GApplication *app)
{
GtkBuilder *builder;
GListModel *listmodel;
GtkTreeListModel *treemodel;
GtkWidget *window, *listview, *search_entry, *search_bar;
GtkFilterListModel *filter_model;
GtkFilter *filter;
GtkWidget *window, *listview;
static GActionEntry win_entries[] = {
{ "run", activate_run, NULL, NULL, NULL }
@@ -1136,8 +1034,6 @@ activate (GApplication *app)
toplevel = GTK_WIDGET (window);
listview = GTK_WIDGET (gtk_builder_get_object (builder, "listview"));
g_signal_connect (listview, "activate", G_CALLBACK (activate_cb), window);
search_bar = GTK_WIDGET (gtk_builder_get_object (builder, "searchbar"));
g_signal_connect (search_bar, "notify::search-mode-enabled", G_CALLBACK (clear_search), NULL);
listmodel = create_demo_model ();
treemodel = gtk_tree_list_model_new (FALSE,
@@ -1146,17 +1042,11 @@ activate (GApplication *app)
get_child_model,
NULL,
NULL);
filter_model = gtk_filter_list_model_new (G_LIST_MODEL (treemodel), NULL);
filter = gtk_custom_filter_new ((GtkCustomFilterFunc)demo_filter_by_name, filter_model, NULL);
gtk_filter_list_model_set_filter (filter_model, filter);
search_entry = GTK_WIDGET (gtk_builder_get_object (builder, "search-entry"));
g_signal_connect (search_entry, "search-changed", G_CALLBACK (demo_search_changed_cb), filter);
selection = GTK_SELECTION_MODEL (gtk_single_selection_new (G_LIST_MODEL (filter_model)));
selection = gtk_single_selection_new (G_LIST_MODEL (treemodel));
g_signal_connect (selection, "notify::selected-item", G_CALLBACK (selection_cb), NULL);
gtk_list_view_set_model (GTK_LIST_VIEW (listview), selection);
gtk_list_view_set_model (GTK_LIST_VIEW (listview), G_LIST_MODEL (selection));
selection_cb (GTK_SINGLE_SELECTION (selection), NULL, NULL);
selection_cb (selection, NULL, NULL);
g_object_unref (builder);
}
@@ -1249,6 +1139,7 @@ out:
demo = (func) (window);
gtk_window_set_transient_for (GTK_WINDOW (demo), GTK_WINDOW (window));
gtk_window_set_modal (GTK_WINDOW (demo), TRUE);
g_signal_connect_swapped (G_OBJECT (demo), "destroy", G_CALLBACK (g_application_quit), app);
}
+5 -22
View File
@@ -55,29 +55,12 @@
<property name="hscrollbar-policy">never</property>
<property name="min-content-width">150</property>
<child>
<object class="GtkBox">
<property name="width-request">220</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkSearchBar" id="searchbar">
<property name="key-capture-widget">window</property>
<child>
<object class="GtkSearchEntry" id="search-entry"/>
</child>
<object class="GtkListView" id="listview">
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="resource">/ui/main-listitem.ui</property>
</object>
</child>
<child>
<object class="GtkListView" id="listview">
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="resource">/ui/main-listitem.ui</property>
</object>
</property>
</object>
</child>
</property>
</object>
</child>
</object>
-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',
@@ -1,88 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="128px" viewBox="0 0 128 128" width="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<linearGradient id="a" gradientUnits="userSpaceOnUse" x1="43.000351" x2="85.000351" y1="39.000164" y2="39.000164">
<stop offset="0" stop-color="#26a269"/>
<stop offset="0.0934161" stop-color="#84e3b7"/>
<stop offset="0.330831" stop-color="#26a269"/>
<stop offset="0.686952" stop-color="#26a269"/>
<stop offset="0.89736" stop-color="#175e3c"/>
<stop offset="1" stop-color="#26a269"/>
</linearGradient>
<linearGradient id="b" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#c0bfbc"/>
<stop offset="0.154754" stop-color="#ffffff"/>
<stop offset="0.433722" stop-color="#bdbbb5"/>
<stop offset="0.650505" stop-color="#c1c0ba"/>
<stop offset="0.825253" stop-color="#ffffff"/>
<stop offset="1" stop-color="#c0bfbc"/>
</linearGradient>
<linearGradient id="c" gradientTransform="matrix(0.0811899 -0.046875 0.069079 0.119648 307.03142 127.069456)" x1="-1710.210571" x2="-1774.45166" xlink:href="#b" y1="-1202.376709" y2="-1202.376709"/>
<linearGradient id="d" gradientTransform="matrix(-0.0811899 -0.046875 -0.069079 0.119648 -177.242852 127.069447)" x1="-1710.210571" x2="-1774.45166" xlink:href="#b" y1="-1202.376709" y2="-1202.376709"/>
<linearGradient id="e" gradientUnits="userSpaceOnUse" x1="14" x2="56" y1="94.999964" y2="94.999964">
<stop offset="0" stop-color="#813d9c"/>
<stop offset="0.109119" stop-color="#b378ca"/>
<stop offset="0.241583" stop-color="#813d9c"/>
<stop offset="0.731841" stop-color="#813d9c"/>
<stop offset="0.872163" stop-color="#4d255d"/>
<stop offset="1" stop-color="#813d9c"/>
</linearGradient>
<linearGradient id="f" gradientUnits="userSpaceOnUse" x1="72" x2="114" y1="94.999964" y2="94.999964">
<stop offset="0" stop-color="#e66100"/>
<stop offset="0.0678478" stop-color="#ff903e"/>
<stop offset="0.168852" stop-color="#e66100"/>
<stop offset="0.886626" stop-color="#e66100"/>
<stop offset="1" stop-color="#9d4200"/>
</linearGradient>
<clipPath id="g">
<rect height="128" width="128"/>
</clipPath>
<clipPath id="h">
<rect height="128" width="128"/>
</clipPath>
<filter id="i" height="100%" width="100%" x="0%" y="0%">
<feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
</filter>
<mask id="j">
<g clip-path="url(#h)" filter="url(#i)">
<g clip-path="url(#g)">
<path d="m 51 18 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="url(#a)"/>
<path d="m 51 12 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#57e389"/>
<path d="m 76.976562 55.453125 c 1.480469 -0.855469 3.371094 -0.347656 4.226563 1.132813 l 6.742187 11.679687 c 0.855469 1.480469 0.347657 3.371094 -1.132812 4.226563 c -1.480469 0.851562 -3.371094 0.347656 -4.226562 -1.132813 l -6.742188 -11.679687 c -0.855469 -1.480469 -0.347656 -3.371094 1.132812 -4.226563 z m 0 0" fill="url(#c)"/>
<path d="m 52.8125 55.453125 c -1.480469 -0.855469 -3.371094 -0.347656 -4.226562 1.132813 l -6.742188 11.679687 c -0.855469 1.480469 -0.347656 3.371094 1.132812 4.226563 c 1.480469 0.851562 3.371094 0.347656 4.226563 -1.132813 l 6.742187 -11.679687 c 0.855469 -1.480469 0.347657 -3.371094 -1.132812 -4.226563 z m 0 0" fill="url(#d)"/>
<path d="m 22 74 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="url(#e)"/>
<path d="m 22 68 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#dc8add"/>
<path d="m 80 74 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="url(#f)"/>
<path d="m 80 68 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#ffa348"/>
</g>
</g>
</mask>
<mask id="k">
<g filter="url(#i)">
<rect fill-opacity="0.8" height="128" width="128"/>
</g>
</mask>
<linearGradient id="l" gradientTransform="matrix(0 0.37 -0.98462 0 295.38501 -30.360001)" gradientUnits="userSpaceOnUse" x1="300" x2="428" y1="235" y2="235">
<stop offset="0" stop-color="#f9f06b"/>
<stop offset="1" stop-color="#f5c211"/>
</linearGradient>
<clipPath id="m">
<rect height="128" width="128"/>
</clipPath>
<clipPath id="n">
<rect height="128" width="128"/>
</clipPath>
<path d="m 51 18 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="url(#a)"/>
<path d="m 51 12 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#57e389"/>
<path d="m 76.976562 55.453125 c 1.480469 -0.855469 3.371094 -0.347656 4.226563 1.132813 l 6.742187 11.679687 c 0.855469 1.480469 0.347657 3.371094 -1.132812 4.226563 c -1.480469 0.851562 -3.371094 0.347656 -4.226562 -1.132813 l -6.742188 -11.679687 c -0.855469 -1.480469 -0.347656 -3.371094 1.132812 -4.226563 z m 0 0" fill="url(#c)"/>
<path d="m 52.8125 55.453125 c -1.480469 -0.855469 -3.371094 -0.347656 -4.226562 1.132813 l -6.742188 11.679687 c -0.855469 1.480469 -0.347656 3.371094 1.132812 4.226563 c 1.480469 0.851562 3.371094 0.347656 4.226563 -1.132813 l 6.742187 -11.679687 c 0.855469 -1.480469 0.347657 -3.371094 -1.132812 -4.226563 z m 0 0" fill="url(#d)"/>
<path d="m 22 74 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="url(#e)"/>
<path d="m 22 68 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#dc8add"/>
<path d="m 80 74 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="url(#f)"/>
<path d="m 80 68 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#ffa348"/>
<g clip-path="url(#n)" mask="url(#j)">
<g clip-path="url(#m)" mask="url(#k)">
<path d="m 128 80.640625 v 47.359375 h -128 v -47.359375 z m 0 0" fill="url(#l)"/>
<path d="m 13.308594 80.640625 l 47.355468 47.359375 h 21.214844 l -47.359375 -47.359375 z m 42.421875 0 l 47.363281 47.359375 h 21.214844 l -47.363282 -47.359375 z m 42.429687 0 l 29.839844 29.839844 v -21.210938 l -8.628906 -8.628906 z m -98.160156 7.90625 v 21.214844 l 18.238281 18.238281 h 21.214844 z m 0 0"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 7.4 KiB

@@ -1,44 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="128px" viewBox="0 0 128 128" width="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<linearGradient id="a" gradientUnits="userSpaceOnUse" x1="43.000351" x2="85.000351" y1="39.000164" y2="39.000164">
<stop offset="0" stop-color="#26a269"/>
<stop offset="0.0934161" stop-color="#84e3b7"/>
<stop offset="0.330831" stop-color="#26a269"/>
<stop offset="0.686952" stop-color="#26a269"/>
<stop offset="0.89736" stop-color="#175e3c"/>
<stop offset="1" stop-color="#26a269"/>
</linearGradient>
<linearGradient id="b" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#c0bfbc"/>
<stop offset="0.154754" stop-color="#ffffff"/>
<stop offset="0.433722" stop-color="#bdbbb5"/>
<stop offset="0.650505" stop-color="#c1c0ba"/>
<stop offset="0.825253" stop-color="#ffffff"/>
<stop offset="1" stop-color="#c0bfbc"/>
</linearGradient>
<linearGradient id="c" gradientTransform="matrix(0.0811899 -0.046875 0.069079 0.119648 307.03142 127.069456)" x1="-1710.210571" x2="-1774.45166" xlink:href="#b" y1="-1202.376709" y2="-1202.376709"/>
<linearGradient id="d" gradientTransform="matrix(-0.0811899 -0.046875 -0.069079 0.119648 -177.242852 127.069447)" x1="-1710.210571" x2="-1774.45166" xlink:href="#b" y1="-1202.376709" y2="-1202.376709"/>
<linearGradient id="e" gradientUnits="userSpaceOnUse" x1="14" x2="56" y1="94.999964" y2="94.999964">
<stop offset="0" stop-color="#813d9c"/>
<stop offset="0.109119" stop-color="#b378ca"/>
<stop offset="0.241583" stop-color="#813d9c"/>
<stop offset="0.731841" stop-color="#813d9c"/>
<stop offset="0.872163" stop-color="#4d255d"/>
<stop offset="1" stop-color="#813d9c"/>
</linearGradient>
<linearGradient id="f" gradientUnits="userSpaceOnUse" x1="72" x2="114" y1="94.999964" y2="94.999964">
<stop offset="0" stop-color="#e66100"/>
<stop offset="0.0678478" stop-color="#ff903e"/>
<stop offset="0.168852" stop-color="#e66100"/>
<stop offset="0.886626" stop-color="#e66100"/>
<stop offset="1" stop-color="#9d4200"/>
</linearGradient>
<path d="m 51 18 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="url(#a)"/>
<path d="m 51 12 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#57e389"/>
<path d="m 76.976562 55.453125 c 1.480469 -0.855469 3.371094 -0.347656 4.226563 1.132813 l 6.742187 11.679687 c 0.855469 1.480469 0.347657 3.371094 -1.132812 4.226563 c -1.480469 0.851562 -3.371094 0.347656 -4.226562 -1.132813 l -6.742188 -11.679687 c -0.855469 -1.480469 -0.347656 -3.371094 1.132812 -4.226563 z m 0 0" fill="url(#c)"/>
<path d="m 52.8125 55.453125 c -1.480469 -0.855469 -3.371094 -0.347656 -4.226562 1.132813 l -6.742188 11.679687 c -0.855469 1.480469 -0.347656 3.371094 1.132812 4.226563 c 1.480469 0.851562 3.371094 0.347656 4.226563 -1.132813 l 6.742187 -11.679687 c 0.855469 -1.480469 0.347657 -3.371094 -1.132812 -4.226563 z m 0 0" fill="url(#d)"/>
<path d="m 22 74 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="url(#e)"/>
<path d="m 22 68 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#dc8add"/>
<path d="m 80 74 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="url(#f)"/>
<path d="m 80 68 h 26 c 4.417969 0 8 3.582031 8 8 v 26 c 0 4.417969 -3.582031 8 -8 8 h -26 c -4.417969 0 -8 -3.582031 -8 -8 v -26 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#ffa348"/>
</svg>

Before

Width:  |  Height:  |  Size: 4.0 KiB

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
<path d="m 5.75 1 c -0.414062 0 -0.75 0.335938 -0.75 0.75 v 4.5 c 0 0.414062 0.335938 0.75 0.75 0.75 h 0.191406 l -1 2 h -3.191406 c -0.414062 0 -0.75 0.335938 -0.75 0.75 v 4.5 c 0 0.414062 0.335938 0.75 0.75 0.75 h 4.5 c 0.414062 0 0.75 -0.335938 0.75 -0.75 v -4.5 c 0 -0.414062 -0.335938 -0.75 -0.75 -0.75 h -0.191406 l 1 -2 h 1.882812 l 1 2 h -0.191406 c -0.414062 0 -0.75 0.335938 -0.75 0.75 v 4.5 c 0 0.414062 0.335938 0.75 0.75 0.75 h 4.5 c 0.414062 0 0.75 -0.335938 0.75 -0.75 v -4.5 c 0 -0.414062 -0.335938 -0.75 -0.75 -0.75 h -3.191406 l -1 -2 h 0.191406 c 0.414062 0 0.75 -0.335938 0.75 -0.75 v -4.5 c 0 -0.414062 -0.335938 -0.75 -0.75 -0.75 z m 0 0"/>
</svg>

Before

Width:  |  Height:  |  Size: 801 B

-9
View File
@@ -19,12 +19,3 @@ executable('gtk4-node-editor',
gui_app: true,
link_args: extra_demo_ldflags,
install: false)
# icons
icontheme_dir = join_paths(gtk_datadir, 'icons/hicolor')
foreach size: ['scalable', 'symbolic']
install_subdir('data/' + size,
install_dir: icontheme_dir
)
endforeach
+1 -1
View File
@@ -101,7 +101,7 @@ activate_about (GSimpleAction *action,
"website", "http://www.gtk.org",
"comments", "Program to test GTK rendering",
"authors", (const char *[]){ "Benjamin Otte", "Timm Bäder", NULL},
"logo-icon-name", "org.gtk.gtk4.NodeEditor.Devel",
"logo-icon-name", "text-editor-symbolic",
"title", "About GTK Node Editor",
"system-information", s->str,
NULL);
@@ -1,179 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="128px" viewBox="0 0 128 128" width="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient id="a" gradientTransform="matrix(0.232143 0 0 0.328947 -7.567033 263.82666)" gradientUnits="userSpaceOnUse" x1="88.595886" x2="536.595886" y1="-449.394012" y2="-449.394012">
<stop offset="0" stop-color="#acabae"/>
<stop offset="0.0384615" stop-color="#deddda"/>
<stop offset="0.0768555" stop-color="#c0bfbc"/>
<stop offset="0.923077" stop-color="#c0bfbc"/>
<stop offset="0.961538" stop-color="#deddda"/>
<stop offset="1" stop-color="#9a9996"/>
</linearGradient>
<linearGradient id="b" gradientUnits="userSpaceOnUse" x1="26.999876" x2="100.999876" y1="32.999688" y2="32.999688">
<stop offset="0" stop-color="#7e7c77"/>
<stop offset="0.3" stop-color="#9a9996"/>
<stop offset="1" stop-color="#9a9996"/>
</linearGradient>
<linearGradient id="c" gradientUnits="userSpaceOnUse" x1="67.467916" x2="67.467916" y1="83.999688" y2="36.782906">
<stop offset="0" stop-color="#deddda"/>
<stop offset="1" stop-color="#c0bfbc"/>
</linearGradient>
<clipPath id="d">
<path d="m 79 72 h 15 v 16 h -15 z m 0 0"/>
</clipPath>
<clipPath id="e">
<path d="m 93.21875 72.921875 l -14.21875 14.21875 h -4.0625 v -18.28125 h 18.28125 z m 0 0"/>
</clipPath>
<linearGradient id="f" gradientTransform="matrix(0 0.126951 0.126951 0 76.460862 36.359884)" gradientUnits="userSpaceOnUse" x1="344" x2="340" y1="76" y2="72">
<stop offset="0" stop-color="#d5d3cf"/>
<stop offset="1" stop-color="#ffffff"/>
</linearGradient>
<filter id="g" height="100%" width="100%" x="0%" y="0%">
<feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
</filter>
<mask id="h">
<g filter="url(#g)">
<rect fill-opacity="0.396" height="128" width="128"/>
</g>
</mask>
<linearGradient id="i" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#1c71d8"/>
<stop offset="0.323117" stop-color="#62a0ea"/>
<stop offset="0.59387" stop-color="#1b5aa6"/>
<stop offset="1" stop-color="#1c71d8"/>
</linearGradient>
<linearGradient id="j" gradientTransform="matrix(1.597748 1.597748 -1.06066 1.06066 -56.853041 -543.720139)" x1="224.504562" x2="231.453873" xlink:href="#i" y1="282.5" y2="282.5"/>
<radialGradient id="k" cx="227.599915" cy="201.029724" gradientTransform="matrix(4.072817 4.073078 -5.940048 5.939073 373.883117 -2098.049112)" gradientUnits="userSpaceOnUse" r="2.5">
<stop offset="0" stop-color="#93bdf1"/>
<stop offset="1" stop-color="#1a5fb4"/>
</radialGradient>
<linearGradient id="l" gradientTransform="matrix(2.121328 2.121328 -2.174353 2.174353 181.766074 -1021.145947)" gradientUnits="userSpaceOnUse" x1="226.90625" x2="228.86203" y1="288.75" y2="288.767151">
<stop offset="0" stop-color="#77767b"/>
<stop offset="0.443872" stop-color="#f6f5f4"/>
<stop offset="1" stop-color="#5e5c64"/>
</linearGradient>
<linearGradient id="m" gradientTransform="matrix(1.258421 1.258421 -1.06066 1.06066 57.381892 -503.024312)" gradientUnits="userSpaceOnUse" x1="223.1875" x2="233.0625" y1="278" y2="278">
<stop offset="0" stop-color="#ffa348"/>
<stop offset="0.265823" stop-color="#ffd7af"/>
<stop offset="0.734177" stop-color="#ff8d1c"/>
<stop offset="1" stop-color="#ffa348"/>
</linearGradient>
<linearGradient id="n" gradientTransform="matrix(1.573027 1.573027 -1.06066 1.06066 -14.348129 -574.754333)" x1="224.504562" x2="231.453873" xlink:href="#i" y1="282.5" y2="282.5"/>
<clipPath id="o">
<path d="m 79 72 h 15 v 16 h -15 z m 0 0"/>
</clipPath>
<clipPath id="p">
<path d="m 93.21875 72.921875 l -14.21875 14.21875 h -4.0625 v -18.28125 h 18.28125 z m 0 0"/>
</clipPath>
<mask id="q">
<g filter="url(#g)">
<rect fill-opacity="0.396" height="128" width="128"/>
</g>
</mask>
<clipPath id="r">
<rect height="152" width="192"/>
</clipPath>
<g id="s" clip-path="url(#r)">
<path d="m 29 112 c -4.433594 0 -8 -3.566406 -8 -8 v -2 c 0 4.433594 3.566406 8 8 8 h 88 c 4.433594 0 8 -3.566406 8 -8 v 2 c 0 4.433594 -3.566406 8 -8 8 z m 0 0" fill="#f6f5f4"/>
</g>
<clipPath id="t">
<rect height="128" width="128"/>
</clipPath>
<clipPath id="u">
<rect height="128" width="128"/>
</clipPath>
<mask id="v">
<g clip-path="url(#u)" filter="url(#g)">
<g clip-path="url(#t)">
<path d="m 21 16 c -4.433594 0 -8 3.566406 -8 8 v 84 c 0 4.433594 3.566406 8 8 8 h 4 v -4 h 80 v 4 h 4 c 4.433594 0 8 -3.566406 8 -8 v -84 c 0 -4.433594 -3.566406 -8 -8 -8 z m 0 0" fill="url(#a)"/>
<path d="m 21 12 h 88 c 4.417969 0 8 3.582031 8 8 v 68 c 0 4.417969 -3.582031 8 -8 8 h -88 c -4.417969 0 -8 -3.582031 -8 -8 v -68 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#deddda"/>
<path d="m 27 28 h 74 v 10 h -74 z m 0 0" fill="url(#b)"/>
<path d="m 27 38 h 74 v 46 h -74 z m 0 0" fill="url(#c)"/>
<path d="m 24 33 c 0 1.65625 -1.34375 3 -3 3 s -3 -1.34375 -3 -3 s 1.34375 -3 3 -3 s 3 1.34375 3 3 z m 0 0" fill="#bf5f00" fill-opacity="0.964567"/>
<path d="m 18 40 h 6 v 12 h -6 z m 0 0" fill="#acacac" fill-opacity="0.984252"/>
<path d="m 18 40 h 6 v 10 h -6 z m 0 0" fill="#d1d1d1" fill-opacity="0.984252"/>
<path d="m 37 36 h 56 v 44 h -56 z m 0 0" fill="#deddda" fill-opacity="0.984252"/>
<path d="m 37 34 h 56 c 1.105469 0 2 0.894531 2 2 s -0.894531 2 -2 2 h -56 c -1.105469 0 -2 -0.894531 -2 -2 s 0.894531 -2 2 -2 z m 0 0" fill-opacity="0.940945"/>
<path d="m 37 36.859375 h 56 v 36.925781 l -14.125 14.214844 h -41.875 z m 0 0" fill="#9a9996" fill-opacity="0.984252"/>
<path d="m 37 36 h 56 v 36.925781 l -14.125 14.214844 h -41.875 z m 0 0" fill="#f6f5f4" fill-opacity="0.984252"/>
<g clip-path="url(#o)">
<g clip-path="url(#p)">
<path d="m 79 77.386719 v 9.351562 c 0 2.464844 2 4.464844 4.464844 4.464844 h 9.351562 c 2.464844 0 4.464844 -2 4.464844 -4.464844 v -9.351562 c 0 -2.464844 -2 -4.464844 -4.464844 -4.464844 h -9.351562 c -2.464844 0 -4.464844 2 -4.464844 4.464844 z m 0 0" fill="url(#f)"/>
</g>
</g>
<path d="m 27 100 h 76 c 1.109375 0 2 0.890625 2 2 v 10 h -80 v -10 c 0 -1.109375 0.890625 -2 2 -2 z m 0 0" fill="#5e5c64" fill-opacity="0.940945"/>
<path d="m 27 102 h 76 c 1.109375 0 2 0.890625 2 2 v 10 h -80 v -10 c 0 -1.109375 0.890625 -2 2 -2 z m 0 0" fill="#9a9996"/>
<path d="m 13 106 v 2 c 0 4.433594 3.566406 8 8 8 h 4 v -2 h -4 c -4.433594 0 -8 -3.566406 -8 -8 z m 104 0 c 0 4.433594 -3.566406 8 -8 8 h -4 v 2 h 4 c 4.433594 0 8 -3.566406 8 -8 z m -92 6 v 2 h 80 v -2 z m 0 0" fill="#9e9c99" fill-opacity="0.366142"/>
<path d="m 27 38 v 46 l 6 -46 z m 0 0" fill="#7e7c77" fill-opacity="0.11811"/>
<path d="m 24 32 c 0 1.65625 -1.34375 3 -3 3 s -3 -1.34375 -3 -3 s 1.34375 -3 3 -3 s 3 1.34375 3 3 z m 0 0" fill="#ffa348" fill-opacity="0.964567"/>
<use mask="url(#q)" transform="matrix(1 0 0 1 -8 -16)" xlink:href="#s"/>
<path d="m 89.503906 31.144531 l 10.066406 10.066407 l -41.71875 41.71875 l -10.066406 -10.066407 z m 0 0" fill="#ffa348"/>
<path d="m 88.246094 29.886719 l 7.550781 7.550781 l -41.71875 41.71875 l -7.550781 -7.550781 z m 0 0" fill="#ff7800"/>
<path d="m 86.789062 28.429688 l 2.515626 2.515624 l -41.71875 41.71875 l -2.515626 -2.515624 z m 0 0" fill="#ffbe6f"/>
<path d="m 121.898438 -0.101562 c -4.855469 0.921874 -11.730469 5.152343 -18.140626 11.558593 l -16.96875 16.972657 l 12.78125 12.78125 l 16.972657 -16.972657 c 6.40625 -6.40625 10.636719 -13.28125 11.558593 -18.136719 z m 0 0" fill="url(#j)"/>
<path d="m 110.011719 13.882812 c -2.1875 -0.398437 -5.421875 0.988282 -8.167969 3.730469 l -11.871094 11.875 l -6.6875 6.6875 c -4.800781 4.800781 -9.234375 12.007813 -9.648437 13.042969 c -0.484375 1.207031 -0.449219 2.730469 0.953125 4.136719 c 1.40625 1.40625 2.917968 1.441406 4.136718 0.953125 c 1.035157 -0.414063 8.292969 -4.984375 13.042969 -9.648438 l 2.402344 -2.398437 l 16.160156 -16.160157 c 2.742188 -2.746093 4.128907 -5.976562 3.730469 -8.167968 c -0.742188 1.390625 -1.859375 2.902344 -3.308594 4.347656 l -13.996094 13.996094 l -5.089843 -5.089844 l 13.996093 -13.996094 c 1.445313 -1.445312 2.960938 -2.566406 4.347657 -3.308594 z m 0 0" fill="url(#k)"/>
<path d="m 95.273438 36.914062 l -2.960938 2.960938 l -2.398438 2.402344 c -4.90625 5.101562 -11.855468 10.828125 -11.855468 10.828125 c 1.011718 -0.433594 8.167968 -5.101563 12.914062 -9.769531 l 2.402344 -2.402344 l 2.960938 -2.957032 z m 0 0" fill="#62a0ea"/>
<path d="m 87.320312 26.835938 l 13.789063 13.789062 c 0.292969 0.292969 0.292969 0.769531 0 1.0625 s -0.769531 0.292969 -1.0625 0 l -13.789063 -13.789062 c -0.292968 -0.292969 -0.292968 -0.769532 0 -1.0625 c 0.292969 -0.289063 0.769532 -0.289063 1.0625 0 z m 0 0" fill="#3584e4"/>
<path d="m 42.421875 89.765625 c -3 3 -6.382813 4.484375 -7.554687 3.3125 c -1.171876 -1.171875 0.3125 -4.554687 3.3125 -7.554687 c 3.003906 -3.003907 6.386718 -4.488282 7.558593 -3.316407 s -0.3125 4.554688 -3.316406 7.558594 z m 0 0" fill="url(#l)"/>
<path d="m 45.269531 70.347656 l -7.851562 12.511719 l 7.835937 7.925781 l 12.597656 -7.855468 z m -6.039062 13.171875 l 5.449219 5.449219 c 0.347656 0.347656 0.449218 0.933594 0.097656 1.160156 c -0.886719 0.570313 -2.9375 1.539063 -2.9375 1.539063 c -0.25 0.128906 -0.539063 0.164062 -0.773438 -0.066407 l -4.546875 -4.550781 c -0.234375 -0.230469 -0.207031 -0.527343 -0.066406 -0.773437 l 1.617187 -2.859375 c 0.207032 -0.363281 0.8125 -0.25 1.160157 0.101562 z m 0 0" fill="url(#m)"/>
<path d="m 43.332031 74.777344 l 9.867188 9.867187 c 0.394531 0.390625 0.476562 0.871094 0.128906 1.066407 l -7.710937 5.253906 c -0.308594 0.210937 -0.785157 0.160156 -1.171876 -0.226563 l -6.984374 -6.988281 c -0.386719 -0.386719 -0.4375 -0.859375 -0.230469 -1.167969 l 5.234375 -7.8125 c 0.125 -0.285156 0.558594 -0.304687 0.867187 0.007813 z m 0 0" fill="url(#n)"/>
</g>
</g>
</mask>
<mask id="w">
<g filter="url(#g)">
<rect fill-opacity="0.8" height="128" width="128"/>
</g>
</mask>
<linearGradient id="x" gradientTransform="matrix(0 0.37 -0.98462 0 295.38501 -30.360001)" gradientUnits="userSpaceOnUse" x1="300" x2="428" y1="235" y2="235">
<stop offset="0" stop-color="#f9f06b"/>
<stop offset="1" stop-color="#f5c211"/>
</linearGradient>
<clipPath id="y">
<rect height="128" width="128"/>
</clipPath>
<clipPath id="z">
<rect height="128" width="128"/>
</clipPath>
</defs>
<path d="m 21 16 c -4.433594 0 -8 3.566406 -8 8 v 84 c 0 4.433594 3.566406 8 8 8 h 4 v -4 h 80 v 4 h 4 c 4.433594 0 8 -3.566406 8 -8 v -84 c 0 -4.433594 -3.566406 -8 -8 -8 z m 0 0" fill="url(#a)"/>
<path d="m 21 12 h 88 c 4.417969 0 8 3.582031 8 8 v 68 c 0 4.417969 -3.582031 8 -8 8 h -88 c -4.417969 0 -8 -3.582031 -8 -8 v -68 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#deddda"/>
<path d="m 27 28 h 74 v 10 h -74 z m 0 0" fill="url(#b)"/>
<path d="m 27 38 h 74 v 46 h -74 z m 0 0" fill="url(#c)"/>
<path d="m 24 33 c 0 1.65625 -1.34375 3 -3 3 s -3 -1.34375 -3 -3 s 1.34375 -3 3 -3 s 3 1.34375 3 3 z m 0 0" fill="#bf5f00" fill-opacity="0.964567"/>
<g fill-opacity="0.984252">
<path d="m 18 40 h 6 v 12 h -6 z m 0 0" fill="#acacac"/>
<path d="m 18 40 h 6 v 10 h -6 z m 0 0" fill="#d1d1d1"/>
<path d="m 37 36 h 56 v 44 h -56 z m 0 0" fill="#deddda"/>
</g>
<path d="m 37 34 h 56 c 1.105469 0 2 0.894531 2 2 s -0.894531 2 -2 2 h -56 c -1.105469 0 -2 -0.894531 -2 -2 s 0.894531 -2 2 -2 z m 0 0" fill-opacity="0.940945"/>
<path d="m 37 36.859375 h 56 v 36.925781 l -14.125 14.214844 h -41.875 z m 0 0" fill="#9a9996" fill-opacity="0.984252"/>
<path d="m 37 36 h 56 v 36.925781 l -14.125 14.214844 h -41.875 z m 0 0" fill="#f6f5f4" fill-opacity="0.984252"/>
<g clip-path="url(#d)">
<g clip-path="url(#e)">
<path d="m 79 77.386719 v 9.351562 c 0 2.464844 2 4.464844 4.464844 4.464844 h 9.351562 c 2.464844 0 4.464844 -2 4.464844 -4.464844 v -9.351562 c 0 -2.464844 -2 -4.464844 -4.464844 -4.464844 h -9.351562 c -2.464844 0 -4.464844 2 -4.464844 4.464844 z m 0 0" fill="url(#f)"/>
</g>
</g>
<path d="m 27 100 h 76 c 1.109375 0 2 0.890625 2 2 v 10 h -80 v -10 c 0 -1.109375 0.890625 -2 2 -2 z m 0 0" fill="#5e5c64" fill-opacity="0.940945"/>
<path d="m 27 102 h 76 c 1.109375 0 2 0.890625 2 2 v 10 h -80 v -10 c 0 -1.109375 0.890625 -2 2 -2 z m 0 0" fill="#9a9996"/>
<path d="m 13 106 v 2 c 0 4.433594 3.566406 8 8 8 h 4 v -2 h -4 c -4.433594 0 -8 -3.566406 -8 -8 z m 104 0 c 0 4.433594 -3.566406 8 -8 8 h -4 v 2 h 4 c 4.433594 0 8 -3.566406 8 -8 z m -92 6 v 2 h 80 v -2 z m 0 0" fill="#9e9c99" fill-opacity="0.366142"/>
<path d="m 27 38 v 46 l 6 -46 z m 0 0" fill="#7e7c77" fill-opacity="0.11811"/>
<path d="m 24 32 c 0 1.65625 -1.34375 3 -3 3 s -3 -1.34375 -3 -3 s 1.34375 -3 3 -3 s 3 1.34375 3 3 z m 0 0" fill="#ffa348" fill-opacity="0.964567"/>
<use mask="url(#h)" transform="matrix(1 0 0 1 -8 -16)" xlink:href="#s"/>
<path d="m 89.503906 31.144531 l 10.066406 10.066407 l -41.71875 41.71875 l -10.066406 -10.066407 z m 0 0" fill="#ffa348"/>
<path d="m 88.246094 29.886719 l 7.550781 7.550781 l -41.71875 41.71875 l -7.550781 -7.550781 z m 0 0" fill="#ff7800"/>
<path d="m 86.789062 28.429688 l 2.515626 2.515624 l -41.71875 41.71875 l -2.515626 -2.515624 z m 0 0" fill="#ffbe6f"/>
<path d="m 121.898438 -0.101562 c -4.855469 0.921874 -11.730469 5.152343 -18.140626 11.558593 l -16.96875 16.972657 l 12.78125 12.78125 l 16.972657 -16.972657 c 6.40625 -6.40625 10.636719 -13.28125 11.558593 -18.136719 z m 0 0" fill="url(#j)"/>
<path d="m 110.011719 13.882812 c -2.1875 -0.398437 -5.421875 0.988282 -8.167969 3.730469 l -11.871094 11.875 l -6.6875 6.6875 c -4.800781 4.800781 -9.234375 12.007813 -9.648437 13.042969 c -0.484375 1.207031 -0.449219 2.730469 0.953125 4.136719 c 1.40625 1.40625 2.917968 1.441406 4.136718 0.953125 c 1.035157 -0.414063 8.292969 -4.984375 13.042969 -9.648438 l 2.402344 -2.398437 l 16.160156 -16.160157 c 2.742188 -2.746093 4.128907 -5.976562 3.730469 -8.167968 c -0.742188 1.390625 -1.859375 2.902344 -3.308594 4.347656 l -13.996094 13.996094 l -5.089843 -5.089844 l 13.996093 -13.996094 c 1.445313 -1.445312 2.960938 -2.566406 4.347657 -3.308594 z m 0 0" fill="url(#k)"/>
<path d="m 95.273438 36.914062 l -2.960938 2.960938 l -2.398438 2.402344 c -4.90625 5.101562 -11.855468 10.828125 -11.855468 10.828125 c 1.011718 -0.433594 8.167968 -5.101563 12.914062 -9.769531 l 2.402344 -2.402344 l 2.960938 -2.957032 z m 0 0" fill="#62a0ea"/>
<path d="m 87.320312 26.835938 l 13.789063 13.789062 c 0.292969 0.292969 0.292969 0.769531 0 1.0625 s -0.769531 0.292969 -1.0625 0 l -13.789063 -13.789062 c -0.292968 -0.292969 -0.292968 -0.769532 0 -1.0625 c 0.292969 -0.289063 0.769532 -0.289063 1.0625 0 z m 0 0" fill="#3584e4"/>
<path d="m 42.421875 89.765625 c -3 3 -6.382813 4.484375 -7.554687 3.3125 c -1.171876 -1.171875 0.3125 -4.554687 3.3125 -7.554687 c 3.003906 -3.003907 6.386718 -4.488282 7.558593 -3.316407 s -0.3125 4.554688 -3.316406 7.558594 z m 0 0" fill="url(#l)"/>
<path d="m 45.269531 70.347656 l -7.851562 12.511719 l 7.835937 7.925781 l 12.597656 -7.855468 z m -6.039062 13.171875 l 5.449219 5.449219 c 0.347656 0.347656 0.449218 0.933594 0.097656 1.160156 c -0.886719 0.570313 -2.9375 1.539063 -2.9375 1.539063 c -0.25 0.128906 -0.539063 0.164062 -0.773438 -0.066407 l -4.546875 -4.550781 c -0.234375 -0.230469 -0.207031 -0.527343 -0.066406 -0.773437 l 1.617187 -2.859375 c 0.207032 -0.363281 0.8125 -0.25 1.160157 0.101562 z m 0 0" fill="url(#m)"/>
<path d="m 43.332031 74.777344 l 9.867188 9.867187 c 0.394531 0.390625 0.476562 0.871094 0.128906 1.066407 l -7.710937 5.253906 c -0.308594 0.210937 -0.785157 0.160156 -1.171876 -0.226563 l -6.984374 -6.988281 c -0.386719 -0.386719 -0.4375 -0.859375 -0.230469 -1.167969 l 5.234375 -7.8125 c 0.125 -0.285156 0.558594 -0.304687 0.867187 0.007813 z m 0 0" fill="url(#n)"/>
<g clip-path="url(#z)" mask="url(#v)">
<g clip-path="url(#y)" mask="url(#w)">
<path d="m 128 80.640625 v 47.359375 h -128 v -47.359375 z m 0 0" fill="url(#x)"/>
<path d="m 13.308594 80.640625 l 47.355468 47.359375 h 21.214844 l -47.359375 -47.359375 z m 42.421875 0 l 47.363281 47.359375 h 21.214844 l -47.363282 -47.359375 z m 42.429687 0 l 29.839844 29.839844 v -21.210938 l -8.628906 -8.628906 z m -98.160156 7.90625 v 21.214844 l 18.238281 18.238281 h 21.214844 z m 0 0"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 18 KiB

@@ -1,100 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="128px" viewBox="0 0 128 128" width="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<linearGradient id="a" gradientTransform="matrix(0.232143 0 0 0.328947 -7.567033 263.82666)" gradientUnits="userSpaceOnUse" x1="88.595886" x2="536.595886" y1="-449.394012" y2="-449.394012">
<stop offset="0" stop-color="#acabae"/>
<stop offset="0.0384615" stop-color="#deddda"/>
<stop offset="0.0768555" stop-color="#c0bfbc"/>
<stop offset="0.923077" stop-color="#c0bfbc"/>
<stop offset="0.961538" stop-color="#deddda"/>
<stop offset="1" stop-color="#9a9996"/>
</linearGradient>
<linearGradient id="b" gradientUnits="userSpaceOnUse" x1="26.999876" x2="100.999876" y1="32.999688" y2="32.999688">
<stop offset="0" stop-color="#7e7c77"/>
<stop offset="0.3" stop-color="#9a9996"/>
<stop offset="1" stop-color="#9a9996"/>
</linearGradient>
<linearGradient id="c" gradientUnits="userSpaceOnUse" x1="67.467916" x2="67.467916" y1="83.999688" y2="36.782906">
<stop offset="0" stop-color="#deddda"/>
<stop offset="1" stop-color="#c0bfbc"/>
</linearGradient>
<clipPath id="d">
<path d="m 79 72 h 15 v 16 h -15 z m 0 0"/>
</clipPath>
<clipPath id="e">
<path d="m 93.21875 72.921875 l -14.21875 14.21875 h -4.0625 v -18.28125 h 18.28125 z m 0 0"/>
</clipPath>
<linearGradient id="f" gradientTransform="matrix(0 0.126951 0.126951 0 76.460862 36.359884)" gradientUnits="userSpaceOnUse" x1="344" x2="340" y1="76" y2="72">
<stop offset="0" stop-color="#d5d3cf"/>
<stop offset="1" stop-color="#ffffff"/>
</linearGradient>
<filter id="g" height="100%" width="100%" x="0%" y="0%">
<feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
</filter>
<mask id="h">
<g filter="url(#g)">
<rect fill-opacity="0.396" height="128" width="128"/>
</g>
</mask>
<clipPath id="i">
<rect height="152" width="192"/>
</clipPath>
<linearGradient id="j" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#1c71d8"/>
<stop offset="0.323117" stop-color="#62a0ea"/>
<stop offset="0.59387" stop-color="#1b5aa6"/>
<stop offset="1" stop-color="#1c71d8"/>
</linearGradient>
<linearGradient id="k" gradientTransform="matrix(1.597748 1.597748 -1.06066 1.06066 -56.853041 -543.720139)" x1="224.504562" x2="231.453873" xlink:href="#j" y1="282.5" y2="282.5"/>
<radialGradient id="l" cx="227.599915" cy="201.029724" gradientTransform="matrix(4.072817 4.073078 -5.940048 5.939073 373.883117 -2098.049112)" gradientUnits="userSpaceOnUse" r="2.5">
<stop offset="0" stop-color="#93bdf1"/>
<stop offset="1" stop-color="#1a5fb4"/>
</radialGradient>
<linearGradient id="m" gradientTransform="matrix(2.121328 2.121328 -2.174353 2.174353 181.766074 -1021.145947)" gradientUnits="userSpaceOnUse" x1="226.90625" x2="228.86203" y1="288.75" y2="288.767151">
<stop offset="0" stop-color="#77767b"/>
<stop offset="0.443872" stop-color="#f6f5f4"/>
<stop offset="1" stop-color="#5e5c64"/>
</linearGradient>
<linearGradient id="n" gradientTransform="matrix(1.258421 1.258421 -1.06066 1.06066 57.381892 -503.024312)" gradientUnits="userSpaceOnUse" x1="223.1875" x2="233.0625" y1="278" y2="278">
<stop offset="0" stop-color="#ffa348"/>
<stop offset="0.265823" stop-color="#ffd7af"/>
<stop offset="0.734177" stop-color="#ff8d1c"/>
<stop offset="1" stop-color="#ffa348"/>
</linearGradient>
<linearGradient id="o" gradientTransform="matrix(1.573027 1.573027 -1.06066 1.06066 -14.348129 -574.754333)" x1="224.504562" x2="231.453873" xlink:href="#j" y1="282.5" y2="282.5"/>
<path d="m 21 16 c -4.433594 0 -8 3.566406 -8 8 v 84 c 0 4.433594 3.566406 8 8 8 h 4 v -4 h 80 v 4 h 4 c 4.433594 0 8 -3.566406 8 -8 v -84 c 0 -4.433594 -3.566406 -8 -8 -8 z m 0 0" fill="url(#a)"/>
<path d="m 21 12 h 88 c 4.417969 0 8 3.582031 8 8 v 68 c 0 4.417969 -3.582031 8 -8 8 h -88 c -4.417969 0 -8 -3.582031 -8 -8 v -68 c 0 -4.417969 3.582031 -8 8 -8 z m 0 0" fill="#deddda"/>
<path d="m 27 28 h 74 v 10 h -74 z m 0 0" fill="url(#b)"/>
<path d="m 27 38 h 74 v 46 h -74 z m 0 0" fill="url(#c)"/>
<path d="m 24 33 c 0 1.65625 -1.34375 3 -3 3 s -3 -1.34375 -3 -3 s 1.34375 -3 3 -3 s 3 1.34375 3 3 z m 0 0" fill="#bf5f00" fill-opacity="0.964567"/>
<g fill-opacity="0.984252">
<path d="m 18 40 h 6 v 12 h -6 z m 0 0" fill="#acacac"/>
<path d="m 18 40 h 6 v 10 h -6 z m 0 0" fill="#d1d1d1"/>
<path d="m 37 36 h 56 v 44 h -56 z m 0 0" fill="#deddda"/>
</g>
<path d="m 37 34 h 56 c 1.105469 0 2 0.894531 2 2 s -0.894531 2 -2 2 h -56 c -1.105469 0 -2 -0.894531 -2 -2 s 0.894531 -2 2 -2 z m 0 0" fill-opacity="0.940945"/>
<path d="m 37 36.859375 h 56 v 36.925781 l -14.125 14.214844 h -41.875 z m 0 0" fill="#9a9996" fill-opacity="0.984252"/>
<path d="m 37 36 h 56 v 36.925781 l -14.125 14.214844 h -41.875 z m 0 0" fill="#f6f5f4" fill-opacity="0.984252"/>
<g clip-path="url(#d)">
<g clip-path="url(#e)">
<path d="m 79 77.386719 v 9.351562 c 0 2.464844 2 4.464844 4.464844 4.464844 h 9.351562 c 2.464844 0 4.464844 -2 4.464844 -4.464844 v -9.351562 c 0 -2.464844 -2 -4.464844 -4.464844 -4.464844 h -9.351562 c -2.464844 0 -4.464844 2 -4.464844 4.464844 z m 0 0" fill="url(#f)"/>
</g>
</g>
<path d="m 27 100 h 76 c 1.109375 0 2 0.890625 2 2 v 10 h -80 v -10 c 0 -1.109375 0.890625 -2 2 -2 z m 0 0" fill="#5e5c64" fill-opacity="0.940945"/>
<path d="m 27 102 h 76 c 1.109375 0 2 0.890625 2 2 v 10 h -80 v -10 c 0 -1.109375 0.890625 -2 2 -2 z m 0 0" fill="#9a9996"/>
<path d="m 13 106 v 2 c 0 4.433594 3.566406 8 8 8 h 4 v -2 h -4 c -4.433594 0 -8 -3.566406 -8 -8 z m 104 0 c 0 4.433594 -3.566406 8 -8 8 h -4 v 2 h 4 c 4.433594 0 8 -3.566406 8 -8 z m -92 6 v 2 h 80 v -2 z m 0 0" fill="#9e9c99" fill-opacity="0.366142"/>
<path d="m 27 38 v 46 l 6 -46 z m 0 0" fill="#7e7c77" fill-opacity="0.11811"/>
<path d="m 24 32 c 0 1.65625 -1.34375 3 -3 3 s -3 -1.34375 -3 -3 s 1.34375 -3 3 -3 s 3 1.34375 3 3 z m 0 0" fill="#ffa348" fill-opacity="0.964567"/>
<g clip-path="url(#i)" mask="url(#h)" transform="matrix(1 0 0 1 -8 -16)">
<path d="m 29 112 c -4.433594 0 -8 -3.566406 -8 -8 v -2 c 0 4.433594 3.566406 8 8 8 h 88 c 4.433594 0 8 -3.566406 8 -8 v 2 c 0 4.433594 -3.566406 8 -8 8 z m 0 0" fill="#f6f5f4"/>
</g>
<path d="m 89.503906 31.144531 l 10.066406 10.066407 l -41.71875 41.71875 l -10.066406 -10.066407 z m 0 0" fill="#ffa348"/>
<path d="m 88.246094 29.886719 l 7.550781 7.550781 l -41.71875 41.71875 l -7.550781 -7.550781 z m 0 0" fill="#ff7800"/>
<path d="m 86.789062 28.429688 l 2.515626 2.515624 l -41.71875 41.71875 l -2.515626 -2.515624 z m 0 0" fill="#ffbe6f"/>
<path d="m 121.898438 -0.101562 c -4.855469 0.921874 -11.730469 5.152343 -18.140626 11.558593 l -16.96875 16.972657 l 12.78125 12.78125 l 16.972657 -16.972657 c 6.40625 -6.40625 10.636719 -13.28125 11.558593 -18.136719 z m 0 0" fill="url(#k)"/>
<path d="m 110.011719 13.882812 c -2.1875 -0.398437 -5.421875 0.988282 -8.167969 3.730469 l -11.871094 11.875 l -6.6875 6.6875 c -4.800781 4.800781 -9.234375 12.007813 -9.648437 13.042969 c -0.484375 1.207031 -0.449219 2.730469 0.953125 4.136719 c 1.40625 1.40625 2.917968 1.441406 4.136718 0.953125 c 1.035157 -0.414063 8.292969 -4.984375 13.042969 -9.648438 l 2.402344 -2.398437 l 16.160156 -16.160157 c 2.742188 -2.746093 4.128907 -5.976562 3.730469 -8.167968 c -0.742188 1.390625 -1.859375 2.902344 -3.308594 4.347656 l -13.996094 13.996094 l -5.089843 -5.089844 l 13.996093 -13.996094 c 1.445313 -1.445312 2.960938 -2.566406 4.347657 -3.308594 z m 0 0" fill="url(#l)"/>
<path d="m 95.273438 36.914062 l -2.960938 2.960938 l -2.398438 2.402344 c -4.90625 5.101562 -11.855468 10.828125 -11.855468 10.828125 c 1.011718 -0.433594 8.167968 -5.101563 12.914062 -9.769531 l 2.402344 -2.402344 l 2.960938 -2.957032 z m 0 0" fill="#62a0ea"/>
<path d="m 87.320312 26.835938 l 13.789063 13.789062 c 0.292969 0.292969 0.292969 0.769531 0 1.0625 s -0.769531 0.292969 -1.0625 0 l -13.789063 -13.789062 c -0.292968 -0.292969 -0.292968 -0.769532 0 -1.0625 c 0.292969 -0.289063 0.769532 -0.289063 1.0625 0 z m 0 0" fill="#3584e4"/>
<path d="m 42.421875 89.765625 c -3 3 -6.382813 4.484375 -7.554687 3.3125 c -1.171876 -1.171875 0.3125 -4.554687 3.3125 -7.554687 c 3.003906 -3.003907 6.386718 -4.488282 7.558593 -3.316407 s -0.3125 4.554688 -3.316406 7.558594 z m 0 0" fill="url(#m)"/>
<path d="m 45.269531 70.347656 l -7.851562 12.511719 l 7.835937 7.925781 l 12.597656 -7.855468 z m -6.039062 13.171875 l 5.449219 5.449219 c 0.347656 0.347656 0.449218 0.933594 0.097656 1.160156 c -0.886719 0.570313 -2.9375 1.539063 -2.9375 1.539063 c -0.25 0.128906 -0.539063 0.164062 -0.773438 -0.066407 l -4.546875 -4.550781 c -0.234375 -0.230469 -0.207031 -0.527343 -0.066406 -0.773437 l 1.617187 -2.859375 c 0.207032 -0.363281 0.8125 -0.25 1.160157 0.101562 z m 0 0" fill="url(#n)"/>
<path d="m 43.332031 74.777344 l 9.867188 9.867187 c 0.394531 0.390625 0.476562 0.871094 0.128906 1.066407 l -7.710937 5.253906 c -0.308594 0.210937 -0.785157 0.160156 -1.171876 -0.226563 l -6.984374 -6.988281 c -0.386719 -0.386719 -0.4375 -0.859375 -0.230469 -1.167969 l 5.234375 -7.8125 c 0.125 -0.285156 0.558594 -0.304687 0.867187 0.007813 z m 0 0" fill="url(#o)"/>
</svg>

Before

Width:  |  Height:  |  Size: 9.4 KiB

@@ -1,21 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<filter id="a" height="100%" width="100%" x="0%" y="0%">
<feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
</filter>
<mask id="b">
<g filter="url(#a)">
<rect fill-opacity="0.396" height="16" width="16"/>
</g>
</mask>
<clipPath id="c">
<rect height="152" width="192"/>
</clipPath>
<g clip-path="url(#c)" mask="url(#b)" transform="matrix(1 0 0 1 -168 -16)">
<path d="m 29 112 c -4.433594 0 -8 -3.566406 -8 -8 v -2 c 0 4.433594 3.566406 8 8 8 h 88 c 4.433594 0 8 -3.566406 8 -8 v 2 c 0 4.433594 -3.566406 8 -8 8 z m 0 0" fill="#f6f5f4"/>
</g>
<g fill="#2e3436">
<path d="m 4 2 v 2 h 5.585938 l 2 -2 z m -2 3 c -0.5 0 -1 0.5 -1 1 v 4 c 0 0.5 0.5 1 1 1 h 1 v -2 h 2 c 0 -0.265625 0.105469 -0.519531 0.292969 -0.707031 l 3.292969 -3.292969 z m 11.414062 0 l -4 4 h 3.585938 v 2 h 1 c 0.5 0 1 -0.5 1 -1 v -4 c 0 -0.5 -0.5 -1 -1 -1 z m -9.414062 5 v 5 h 8 v -5 h -3.585938 l -0.707031 0.707031 c -0.1875 0.1875 -0.441406 0.292969 -0.707031 0.292969 h -1 c -0.550781 0 -1 -0.449219 -1 -1 z m 0 0"/>
<path d="m 6 10 h 1 l 9 -9 l -1 -1 l -9 9 z m 0 0"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

-9
View File
@@ -12,12 +12,3 @@ install_data('org.gtk.PrintEditor4.desktop', install_dir: gtk_applicationsdir)
# appdata
install_data('org.gtk.PrintEditor4.appdata.xml', install_dir: gtk_appdatadir)
# icons
icontheme_dir = join_paths(gtk_datadir, 'icons/hicolor')
foreach size: ['scalable', 'symbolic']
install_subdir('data/' + size,
install_dir: icontheme_dir
)
endforeach
@@ -2,7 +2,7 @@
Name=Print Editor
Comment=A simple editor demonstrating GTK printing
Exec=gtk4-print-editor %f
Icon=org.gtk.PrintEditor4.Devel
Icon=text-editor-symbolic
Terminal=false
Type=Application
StartupNotify=true
+1 -3
View File
@@ -633,7 +633,7 @@ activate_about (GSimpleAction *action,
"website", "http://www.gtk.org",
"comments", "Program to demonstrate GTK printing",
"authors", (const char *[]){ "Alexander Larsson", NULL },
"logo-icon-name", "org.gtk.PrintEditor4.Devel",
"logo-icon-name", "text-editor-symbolic",
"title", "About GTK Print Editor",
"system-information", sysinfo->str,
NULL);
@@ -781,8 +781,6 @@ activate (GApplication *app)
gtk_application_window_set_show_menubar (GTK_APPLICATION_WINDOW (main_window), TRUE);
update_title (GTK_WINDOW (main_window));
gtk_widget_add_css_class (main_window, "devel");
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_window_set_child (GTK_WINDOW (main_window), box);
+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" />
+16 -19
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>
@@ -1300,19 +1296,23 @@ gtk_file_chooser_get_current_name
<SUBSECTION>
gtk_file_chooser_get_file
gtk_file_chooser_set_file
gtk_file_chooser_select_file
gtk_file_chooser_unselect_file
gtk_file_chooser_select_all
gtk_file_chooser_unselect_all
gtk_file_chooser_get_files
gtk_file_chooser_set_current_folder
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>
gtk_file_chooser_add_shortcut_folder
gtk_file_chooser_remove_shortcut_folder
gtk_file_chooser_get_shortcut_folders
gtk_file_chooser_list_shortcut_folders
<SUBSECTION>
gtk_file_chooser_add_choice
gtk_file_chooser_remove_choice
@@ -1409,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
@@ -1440,8 +1445,6 @@ gtk_directory_list_get_file
gtk_directory_list_set_file
gtk_directory_list_get_io_priority
gtk_directory_list_set_io_priority
gtk_directory_list_get_monitored
gtk_directory_list_set_monitored
gtk_directory_list_is_loading
gtk_directory_list_get_error
<SUBSECTION Standard>
@@ -1536,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
@@ -2697,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
@@ -2828,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
@@ -7541,13 +7544,9 @@ gtk_expression_watch_unwatch
<SUBSECTION>
gtk_property_expression_new
gtk_property_expression_new_for_pspec
gtk_property_expression_get_expression
gtk_property_expression_get_pspec
gtk_constant_expression_new
gtk_constant_expression_new_for_value
gtk_constant_expression_get_value
gtk_object_expression_new
gtk_object_expression_get_object
gtk_closure_expression_new
gtk_cclosure_expression_new
@@ -7611,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>
-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 GDK_ARRAY_TYPE_NAME
#define GDK_ARRAY_TYPE_NAME GdkArray
#endif
#ifndef GDK_ARRAY_NAME
#define GDK_ARRAY_NAME gdk_array
#endif
#ifndef GDK_ARRAY_ELEMENT_TYPE
#define GDK_ARRAY_ELEMENT_TYPE gpointer
#endif
#ifdef GDK_ARRAY_PREALLOC
#if GDK_ARRAY_PREALLOC == 0
#undef GDK_ARRAY_PREALLOC
#endif
#endif
#ifdef GDK_ARRAY_NULL_TERMINATED
#define GDK_ARRAY_REAL_SIZE(_size) ((_size) + 1)
#else
#define GDK_ARRAY_REAL_SIZE(_size) (_size)
#endif
/* make this readable */
#define _T_ GDK_ARRAY_ELEMENT_TYPE
#define GdkArray GDK_ARRAY_TYPE_NAME
#define gdk_array_paste_more(GDK_ARRAY_NAME, func_name) GDK_ARRAY_NAME ## _ ## func_name
#define gdk_array_paste(GDK_ARRAY_NAME, func_name) gdk_array_paste_more (GDK_ARRAY_NAME, func_name)
#define gdk_array(func_name) gdk_array_paste (GDK_ARRAY_NAME, func_name)
typedef struct GdkArray GdkArray;
struct GdkArray
{
_T_ *start;
_T_ *end;
_T_ *end_allocation;
#ifdef GDK_ARRAY_PREALLOC
_T_ preallocated[GDK_ARRAY_REAL_SIZE(GDK_ARRAY_PREALLOC)];
#endif
};
/* no G_GNUC_UNUSED here, if you don't use an array type, remove it. */
static inline void
gdk_array(init) (GdkArray *self)
{
#ifdef GDK_ARRAY_PREALLOC
self->start = self->preallocated;
self->end = self->start;
self->end_allocation = self->start + GDK_ARRAY_PREALLOC;
#ifdef GDK_ARRAY_NULL_TERMINATED
*self->start = *(_T_[1]) {};
#endif
#else
self->start = NULL;
self->end = NULL;
self->end_allocation = NULL;
#endif
}
static inline void
gdk_array(free_elements) (_T_ *start,
_T_ *end)
{
#ifdef GDK_ARRAY_FREE_FUNC
_T_ *e;
for (e = start; e < end; e++)
#ifdef GDK_ARRAY_BY_VALUE
GDK_ARRAY_FREE_FUNC (e);
#else
GDK_ARRAY_FREE_FUNC (*e);
#endif
#endif
}
/* no G_GNUC_UNUSED here */
static inline void
gdk_array(clear) (GdkArray *self)
{
gdk_array(free_elements) (self->start, self->end);
#ifdef GDK_ARRAY_PREALLOC
if (self->start != self->preallocated)
#endif
g_free (self->start);
gdk_array(init) (self);
}
G_GNUC_UNUSED static inline _T_ *
gdk_array(get_data) (const GdkArray *self)
{
return self->start;
}
G_GNUC_UNUSED static inline _T_ *
gdk_array(index) (const GdkArray *self,
gsize pos)
{
return self->start + pos;
}
G_GNUC_UNUSED static inline gsize
gdk_array(get_capacity) (const GdkArray *self)
{
return self->end_allocation - self->start;
}
G_GNUC_UNUSED static inline gsize
gdk_array(get_size) (const GdkArray *self)
{
return self->end - self->start;
}
G_GNUC_UNUSED static inline gboolean
gdk_array(is_empty) (const GdkArray *self)
{
return self->end == self->start;
}
G_GNUC_UNUSED static void
gdk_array(reserve) (GdkArray *self,
gsize n)
{
gsize new_size, size;
if (n <= gdk_array(get_capacity) (self))
return;
size = gdk_array(get_size) (self);
new_size = 1 << g_bit_storage (MAX (GDK_ARRAY_REAL_SIZE (n), 16) - 1);
#ifdef GDK_ARRAY_PREALLOC
if (self->start == self->preallocated)
{
self->start = g_new (_T_, new_size);
memcpy (self->start, self->preallocated, sizeof (_T_) * GDK_ARRAY_REAL_SIZE (size));
}
else
#endif
#ifdef GDK_ARRAY_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 GDK_ARRAY_NULL_TERMINATED
self->end_allocation--;
#endif
}
G_GNUC_UNUSED static void
gdk_array(splice) (GdkArray *self,
gsize pos,
gsize removed,
_T_ *additions,
gsize added)
{
gsize size;
gsize remaining;
size = gdk_array(get_size) (self);
g_assert (pos + removed <= size);
remaining = size - pos - removed;
gdk_array(free_elements) (gdk_array(index) (self, pos),
gdk_array(index) (self, pos + removed));
gdk_array(reserve) (self, size - removed + added);
if (GDK_ARRAY_REAL_SIZE (remaining) && removed != added)
memmove (gdk_array(index) (self, pos + added),
gdk_array(index) (self, pos + removed),
GDK_ARRAY_REAL_SIZE (remaining) * sizeof (_T_));
if (added)
{
if (additions)
memcpy (gdk_array(index) (self, pos),
additions,
added * sizeof (_T_));
else
memset (gdk_array(index) (self, pos), 0, added * sizeof (_T_));
}
/* might overflow, but does the right thing */
self->end += added - removed;
}
G_GNUC_UNUSED static void
gdk_array(set_size) (GdkArray *self,
gsize new_size)
{
gsize old_size = gdk_array(get_size) (self);
if (new_size > old_size)
gdk_array(splice) (self, old_size, 0, NULL, new_size - old_size);
else
gdk_array(splice) (self, new_size, old_size - new_size, NULL, 0);
}
G_GNUC_UNUSED static void
gdk_array(append) (GdkArray *self,
#ifdef GDK_ARRAY_BY_VALUE
_T_ *value)
#else
_T_ value)
#endif
{
gdk_array(splice) (self,
gdk_array(get_size) (self),
0,
#ifdef GDK_ARRAY_BY_VALUE
value,
#else
&value,
#endif
1);
}
#ifdef GDK_ARRAY_BY_VALUE
G_GNUC_UNUSED static _T_ *
gdk_array(get) (const GdkArray *self,
gsize pos)
{
return gdk_array(index) (self, pos);
}
#else
G_GNUC_UNUSED static _T_
gdk_array(get) (const GdkArray *self,
gsize pos)
{
return *gdk_array(index) (self, pos);
}
#endif
#ifndef GDK_ARRAY_NO_UNDEF
#undef _T_
#undef GdkArray
#undef gdk_array_paste_more
#undef gdk_array_paste
#undef gdk_array
#undef GDK_ARRAY_REAL_SIZE
#undef GDK_ARRAY_BY_VALUE
#undef GDK_ARRAY_ELEMENT_TYPE
#undef GDK_ARRAY_FREE_FUNC
#undef GDK_ARRAY_NAME
#undef GDK_ARRAY_NULL_TERMINATED
#undef GDK_ARRAY_PREALLOC
#undef GDK_ARRAY_TYPE_NAME
#endif
-6
View File
@@ -544,12 +544,6 @@ gdk_registry_handle_global (void *data,
gdk_wayland_display_init_xdg_output (display_wayland);
_gdk_wayland_display_async_roundtrip (display_wayland);
}
else if (strcmp(interface, "zwp_idle_inhibit_manager_v1") == 0)
{
display_wayland->idle_inhibit_manager =
wl_registry_bind (display_wayland->wl_registry, id,
&zwp_idle_inhibit_manager_v1_interface, 1);
}
g_hash_table_insert (display_wayland->known_globals,
GUINT_TO_POINTER (id), g_strdup (interface));
-2
View File
@@ -35,7 +35,6 @@
#include <gdk/wayland/keyboard-shortcuts-inhibit-unstable-v1-client-protocol.h>
#include <gdk/wayland/server-decoration-client-protocol.h>
#include <gdk/wayland/xdg-output-unstable-v1-client-protocol.h>
#include <gdk/wayland/idle-inhibit-unstable-v1-client-protocol.h>
#include <glib.h>
#include <gdk/gdkkeys.h>
@@ -110,7 +109,6 @@ struct _GdkWaylandDisplay
struct zwp_keyboard_shortcuts_inhibit_manager_v1 *keyboard_shortcuts_inhibit;
struct org_kde_kwin_server_decoration_manager *server_decoration_manager;
struct zxdg_output_manager_v1 *xdg_output_manager;
struct zwp_idle_inhibit_manager_v1 *idle_inhibit_manager;
GList *async_roundtrips;
+13 -69
View File
@@ -191,9 +191,6 @@ struct _GdkWaylandSurface
struct zxdg_imported_v1 *imported_transient_for;
GHashTable *shortcuts_inhibitors;
struct zwp_idle_inhibitor_v1 *idle_inhibitor;
size_t idle_inhibitor_refcount;
};
struct _GdkWaylandSurfaceClass
@@ -1651,38 +1648,6 @@ create_zxdg_toplevel_v6_resources (GdkSurface *surface)
surface);
}
void
gdk_wayland_surface_set_application_id (GdkSurface *surface, const char* application_id)
{
GdkWaylandSurface *impl;
GdkWaylandDisplay *display_wayland;
g_return_if_fail (application_id != NULL);
if (GDK_SURFACE_DESTROYED (surface))
return;
if (!is_realized_toplevel (surface))
return;
display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
impl = GDK_WAYLAND_SURFACE (surface);
switch (display_wayland->shell_variant)
{
case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL:
xdg_toplevel_set_app_id (impl->display_server.xdg_toplevel,
application_id);
break;
case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6:
zxdg_toplevel_v6_set_app_id (impl->display_server.zxdg_toplevel_v6,
application_id);
break;
default:
g_assert_not_reached ();
}
}
static void
gdk_wayland_surface_create_xdg_toplevel (GdkSurface *surface)
{
@@ -1737,7 +1702,19 @@ gdk_wayland_surface_create_xdg_toplevel (GdkSurface *surface)
if (app_id == NULL)
app_id = "GTK+ Application";
gdk_wayland_surface_set_application_id (surface, app_id);
switch (display_wayland->shell_variant)
{
case GDK_WAYLAND_SHELL_VARIANT_XDG_SHELL:
xdg_toplevel_set_app_id (impl->display_server.xdg_toplevel,
app_id);
break;
case GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6:
zxdg_toplevel_v6_set_app_id (impl->display_server.zxdg_toplevel_v6,
app_id);
break;
default:
g_assert_not_reached ();
}
maybe_set_gtk_surface_dbus_properties (surface);
maybe_set_gtk_surface_modal (surface);
@@ -1987,39 +1964,6 @@ gdk_wayland_surface_announce_csd (GdkSurface *surface)
ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_CLIENT);
}
gboolean
gdk_wayland_surface_inhibit_idle (GdkSurface *surface)
{
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
if (!display_wayland->idle_inhibit_manager)
return false;
if (!impl->idle_inhibitor)
{
g_assert (impl->idle_inhibitor_refcount == 0);
impl->idle_inhibitor =
zwp_idle_inhibit_manager_v1_create_inhibitor (display_wayland->idle_inhibit_manager,
impl->display_server.wl_surface);
}
++impl->idle_inhibitor_refcount;
return true;
}
void
gdk_wayland_surface_uninhibit_idle (GdkSurface *surface)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
g_assert (impl->idle_inhibitor && impl->idle_inhibitor_refcount > 0);
if (--impl->idle_inhibitor_refcount == 0)
{
zwp_idle_inhibitor_v1_destroy (impl->idle_inhibitor);
impl->idle_inhibitor = NULL;
}
}
static void
calculate_popup_rect (GdkSurface *surface,
GdkPopupLayout *layout,
-7
View File
@@ -74,15 +74,8 @@ GDK_AVAILABLE_IN_ALL
gboolean gdk_wayland_surface_set_transient_for_exported (GdkSurface *surface,
char *parent_handle_str);
GDK_AVAILABLE_IN_ALL
void gdk_wayland_surface_set_application_id (GdkSurface *surface,
const char *application_id);
void gdk_wayland_surface_announce_csd (GdkSurface *surface);
gboolean gdk_wayland_surface_inhibit_idle (GdkSurface *surface);
void gdk_wayland_surface_uninhibit_idle (GdkSurface *surface);
G_END_DECLS
#endif /* __GDK_WAYLAND_SURFACE_H__ */
-1
View File
@@ -54,7 +54,6 @@ proto_sources = [
['keyboard-shortcuts-inhibit', 'unstable', 'v1', ],
['server-decoration', 'private' ],
['xdg-output', 'unstable', 'v1', ],
['idle-inhibit', 'unstable', 'v1', ],
]
gdk_wayland_gen_headers = []
-2
View File
@@ -653,8 +653,6 @@ gdk_x11_clipboard_store_async (GdkClipboard *clipboard,
GDK_DISPLAY_NOTE (display, CLIPBOARD,
g_printerr ("%s: X error during ConvertSelection() while storing selection: %d\n", cb->selection, error));
}
g_free (atoms);
}
static gboolean
+2 -14
View File
@@ -1874,7 +1874,6 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
case XI_Leave:
{
XIEnterEvent *xev = (XIEnterEvent *) ev;
GdkModifierType state;
GDK_DISPLAY_NOTE (display, EVENTS,
g_message ("%s notify:\twindow %ld\n\tsubwindow:%ld\n"
@@ -1891,18 +1890,6 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
source_device = g_hash_table_lookup (device_manager->id_table,
GUINT_TO_POINTER (xev->sourceid));
state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
/* Ignore normal crossing events while there is an implicit grab.
* We will receive a crossing event with one of the other details if
* the implicit grab were finished (eg. releasing the button outside
* the window triggers a XINotifyUngrab leave).
*/
if (xev->mode == XINotifyNormal &&
(state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK |
GDK_BUTTON4_MASK | GDK_BUTTON5_MASK)))
break;
if (ev->evtype == XI_Enter &&
xev->detail != XINotifyInferior && xev->mode != XINotifyPassiveUngrab &&
GDK_IS_TOPLEVEL (surface))
@@ -1929,11 +1916,12 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
device,
source_device,
xev->time,
state,
_gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group),
(double) xev->event_x / scale,
(double) xev->event_y / scale,
translate_crossing_mode (xev->mode),
translate_notify_type (xev->detail));
}
break;
case XI_FocusIn:
+1 -1
View File
@@ -184,7 +184,7 @@ gdk_x11_gl_context_end_frame (GdkDrawContext *draw_context,
gdk_x11_surface_pre_damage (surface);
#ifdef HAVE_XDAMAGE
if (context_x11->xdamage != 0 && _gdk_x11_surface_syncs_frames (surface))
if (context_x11->xdamage != 0)
{
g_assert (context_x11->frame_fence == 0);
+4 -4
View File
@@ -360,8 +360,8 @@ gdk_x11_surface_begin_frame (GdkSurface *surface,
}
}
gboolean
_gdk_x11_surface_syncs_frames (GdkSurface *surface)
static gboolean
should_sync_frame_drawing (GdkSurface *surface)
{
GdkX11Surface *impl = GDK_X11_SURFACE (surface);
@@ -395,7 +395,7 @@ static void
maybe_sync_counter_for_end_frame (GdkSurface *surface)
{
GdkX11Surface *impl = GDK_X11_SURFACE (surface);
gboolean frame_sync_negotiated = _gdk_x11_surface_syncs_frames (surface);
gboolean frame_sync_negotiated = should_sync_frame_drawing (surface);
gboolean frame_done_painting = !impl->toplevel->frame_pending;
#ifdef HAVE_XDAMAGE
@@ -478,7 +478,7 @@ gdk_x11_surface_end_frame (GdkSurface *surface)
maybe_sync_counter_for_end_frame (surface);
if (_gdk_x11_surface_syncs_frames (surface))
if (should_sync_frame_drawing (surface))
{
impl->toplevel->frame_pending = TRUE;
gdk_surface_freeze_updates (surface);
-2
View File
@@ -179,7 +179,6 @@ GdkCursor *_gdk_x11_surface_get_cursor (GdkSurface *window);
void _gdk_x11_surface_update_size (GdkX11Surface *impl);
void _gdk_x11_surface_set_surface_scale (GdkSurface *window,
int scale);
gboolean _gdk_x11_surface_syncs_frames (GdkSurface *surface);
void gdk_x11_surface_pre_damage (GdkSurface *surface);
@@ -189,7 +188,6 @@ void gdk_x11_surface_move (GdkSurface *surface,
void gdk_x11_surface_check_monitor (GdkSurface *surface,
GdkMonitor *monitor);
G_END_DECLS
#endif /* __GDK_X11_SURFACE__ */
+1 -2
View File
@@ -123,8 +123,7 @@ gsk_transform_alloc (const GskTransformClass *transform_class,
self->transform_class = transform_class;
self->category = next ? MIN (category, next->category) : category;
self->next = gsk_transform_is_identity (next) ? NULL : gsk_transform_ref (next);
g_clear_pointer (&next, gsk_transform_unref);
self->next = gsk_transform_is_identity (next) ? NULL : next;
return self;
}
+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;
+1 -103
View File
@@ -1,7 +1,6 @@
/*
* Copyright © 2010 Codethink Limited
* Copyright © 2013 Canonical Limited
* Copyright © 2020 Emmanuel Gil Peyrot
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -25,42 +24,12 @@
#include "gtknative.h"
#include <gdk/wayland/gdkwayland.h>
#include <gdk/wayland/gdkdisplay-wayland.h>
#include <gdk/wayland/idle-inhibit-unstable-v1-client-protocol.h>
typedef struct
{
GtkApplicationImplDBusClass parent_class;
/* stores the dbus version of the overriden methods */
guint (*dbus_inhibit) (GtkApplicationImpl *impl,
GtkWindow *window,
GtkApplicationInhibitFlags flags,
const gchar *reason);
void (*dbus_uninhibit) (GtkApplicationImpl *impl,
guint cookie);
} GtkApplicationImplWaylandClass;
typedef struct
{
guint cookie;
guint dbus_cookie;
GtkApplicationInhibitFlags flags;
GdkSurface *surface;
} GtkApplicationWaylandInhibitor;
static void
gtk_application_wayland_inhibitor_free (GtkApplicationWaylandInhibitor *inhibitor)
{
g_slice_free (GtkApplicationWaylandInhibitor, inhibitor);
}
typedef GtkApplicationImplDBusClass GtkApplicationImplWaylandClass;
typedef struct
{
GtkApplicationImplDBus dbus;
GSList *inhibitors;
guint next_cookie;
} GtkApplicationImplWayland;
@@ -103,70 +72,6 @@ gtk_application_impl_wayland_before_emit (GtkApplicationImpl *impl,
gdk_wayland_display_set_startup_notification_id (gdk_display_get_default (), startup_notification_id);
}
static guint
gtk_application_impl_wayland_inhibit (GtkApplicationImpl *impl,
GtkWindow *window,
GtkApplicationInhibitFlags flags,
const gchar *reason)
{
GtkApplicationImplWayland *wayland = (GtkApplicationImplWayland *) impl;
GdkSurface *surface;
GtkApplicationWaylandInhibitor *inhibitor;
gboolean success;
if (!flags)
return 0;
inhibitor = g_slice_new (GtkApplicationWaylandInhibitor);
inhibitor->cookie = ++wayland->next_cookie;
inhibitor->flags = flags;
wayland->inhibitors = g_slist_prepend (wayland->inhibitors, inhibitor);
if (flags & GTK_APPLICATION_INHIBIT_IDLE)
{
surface = gtk_native_get_surface (GTK_NATIVE (window));
if (GDK_IS_WAYLAND_SURFACE (surface))
{
success = gdk_wayland_surface_inhibit_idle (surface);
if (success)
{
flags &= ~GTK_APPLICATION_INHIBIT_IDLE;
inhibitor->surface = surface;
}
}
}
inhibitor->dbus_cookie = ((GtkApplicationImplWaylandClass *) G_OBJECT_GET_CLASS (wayland))->dbus_inhibit (impl, window, flags, reason);
return inhibitor->cookie;
}
static void
gtk_application_impl_wayland_uninhibit (GtkApplicationImpl *impl,
guint cookie)
{
GtkApplicationImplWayland *wayland = (GtkApplicationImplWayland *) impl;
GSList *iter;
for (iter = wayland->inhibitors; iter; iter = iter->next)
{
GtkApplicationWaylandInhibitor *inhibitor = iter->data;
if (inhibitor->cookie == cookie)
{
if (inhibitor->dbus_cookie)
((GtkApplicationImplWaylandClass *) G_OBJECT_GET_CLASS (wayland))->dbus_uninhibit (impl, inhibitor->dbus_cookie);
if (inhibitor->surface)
gdk_wayland_surface_uninhibit_idle (inhibitor->surface);
gtk_application_wayland_inhibitor_free (inhibitor);
wayland->inhibitors = g_slist_delete_link (wayland->inhibitors, iter);
return;
}
}
g_warning ("Invalid inhibitor cookie");
}
static void
gtk_application_impl_wayland_init (GtkApplicationImplWayland *wayland)
{
@@ -177,15 +82,8 @@ gtk_application_impl_wayland_class_init (GtkApplicationImplWaylandClass *class)
{
GtkApplicationImplClass *impl_class = GTK_APPLICATION_IMPL_CLASS (class);
class->dbus_inhibit = impl_class->inhibit;
class->dbus_uninhibit = impl_class->uninhibit;
impl_class->handle_window_realize =
gtk_application_impl_wayland_handle_window_realize;
impl_class->before_emit =
gtk_application_impl_wayland_before_emit;
impl_class->inhibit =
gtk_application_impl_wayland_inhibit;
impl_class->uninhibit =
gtk_application_impl_wayland_uninhibit;
}
-1
View File
@@ -109,7 +109,6 @@ gtk_application_accels_set_accels_for_action (GtkApplicationAccels *accels,
}
g_list_store_remove (G_LIST_STORE (accels->shortcuts), i);
g_object_unref (shortcut_i);
break;
}
+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);
-2
View File
@@ -369,8 +369,6 @@ gtk_bookmark_list_start_loading (GtkBookmarkList *self)
self);
g_object_unref (file);
}
g_strfreev (uris);
}
else
{
+1 -3
View File
@@ -62,12 +62,10 @@ gtk_column_list_item_factory_setup (GtkListItemFactory *factory,
{
GtkColumnViewColumn *column = g_list_model_get_item (columns, i);
gtk_column_list_item_factory_add_column (self,
gtk_column_list_item_factory_add_column (self,
list_item->owner,
column,
FALSE);
g_object_unref (column);
}
}
+9 -6
View File
@@ -628,7 +628,7 @@ gtk_column_view_class_init (GtkColumnViewClass *klass)
g_param_spec_object ("model",
P_("Model"),
P_("Model for the items displayed"),
GTK_TYPE_SELECTION_MODEL,
G_TYPE_LIST_MODEL,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
@@ -1202,7 +1202,7 @@ gtk_column_view_new (void)
*
* Returns: (nullable) (transfer none): The model in use
**/
GtkSelectionModel *
GListModel *
gtk_column_view_get_model (GtkColumnView *self)
{
g_return_val_if_fail (GTK_IS_COLUMN_VIEW (self), NULL);
@@ -1215,14 +1215,17 @@ gtk_column_view_get_model (GtkColumnView *self)
* @self: a #GtkColumnView
* @model: (allow-none) (transfer none): the model to use or %NULL for none
*
* Sets the #GtkSelectionModel to use.
* Sets the #GListModel to use.
*
* If the @model is a #GtkSelectionModel, it is used for managing the selection.
* Otherwise, @self creates a #GtkSingleSelection for the selection.
**/
void
gtk_column_view_set_model (GtkColumnView *self,
GtkSelectionModel *model)
gtk_column_view_set_model (GtkColumnView *self,
GListModel *model)
{
g_return_if_fail (GTK_IS_COLUMN_VIEW (self));
g_return_if_fail (model == NULL || GTK_IS_SELECTION_MODEL (model));
g_return_if_fail (model == NULL || G_IS_LIST_MODEL (model));
if (gtk_list_view_get_model (self->listview) == model)
return;
+2 -4
View File
@@ -26,7 +26,6 @@
#include <gtk/gtktypes.h>
#include <gtk/gtksortlistmodel.h>
#include <gtk/gtkselectionmodel.h>
#include <gtk/gtksorter.h>
G_BEGIN_DECLS
@@ -68,10 +67,10 @@ void gtk_column_view_insert_column (GtkColumnView
GtkColumnViewColumn *column);
GDK_AVAILABLE_IN_ALL
GtkSelectionModel * gtk_column_view_get_model (GtkColumnView *self);
GListModel * gtk_column_view_get_model (GtkColumnView *self);
GDK_AVAILABLE_IN_ALL
void gtk_column_view_set_model (GtkColumnView *self,
GtkSelectionModel *model);
GListModel *model);
GDK_AVAILABLE_IN_ALL
gboolean gtk_column_view_get_show_row_separators (GtkColumnView *self);
@@ -106,7 +105,6 @@ void gtk_column_view_set_reorderable (GtkColumnView
GDK_AVAILABLE_IN_ALL
gboolean gtk_column_view_get_reorderable (GtkColumnView *self);
GDK_AVAILABLE_IN_ALL
void gtk_column_view_set_enable_rubberband (GtkColumnView *self,
gboolean enable_rubberband);
GDK_AVAILABLE_IN_ALL
-1
View File
@@ -85,7 +85,6 @@ void gtk_column_view_column_set_header_menu (GtkColu
GDK_AVAILABLE_IN_ALL
GMenuModel * gtk_column_view_column_get_header_menu (GtkColumnViewColumn *self);
GDK_AVAILABLE_IN_ALL
void gtk_column_view_column_set_fixed_width (GtkColumnViewColumn *self,
int fixed_width);
GDK_AVAILABLE_IN_ALL
-8
View File
@@ -115,14 +115,6 @@ gtk_column_view_sorter_dispose (GObject *object)
{
GtkColumnViewSorter *self = GTK_COLUMN_VIEW_SORTER (object);
/* The sorter is owned by the columview and is unreffed
* after the columns, so the sequence must be empty at
* this point.
* The sorter can outlive the columview it comes from
* (the model might still have a ref), but that does
* not change the fact that all columns will be gone.
*/
g_assert (g_sequence_is_empty (self->sorters));
g_clear_pointer (&self->sorters, g_sequence_free);
G_OBJECT_CLASS (gtk_column_view_sorter_parent_class)->dispose (object);
+33 -30
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);
@@ -560,12 +562,10 @@ css_provider_commit (GtkCssProvider *css_provider,
if (ruleset->styles == NULL)
{
for (i = 0; i < n_selectors; i++)
_gtk_css_selector_free (selectors[i]);
return;
}
for (i = 0; i < n_selectors; i++)
for (i = 0; i < n_selectors; i ++)
{
GtkCssRuleset *new;
@@ -768,11 +768,7 @@ parse_selector_list (GtkCssScanner *scanner,
GtkCssSelector *select = _gtk_css_selector_parse (scanner->parser);
if (select == NULL)
{
for (int i = 0; i < n_selectors; i++)
g_clear_pointer (&out_selectors[i], _gtk_css_selector_free);
return 0;
}
return 0;
out_selectors[n_selectors] = select;
n_selectors++;
@@ -782,8 +778,6 @@ parse_selector_list (GtkCssScanner *scanner,
gtk_css_parser_error_syntax (scanner->parser,
"Only %u selectors per ruleset allowed",
MAX_SELECTOR_LIST_LENGTH);
for (int i = 0; i < MAX_SELECTOR_LIST_LENGTH; i++)
g_clear_pointer (&out_selectors[i], _gtk_css_selector_free);
return 0;
}
}
@@ -812,7 +806,10 @@ parse_declaration (GtkCssScanner *scanner,
name = gtk_css_parser_consume_ident (scanner->parser);
if (name == NULL)
goto out;
{
gtk_css_parser_end_block (scanner->parser);
return;
}
property = _gtk_style_property_lookup (name);
@@ -824,18 +821,25 @@ parse_declaration (GtkCssScanner *scanner,
if (!gtk_css_parser_try_token (scanner->parser, GTK_CSS_TOKEN_COLON))
{
gtk_css_parser_error_syntax (scanner->parser, "Expected ':'");
goto out;
g_free (name);
gtk_css_parser_end_block (scanner->parser);
return;
}
value = _gtk_style_property_parse_value (property, scanner->parser);
value = _gtk_style_property_parse_value (property,
scanner->parser);
if (value == NULL)
goto out;
{
gtk_css_parser_end_block (scanner->parser);
return;
}
if (!gtk_css_parser_has_token (scanner->parser, GTK_CSS_TOKEN_EOF))
{
gtk_css_parser_error_syntax (scanner->parser, "Junk at end of value for %s", property->name);
goto out;
gtk_css_parser_end_block (scanner->parser);
return;
}
if (gtk_keep_css_sections)
@@ -880,7 +884,6 @@ parse_declaration (GtkCssScanner *scanner,
gtk_css_parser_error_value (scanner->parser, "No property named \"%s\"", name);
}
out:
g_free (name);
gtk_css_parser_end_block (scanner->parser);
@@ -915,7 +918,7 @@ parse_ruleset (GtkCssScanner *scanner)
{
guint i;
gtk_css_parser_error_syntax (scanner->parser, "Expected '{' after selectors");
for (i = 0; i < n_selectors; i++)
for (i = 0; i < n_selectors; i ++)
_gtk_css_selector_free (selectors[i]);
gtk_css_parser_skip_until (scanner->parser, GTK_CSS_TOKEN_OPEN_CURLY);
gtk_css_parser_skip (scanner->parser);
+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 GDK_ARRAY_ELEMENT_TYPE gpointer
#define GDK_ARRAY_TYPE_NAME GtkCssSelectorMatches
#define GDK_ARRAY_NAME gtk_css_selector_matches
#define GDK_ARRAY_PREALLOC 32
#include "gdk/gdkarrayimpl.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);
+9 -9
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);
@@ -513,7 +513,7 @@ update_combo_sensitivity_from_printers (GtkCustomPaperUnixDialog *dialog)
static void
update_custom_widgets_from_list (GtkCustomPaperUnixDialog *dialog)
{
GtkSelectionModel *model;
GListModel *model;
GtkPageSetup *page_setup;
model = gtk_list_view_get_model (GTK_LIST_VIEW (dialog->listview));
@@ -559,7 +559,7 @@ static void
unit_widget_changed (GtkCustomPaperUnixDialog *dialog)
{
double w, h, top, bottom, left, right;
GtkSelectionModel *model;
GListModel *model;
GtkPageSetup *page_setup;
GtkPaperSize *paper_size;
@@ -648,7 +648,7 @@ add_custom_paper (GtkCustomPaperUnixDialog *dialog)
static void
remove_custom_paper (GtkCustomPaperUnixDialog *dialog)
{
GtkSelectionModel *model;
GListModel *model;
guint selected;
model = gtk_list_view_get_model (GTK_LIST_VIEW (dialog->listview));
@@ -870,7 +870,7 @@ populate_dialog (GtkCustomPaperUnixDialog *dialog)
GtkWidget *grid, *label, *widget, *frame, *combo;
GtkWidget *hbox, *vbox, *listview, *scrolled, *toolbar, *button;
GtkUnit user_units;
GtkSingleSelection *selection;
GListModel *model;
GtkListItemFactory *factory;
content_area = gtk_dialog_get_content_area (cpu_dialog);
@@ -899,10 +899,10 @@ populate_dialog (GtkCustomPaperUnixDialog *dialog)
listview = gtk_list_view_new ();
gtk_widget_set_size_request (listview, 140, -1);
selection = gtk_single_selection_new (G_LIST_MODEL (dialog->custom_paper_list));
gtk_list_view_set_model (GTK_LIST_VIEW (listview), GTK_SELECTION_MODEL (selection));
g_signal_connect (selection, "notify::selected", G_CALLBACK (selected_custom_paper_changed), dialog);
g_object_unref (selection);
model = G_LIST_MODEL (gtk_single_selection_new (G_LIST_MODEL (dialog->custom_paper_list)));
gtk_list_view_set_model (GTK_LIST_VIEW (listview), model);
g_signal_connect (model, "notify::selected", G_CALLBACK (selected_custom_paper_changed), dialog);
g_object_unref (model);
factory = gtk_signal_list_item_factory_new ();
g_signal_connect (factory, "setup", G_CALLBACK (setup_item), NULL);
+4 -229
View File
@@ -62,7 +62,6 @@ enum {
PROP_IO_PRIORITY,
PROP_ITEM_TYPE,
PROP_LOADING,
PROP_MONITORED,
NUM_PROPERTIES
};
@@ -71,10 +70,8 @@ struct _GtkDirectoryList
GObject parent_instance;
char *attributes;
GFile *file;
GFileMonitor *monitor;
gboolean monitored;
int io_priority;
GFile *file;
GCancellable *cancellable;
GError *error; /* Error while loading */
@@ -150,17 +147,13 @@ gtk_directory_list_set_property (GObject *object,
gtk_directory_list_set_io_priority (self, g_value_get_int (value));
break;
case PROP_MONITORED:
gtk_directory_list_set_monitored (self, g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
static void
gtk_directory_list_get_property (GObject *object,
guint prop_id,
GValue *value,
@@ -194,10 +187,6 @@ gtk_directory_list_get_property (GObject *object,
g_value_set_boolean (value, gtk_directory_list_is_loading (self));
break;
case PROP_MONITORED:
g_value_set_boolean (value, gtk_directory_list_get_monitored (self));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -215,27 +204,12 @@ gtk_directory_list_stop_loading (GtkDirectoryList *self)
return TRUE;
}
static void directory_changed (GFileMonitor *monitor,
GFile *file,
GFile *other_file,
GFileMonitorEvent event,
gpointer data);
static void
gtk_directory_list_stop_monitoring (GtkDirectoryList *self)
{
if (self->monitor)
g_signal_handlers_disconnect_by_func (self->monitor, directory_changed, self);
g_clear_object (&self->monitor);
}
static void
gtk_directory_list_dispose (GObject *object)
{
GtkDirectoryList *self = GTK_DIRECTORY_LIST (object);
gtk_directory_list_stop_loading (self);
gtk_directory_list_stop_monitoring (self);
g_clear_object (&self->file);
g_clear_pointer (&self->attributes, g_free);
@@ -327,18 +301,6 @@ gtk_directory_list_class_init (GtkDirectoryListClass *class)
FALSE,
GTK_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY);
/**
* GtkDirectoryList:monitored:
*
* %TRUE if the directory is monitored for changed
*/
properties[PROP_MONITORED] =
g_param_spec_boolean ("monitored",
P_("monitored"),
P_("TRUE if the directory is monitored for changes"),
TRUE,
GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
g_object_class_install_properties (gobject_class, NUM_PROPERTIES, properties);
}
@@ -347,7 +309,6 @@ gtk_directory_list_init (GtkDirectoryList *self)
{
self->items = g_sequence_new (g_object_unref);
self->io_priority = G_PRIORITY_DEFAULT;
self->monitored = TRUE;
}
/**
@@ -363,6 +324,7 @@ gtk_directory_list_init (GtkDirectoryList *self)
GtkDirectoryList *
gtk_directory_list_new (const char *attributes,
GFile *file)
{
g_return_val_if_fail (file == NULL || G_IS_FILE (file), NULL);
@@ -448,7 +410,7 @@ gtk_directory_list_got_files_cb (GObject *source,
{
GFileInfo *info;
GFile *file;
info = l->data;
file = g_file_enumerator_get_child (enumerator, info);
g_file_info_set_attribute_object (info, "standard::file", G_OBJECT (file));
@@ -534,143 +496,6 @@ gtk_directory_list_start_loading (GtkDirectoryList *self)
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_LOADING]);
}
static void
got_new_file_info_cb (GObject *source,
GAsyncResult *res,
gpointer data)
{
GFile *file = G_FILE (source);
GtkDirectoryList *self = GTK_DIRECTORY_LIST (data);
GFileInfo *info;
guint position;
info = g_file_query_info_finish (file, res, NULL);
if (!info)
return;
g_file_info_set_attribute_object (info, "standard::file", G_OBJECT (file));
position = g_sequence_get_length (self->items);
g_sequence_append (self->items, info);
g_list_model_items_changed (G_LIST_MODEL (self), position, 0, 1);
}
static void
got_existing_file_info_cb (GObject *source,
GAsyncResult *res,
gpointer data)
{
GFile *file = G_FILE (source);
GtkDirectoryList *self = GTK_DIRECTORY_LIST (data);
GFileInfo *info;
GSequenceIter *iter;
info = g_file_query_info_finish (file, res, NULL);
if (!info)
return;
g_file_info_set_attribute_object (info, "standard::file", G_OBJECT (file));
for (iter = g_sequence_get_begin_iter (self->items);
!g_sequence_iter_is_end (iter);
iter = g_sequence_iter_next (iter))
{
GFileInfo *item = g_sequence_get (iter);
GFile *f = G_FILE (g_file_info_get_attribute_object (item, "standard::file"));
if (g_file_equal (f, file))
{
guint position = g_sequence_iter_get_position (iter);
g_sequence_set (iter, g_object_ref (info));
g_list_model_items_changed (G_LIST_MODEL (self), position, 1, 1);
break;
}
}
}
static void
gtk_directory_list_remove_file (GtkDirectoryList *self,
GFile *file)
{
GSequenceIter *iter;
for (iter = g_sequence_get_begin_iter (self->items);
!g_sequence_iter_is_end (iter);
iter = g_sequence_iter_next (iter))
{
GFileInfo *item = g_sequence_get (iter);
GFile *f = G_FILE (g_file_info_get_attribute_object (item, "standard::file"));
if (g_file_equal (f, file))
{
guint position = g_sequence_iter_get_position (iter);
g_sequence_remove (iter);
g_list_model_items_changed (G_LIST_MODEL (self), position, 1, 0);
break;
}
}
}
static void
directory_changed (GFileMonitor *monitor,
GFile *file,
GFile *other_file,
GFileMonitorEvent event,
gpointer data)
{
GtkDirectoryList *self = GTK_DIRECTORY_LIST (data);
switch (event)
{
case G_FILE_MONITOR_EVENT_CREATED:
g_file_query_info_async (file,
self->attributes,
G_FILE_QUERY_INFO_NONE,
self->io_priority,
self->cancellable,
got_new_file_info_cb,
self);
break;
case G_FILE_MONITOR_EVENT_DELETED:
gtk_directory_list_remove_file (self, file);
break;
case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED:
g_file_query_info_async (file,
self->attributes,
G_FILE_QUERY_INFO_NONE,
self->io_priority,
self->cancellable,
got_existing_file_info_cb,
self);
break;
case G_FILE_MONITOR_EVENT_CHANGED:
case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
case G_FILE_MONITOR_EVENT_PRE_UNMOUNT:
case G_FILE_MONITOR_EVENT_UNMOUNTED:
case G_FILE_MONITOR_EVENT_MOVED:
case G_FILE_MONITOR_EVENT_RENAMED:
case G_FILE_MONITOR_EVENT_MOVED_IN:
case G_FILE_MONITOR_EVENT_MOVED_OUT:
default:
break;
}
}
static void
gtk_directory_list_start_monitoring (GtkDirectoryList *self)
{
g_assert (self->monitor == NULL);
self->monitor = g_file_monitor_directory (self->file, G_FILE_MONITOR_NONE, NULL, NULL);
g_signal_connect (self->monitor, "changed", G_CALLBACK (directory_changed), self);
}
static void
gtk_directory_list_update_monitoring (GtkDirectoryList *self)
{
gtk_directory_list_stop_monitoring (self);
if (self->file && self->monitored)
gtk_directory_list_start_monitoring (self);
}
/**
* gtk_directory_list_set_file:
* @self: a #GtkDirectoryList
@@ -695,7 +520,6 @@ gtk_directory_list_set_file (GtkDirectoryList *self,
g_set_object (&self->file, file);
gtk_directory_list_update_monitoring (self);
gtk_directory_list_start_loading (self);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FILE]);
@@ -855,52 +679,3 @@ gtk_directory_list_get_error (GtkDirectoryList *self)
return self->error;
}
/**
* gtk_directory_list_set_monitored:
* @self: a #GtkDirectoryList
* @monitored: %TRUE to monitor the directory for changes
*
* Sets whether the directory list will monitor the directory
* for changes. If monitoring is enabled, the
* #GListModel::items-changed signal will be emitted when the
* directory contents change.
*
* When monitoring is turned on after the initial creation
* of the directory list, the directory is reloaded to avoid
* missing files that appeared between the initial loading
* and when monitoring was turned on.
*/
void
gtk_directory_list_set_monitored (GtkDirectoryList *self,
gboolean monitored)
{
g_return_if_fail (GTK_IS_DIRECTORY_LIST (self));
if (self->monitored == monitored)
return;
self->monitored = monitored;
gtk_directory_list_update_monitoring (self);
if (monitored)
gtk_directory_list_start_loading (self);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MONITORED]);
}
/**
* gtk_directory_list_get_monitored:
* @self: a #GtkDirectoryList
*
* Returns whether the directory list is monitoring
* the directory for changes.
*
* Returns: %TRUE if the directory is monitored
*/
gboolean
gtk_directory_list_get_monitored (GtkDirectoryList *self)
{
g_return_val_if_fail (GTK_IS_DIRECTORY_LIST (self), TRUE);
return self->monitored;
}
-6
View File
@@ -62,12 +62,6 @@ gboolean gtk_directory_list_is_loading (GtkDirectoryLis
GDK_AVAILABLE_IN_ALL
const GError * gtk_directory_list_get_error (GtkDirectoryList *self);
GDK_AVAILABLE_IN_ALL
void gtk_directory_list_set_monitored (GtkDirectoryList *self,
gboolean monitored);
GDK_AVAILABLE_IN_ALL
gboolean gtk_directory_list_get_monitored (GtkDirectoryList *self);
G_END_DECLS
#endif /* __GTK_DIRECTORY_LIST_H__ */
+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);
+5 -4
View File
@@ -205,8 +205,9 @@ update_filter (GtkDropDown *self)
if (self->expression)
{
filter = gtk_string_filter_new (gtk_expression_ref (self->expression));
filter = gtk_string_filter_new ();
gtk_string_filter_set_match_mode (GTK_STRING_FILTER (filter), GTK_STRING_FILTER_MATCH_MODE_PREFIX);
gtk_string_filter_set_expression (GTK_STRING_FILTER (filter), self->expression);
}
else
filter = gtk_every_filter_new ();
@@ -673,7 +674,7 @@ gtk_drop_down_set_model (GtkDropDown *self,
selection = G_LIST_MODEL (gtk_single_selection_new (filter_model));
g_set_object (&self->popup_selection, selection);
gtk_list_view_set_model (GTK_LIST_VIEW (self->popup_list), GTK_SELECTION_MODEL (selection));
gtk_list_view_set_model (GTK_LIST_VIEW (self->popup_list), selection);
g_object_unref (selection);
selection = G_LIST_MODEL (gtk_single_selection_new (model));
@@ -926,7 +927,7 @@ gtk_drop_down_get_expression (GtkDropDown *self)
/**
* gtk_drop_down_set_from_strings:
* @self: a #GtkDropDown
* @texts: (array zero-terminated=1) (element-type utf8): a %NULL-terminated string array
* @texts: a %NULL-terminated string array
*
* Populates @self with the strings in @text,
* by creating a suitable model and factory.
@@ -942,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);
-74
View File
@@ -855,24 +855,6 @@ gtk_constant_expression_new_for_value (const GValue *value)
return result;
}
/**
* gtk_constant_expression_get_value:
* @expression: a constant #GtkExpression
*
* Gets the value that a constant expression evaluates to.
*
* Returns: (transfer none): the value
*/
const GValue *
gtk_constant_expression_get_value (GtkExpression *expression)
{
GtkConstantExpression *self = (GtkConstantExpression *) expression;
g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (expression, GTK_TYPE_CONSTANT_EXPRESSION), NULL);
return &self->value;
}
/* }}} */
/* {{{ GtkObjectExpression */
@@ -1020,24 +1002,6 @@ gtk_object_expression_new (GObject *object)
return result;
}
/**
* gtk_object_expression_get_object:
* @expression: an object #GtkExpression
*
* Gets the object that the expression evaluates to.
*
* Returns: (transfer none): the object, or %NULL
*/
GObject *
gtk_object_expression_get_object (GtkExpression *expression)
{
GtkObjectExpression *self = (GtkObjectExpression *) expression;
g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (expression, GTK_TYPE_OBJECT_EXPRESSION), NULL);
return self->object;
}
/* }}} */
/* {{{ GtkPropertyExpression */
@@ -1343,44 +1307,6 @@ gtk_property_expression_new_for_pspec (GtkExpression *expression,
return result;
}
/**
* gtk_property_expression_get_expression:
* @expression: a property #GtkExpression
*
* Gets the expression specifying the object of
* a property expression.
*
* Returns: (transfer none): the object expression
*/
GtkExpression *
gtk_property_expression_get_expression (GtkExpression *expression)
{
GtkPropertyExpression *self = (GtkPropertyExpression *) expression;
g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (expression, GTK_TYPE_PROPERTY_EXPRESSION), NULL);
return self->expr;
}
/**
* gtk_property_expression_get_pspec:
* @expression: a property #GtkExpression
*
* Gets the #GParamSpec specifying the property of
* a property expression.
*
* Returns: (transfer none): the #GParamSpec
*/
GParamSpec *
gtk_property_expression_get_pspec (GtkExpression *expression)
{
GtkPropertyExpression *self = (GtkPropertyExpression *) expression;
g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (expression, GTK_TYPE_PROPERTY_EXPRESSION), NULL);
return self->pspec;
}
/* }}} */
/* {{{ GtkClosureExpression */
-11
View File
@@ -93,11 +93,6 @@ GDK_AVAILABLE_IN_ALL
GtkExpression * gtk_property_expression_new_for_pspec (GtkExpression *expression,
GParamSpec *pspec);
GDK_AVAILABLE_IN_ALL
GtkExpression * gtk_property_expression_get_expression (GtkExpression *expression);
GDK_AVAILABLE_IN_ALL
GParamSpec * gtk_property_expression_get_pspec (GtkExpression *expression);
#define GTK_TYPE_CONSTANT_EXPRESSION (gtk_constant_expression_get_type())
typedef struct _GtkConstantExpression GtkConstantExpression;
@@ -110,9 +105,6 @@ GtkExpression * gtk_constant_expression_new (GType
GDK_AVAILABLE_IN_ALL
GtkExpression * gtk_constant_expression_new_for_value (const GValue *value);
GDK_AVAILABLE_IN_ALL
const GValue * gtk_constant_expression_get_value (GtkExpression *expression);
#define GTK_TYPE_OBJECT_EXPRESSION (gtk_object_expression_get_type())
typedef struct _GtkObjectExpression GtkObjectExpression;
@@ -122,9 +114,6 @@ GType gtk_object_expression_get_type (void) G_GNUC_CO
GDK_AVAILABLE_IN_ALL
GtkExpression * gtk_object_expression_new (GObject *object);
GDK_AVAILABLE_IN_ALL
GObject * gtk_object_expression_get_object (GtkExpression *expression);
#define GTK_TYPE_CLOSURE_EXPRESSION (gtk_closure_expression_get_type())
typedef struct _GtkClosureExpression GtkClosureExpression;
+120 -63
View File
@@ -79,6 +79,75 @@ G_DEFINE_INTERFACE (GtkFileChooser, gtk_file_chooser, G_TYPE_OBJECT);
static void
gtk_file_chooser_default_init (GtkFileChooserInterface *iface)
{
GType iface_type = G_TYPE_FROM_INTERFACE (iface);
/**
* GtkFileChooser::current-folder-changed:
* @chooser: the object which received the signal.
*
* This signal is emitted when the current folder in a #GtkFileChooser
* changes. This can happen due to the user performing some action that
* changes folders, such as selecting a bookmark or visiting a folder on the
* file list. It can also happen as a result of calling a function to
* explicitly change the current folder in a file chooser.
*
* Normally you do not need to connect to this signal, unless you need to keep
* track of which folder a file chooser is showing.
*
* See also: gtk_file_chooser_set_current_folder(),
* gtk_file_chooser_get_current_folder(),
*/
g_signal_new (I_("current-folder-changed"),
iface_type,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkFileChooserIface, current_folder_changed),
NULL, NULL,
NULL,
G_TYPE_NONE, 0);
/**
* GtkFileChooser::selection-changed:
* @chooser: the object which received the signal.
*
* This signal is emitted when there is a change in the set of selected files
* in a #GtkFileChooser. This can happen when the user modifies the selection
* with the mouse or the keyboard, or when explicitly calling functions to
* change the selection.
*
* Normally you do not need to connect to this signal, as it is easier to wait
* for the file chooser to finish running, and then to get the list of
* selected files using the functions mentioned below.
*/
g_signal_new (I_("selection-changed"),
iface_type,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkFileChooserIface, selection_changed),
NULL, NULL,
NULL,
G_TYPE_NONE, 0);
/**
* GtkFileChooser::file-activated:
* @chooser: the object which received the signal.
*
* This signal is emitted when the user "activates" a file in the file
* chooser. This can happen by double-clicking on a file in the file list, or
* by pressing `Enter`.
*
* Normally you do not need to connect to this signal. It is used internally
* by #GtkFileChooserDialog to know when to activate the default button in the
* dialog.
*
* See also: gtk_file_chooser_get_file(), gtk_file_chooser_get_files()
*/
g_signal_new (I_("file-activated"),
iface_type,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkFileChooserIface, file_activated),
NULL, NULL,
NULL,
G_TYPE_NONE, 0);
g_object_interface_install_property (iface,
g_param_spec_enum ("action",
P_("Action"),
@@ -99,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:
*
@@ -439,15 +476,16 @@ gtk_file_chooser_unselect_file (GtkFileChooser *chooser,
/**
* gtk_file_chooser_get_files:
* @chooser: a #GtkFileChooser
*
* Lists all the selected files and subfolders in the current folder of @chooser
* as #GFile.
*
* Lists all the selected files and subfolders in the current folder
* of @chooser as #GFile.
*
* Returns: (transfer full): a list model containing a #GFile for each
* selected file and subfolder in the current folder. Free the returned
* list with g_object_unref().
*/
GListModel *
* Returns: (element-type GFile) (transfer full): a list
* containing a #GFile for each selected file and subfolder in the
* current folder. Free the returned list with g_slist_free(), and
* the files with g_object_unref().
**/
GSList *
gtk_file_chooser_get_files (GtkFileChooser *chooser)
{
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
@@ -527,19 +565,41 @@ gtk_file_chooser_set_file (GtkFileChooser *chooser,
GFile *
gtk_file_chooser_get_file (GtkFileChooser *chooser)
{
GListModel *list;
GSList *list;
GFile *result = NULL;
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
list = gtk_file_chooser_get_files (chooser);
if (g_list_model_get_n_items (list) > 0)
result = g_list_model_get_item (list, 0);
g_object_unref (list);
if (list)
{
result = list->data;
list = g_slist_delete_link (list, list);
g_slist_free_full (list, g_object_unref);
}
return result;
}
/*< private >
* _gtk_file_chooser_get_file_system:
* @chooser: a #GtkFileChooser
*
* Gets the #GtkFileSystem of @chooser; this is an internal
* implementation detail, used for conversion between paths
* and filenames and URIs.
*
* Returns: the file system for @chooser.
**/
GtkFileSystem *
_gtk_file_chooser_get_file_system (GtkFileChooser *chooser)
{
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
return GTK_FILE_CHOOSER_GET_IFACE (chooser)->get_file_system (chooser);
}
/**
* gtk_file_chooser_add_shortcut_folder:
* @chooser: a #GtkFileChooser
@@ -622,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);
}
/**
@@ -691,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);
}
/**
+68 -61
View File
@@ -72,8 +72,7 @@ GType gtk_file_chooser_get_type (void) G_GNUC_CONST;
* @GTK_FILE_CHOOSER_ERROR_BAD_FILENAME: Indicates a malformed filename.
* @GTK_FILE_CHOOSER_ERROR_ALREADY_EXISTS: Indicates a duplicate path (e.g. when
* adding a bookmark).
* @GTK_FILE_CHOOSER_ERROR_INCOMPLETE_HOSTNAME: Indicates an incomplete hostname
* (e.g. "http://foo" without a slash after that).
* @GTK_FILE_CHOOSER_ERROR_INCOMPLETE_HOSTNAME: Indicates an incomplete hostname (e.g. "http://foo" without a slash after that).
*
* These identify the various errors that can occur while calling
* #GtkFileChooser functions.
@@ -88,100 +87,108 @@ typedef enum {
GDK_AVAILABLE_IN_ALL
GQuark gtk_file_chooser_error_quark (void);
/* Configuration */
/* Configuration
*/
GDK_AVAILABLE_IN_ALL
void gtk_file_chooser_set_action (GtkFileChooser *chooser,
GtkFileChooserAction action);
GtkFileChooserAction action);
GDK_AVAILABLE_IN_ALL
GtkFileChooserAction gtk_file_chooser_get_action (GtkFileChooser *chooser);
GDK_AVAILABLE_IN_ALL
void gtk_file_chooser_set_select_multiple (GtkFileChooser *chooser,
gboolean select_multiple);
gboolean select_multiple);
GDK_AVAILABLE_IN_ALL
gboolean gtk_file_chooser_get_select_multiple (GtkFileChooser *chooser);
GDK_AVAILABLE_IN_ALL
void gtk_file_chooser_set_create_folders (GtkFileChooser *chooser,
gboolean create_folders);
gboolean create_folders);
GDK_AVAILABLE_IN_ALL
gboolean gtk_file_chooser_get_create_folders (GtkFileChooser *chooser);
gboolean gtk_file_chooser_get_create_folders (GtkFileChooser *chooser);
/* Suggested name for the Save-type actions */
/* Suggested name for the Save-type actions
*/
GDK_AVAILABLE_IN_ALL
void gtk_file_chooser_set_current_name (GtkFileChooser *chooser,
const gchar *name);
GDK_AVAILABLE_IN_ALL
gchar *gtk_file_chooser_get_current_name (GtkFileChooser *chooser);
GDK_AVAILABLE_IN_ALL
void gtk_file_chooser_set_current_name (GtkFileChooser *chooser,
const char *name);
void gtk_file_chooser_select_all (GtkFileChooser *chooser);
GDK_AVAILABLE_IN_ALL
char * gtk_file_chooser_get_current_name (GtkFileChooser *chooser);
void gtk_file_chooser_unselect_all (GtkFileChooser *chooser);
/* GFile manipulation */
GDK_AVAILABLE_IN_ALL
GFile * gtk_file_chooser_get_file (GtkFileChooser *chooser);
GDK_AVAILABLE_IN_ALL
gboolean gtk_file_chooser_set_file (GtkFileChooser *chooser,
GFile *file,
GError **error);
GDK_AVAILABLE_IN_ALL
gboolean gtk_file_chooser_select_file (GtkFileChooser *chooser,
GFile *file,
GError **error);
GDK_AVAILABLE_IN_ALL
void gtk_file_chooser_unselect_file (GtkFileChooser *chooser,
GFile *file);
GDK_AVAILABLE_IN_ALL
GSList * gtk_file_chooser_get_files (GtkFileChooser *chooser);
GDK_AVAILABLE_IN_ALL
gboolean gtk_file_chooser_set_current_folder (GtkFileChooser *chooser,
GFile *file,
GError **error);
GDK_AVAILABLE_IN_ALL
GFile * gtk_file_chooser_get_current_folder (GtkFileChooser *chooser);
/* List of user selectable filters
*/
GDK_AVAILABLE_IN_ALL
GFile * gtk_file_chooser_get_file (GtkFileChooser *chooser);
void gtk_file_chooser_add_filter (GtkFileChooser *chooser,
GtkFileFilter *filter);
GDK_AVAILABLE_IN_ALL
gboolean gtk_file_chooser_set_file (GtkFileChooser *chooser,
GFile *file,
GError **error);
void gtk_file_chooser_remove_filter (GtkFileChooser *chooser,
GtkFileFilter *filter);
GDK_AVAILABLE_IN_ALL
GListModel * gtk_file_chooser_get_files (GtkFileChooser *chooser);
GDK_AVAILABLE_IN_ALL
gboolean gtk_file_chooser_set_current_folder (GtkFileChooser *chooser,
GFile *file,
GError **error);
GDK_AVAILABLE_IN_ALL
GFile * gtk_file_chooser_get_current_folder (GtkFileChooser *chooser);
/* List of user selectable filters */
GSList *gtk_file_chooser_list_filters (GtkFileChooser *chooser);
/* Current filter
*/
GDK_AVAILABLE_IN_ALL
void gtk_file_chooser_add_filter (GtkFileChooser *chooser,
GtkFileFilter *filter);
void gtk_file_chooser_set_filter (GtkFileChooser *chooser,
GtkFileFilter *filter);
GDK_AVAILABLE_IN_ALL
void gtk_file_chooser_remove_filter (GtkFileChooser *chooser,
GtkFileFilter *filter);
GDK_AVAILABLE_IN_ALL
GListModel * gtk_file_chooser_get_filters (GtkFileChooser *chooser);
/* Current filter */
GDK_AVAILABLE_IN_ALL
void gtk_file_chooser_set_filter (GtkFileChooser *chooser,
GtkFileFilter *filter);
GDK_AVAILABLE_IN_ALL
GtkFileFilter * gtk_file_chooser_get_filter (GtkFileChooser *chooser);
GtkFileFilter *gtk_file_chooser_get_filter (GtkFileChooser *chooser);
/* Per-application shortcut folders */
GDK_AVAILABLE_IN_ALL
gboolean gtk_file_chooser_add_shortcut_folder (GtkFileChooser *chooser,
GFile *folder,
GError **error);
gboolean gtk_file_chooser_add_shortcut_folder (GtkFileChooser *chooser,
GFile *folder,
GError **error);
GDK_AVAILABLE_IN_ALL
gboolean gtk_file_chooser_remove_shortcut_folder
(GtkFileChooser *chooser,
GFile *folder,
GError **error);
gboolean gtk_file_chooser_remove_shortcut_folder (GtkFileChooser *chooser,
GFile *folder,
GError **error);
GDK_AVAILABLE_IN_ALL
GListModel * gtk_file_chooser_get_shortcut_folders (GtkFileChooser *chooser);
/* Custom widgets */
GSList *gtk_file_chooser_list_shortcut_folders (GtkFileChooser *chooser);
GDK_AVAILABLE_IN_ALL
void gtk_file_chooser_add_choice (GtkFileChooser *chooser,
const char *id,
const char *label,
const char **options,
const char **option_labels);
void gtk_file_chooser_add_choice (GtkFileChooser *chooser,
const char *id,
const char *label,
const char **options,
const char **option_labels);
GDK_AVAILABLE_IN_ALL
void gtk_file_chooser_remove_choice (GtkFileChooser *chooser,
const char *id);
void gtk_file_chooser_remove_choice (GtkFileChooser *chooser,
const char *id);
GDK_AVAILABLE_IN_ALL
void gtk_file_chooser_set_choice (GtkFileChooser *chooser,
const char *id,
const char *option);
void gtk_file_chooser_set_choice (GtkFileChooser *chooser,
const char *id,
const char *option);
GDK_AVAILABLE_IN_ALL
const char * gtk_file_chooser_get_choice (GtkFileChooser *chooser,
const char *id);
const char *gtk_file_chooser_get_choice (GtkFileChooser *chooser,
const char *id);
G_END_DECLS
+583 -792
View File
File diff suppressed because it is too large Load Diff
+43 -11
View File
@@ -25,6 +25,8 @@
#include "gtkfilechooserwidget.h"
#include "gtkfilechooserwidgetprivate.h"
#include "gtkfilechooserutils.h"
#include "gtkfilechooserembed.h"
#include "gtkfilesystem.h"
#include "gtksizerequest.h"
#include "gtktypebuiltins.h"
#include "gtkintl.h"
@@ -263,9 +265,12 @@ static void gtk_file_chooser_dialog_size_allocate (GtkWidget *wid
int width,
int height,
int baseline);
static void gtk_file_chooser_dialog_activate_response (GtkWidget *widget,
const char *action_name,
GVariant *parameters);
static void file_chooser_widget_file_activated (GtkFileChooser *chooser,
GtkFileChooserDialog *dialog);
static void file_chooser_widget_response_requested (GtkWidget *widget,
GtkFileChooserDialog *dialog);
static void file_chooser_widget_selection_changed (GtkWidget *widget,
GtkFileChooserDialog *dialog);
static void response_cb (GtkDialog *dialog,
gint response_id);
@@ -305,8 +310,9 @@ gtk_file_chooser_dialog_class_init (GtkFileChooserDialogClass *class)
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserDialog, widget);
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserDialog, buttons);
gtk_widget_class_bind_template_callback (widget_class, response_cb);
gtk_widget_class_install_action (widget_class, "response.activate", NULL, gtk_file_chooser_dialog_activate_response);
gtk_widget_class_bind_template_callback (widget_class, file_chooser_widget_file_activated);
gtk_widget_class_bind_template_callback (widget_class, file_chooser_widget_response_requested);
gtk_widget_class_bind_template_callback (widget_class, file_chooser_widget_selection_changed);
}
static void
@@ -361,12 +367,38 @@ is_accept_response_id (gint response_id)
response_id == GTK_RESPONSE_APPLY);
}
/* Callback used when the user activates a file in the file chooser widget */
static void
gtk_file_chooser_dialog_activate_response (GtkWidget *widget,
const char *action_name,
GVariant *parameters)
file_chooser_widget_file_activated (GtkFileChooser *chooser,
GtkFileChooserDialog *dialog)
{
gtk_widget_activate_default (GTK_WIDGET (chooser));
}
static void
file_chooser_widget_selection_changed (GtkWidget *widget,
GtkFileChooserDialog *dialog)
{
GtkFileChooserDialogPrivate *priv = gtk_file_chooser_dialog_get_instance_private (dialog);
GtkWidget *button;
GSList *files;
gboolean sensitive;
button = get_accept_action_widget (GTK_DIALOG (dialog), FALSE);
if (button == NULL)
return;
files = gtk_file_chooser_get_files (GTK_FILE_CHOOSER (priv->widget));
sensitive = (files != NULL);
gtk_widget_set_sensitive (button, sensitive);
g_slist_free_full (files, g_object_unref);
}
static void
file_chooser_widget_response_requested (GtkWidget *widget,
GtkFileChooserDialog *dialog)
{
GtkFileChooserDialog *dialog = GTK_FILE_CHOOSER_DIALOG (widget);
GtkFileChooserDialogPrivate *priv = gtk_file_chooser_dialog_get_instance_private (dialog);
GtkWidget *button;
@@ -609,7 +641,7 @@ gtk_file_chooser_dialog_map (GtkWidget *widget)
setup_save_entry (dialog);
ensure_default_response (dialog);
gtk_file_chooser_widget_initial_focus (GTK_FILE_CHOOSER_WIDGET (priv->widget));
_gtk_file_chooser_embed_initial_focus (GTK_FILE_CHOOSER_EMBED (priv->widget));
GTK_WIDGET_CLASS (gtk_file_chooser_dialog_parent_class)->map (widget);
}
@@ -673,7 +705,7 @@ response_cb (GtkDialog *dialog,
/* Act only on response IDs we recognize */
if (is_accept_response_id (response_id) &&
!priv->response_requested &&
!gtk_file_chooser_widget_should_respond (GTK_FILE_CHOOSER_WIDGET (priv->widget)))
!_gtk_file_chooser_embed_should_respond (GTK_FILE_CHOOSER_EMBED (priv->widget)))
{
g_signal_stop_emission_by_name (dialog, "response");
}
+152
View File
@@ -0,0 +1,152 @@
/* GTK - The GIMP Toolkit
* gtkfilechooserembed.h: Abstract sizing interface for file selector implementations
* Copyright (C) 2004, Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "gtkfilechooserembed.h"
#include "gtkmarshalers.h"
#include "gtkintl.h"
static void gtk_file_chooser_embed_class_init (gpointer g_iface);
static gboolean delegate_should_respond (GtkFileChooserEmbed *chooser_embed);
static void delegate_initial_focus (GtkFileChooserEmbed *chooser_embed);
static void delegate_response_requested (GtkFileChooserEmbed *chooser_embed,
gpointer data);
static GtkFileChooserEmbed *
get_delegate (GtkFileChooserEmbed *receiver)
{
return g_object_get_data (G_OBJECT (receiver), "gtk-file-chooser-embed-delegate");
}
/**
* _gtk_file_chooser_embed_delegate_iface_init:
* @iface: a #GtkFileChoserEmbedIface structure
*
* An interface-initialization function for use in cases where an object is
* simply delegating the methods, signals of the #GtkFileChooserEmbed interface
* to another object. _gtk_file_chooser_embed_set_delegate() must be called on
* each instance of the object so that the delegate object can be found.
**/
void
_gtk_file_chooser_embed_delegate_iface_init (GtkFileChooserEmbedIface *iface)
{
iface->should_respond = delegate_should_respond;
iface->initial_focus = delegate_initial_focus;
}
/**
* _gtk_file_chooser_embed_set_delegate:
* @receiver: a GOobject implementing #GtkFileChooserEmbed
* @delegate: another GObject implementing #GtkFileChooserEmbed
*
* Establishes that calls on @receiver for #GtkFileChooser methods should be
* delegated to @delegate, and that #GtkFileChooser signals emitted on @delegate
* should be forwarded to @receiver. Must be used in conjunction with
* _gtk_file_chooser_embed_delegate_iface_init().
**/
void
_gtk_file_chooser_embed_set_delegate (GtkFileChooserEmbed *receiver,
GtkFileChooserEmbed *delegate)
{
g_return_if_fail (GTK_IS_FILE_CHOOSER_EMBED (receiver));
g_return_if_fail (GTK_IS_FILE_CHOOSER_EMBED (delegate));
g_object_set_data (G_OBJECT (receiver), I_("gtk-file-chooser-embed-delegate"), delegate);
g_signal_connect (delegate, "response-requested",
G_CALLBACK (delegate_response_requested), receiver);
}
static gboolean
delegate_should_respond (GtkFileChooserEmbed *chooser_embed)
{
return _gtk_file_chooser_embed_should_respond (get_delegate (chooser_embed));
}
static void
delegate_initial_focus (GtkFileChooserEmbed *chooser_embed)
{
_gtk_file_chooser_embed_initial_focus (get_delegate (chooser_embed));
}
static void
delegate_response_requested (GtkFileChooserEmbed *chooser_embed,
gpointer data)
{
g_signal_emit_by_name (data, "response-requested");
}
/* publicly callable functions */
GType
_gtk_file_chooser_embed_get_type (void)
{
static GType file_chooser_embed_type = 0;
if (!file_chooser_embed_type)
{
const GTypeInfo file_chooser_embed_info =
{
sizeof (GtkFileChooserEmbedIface), /* class_size */
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc)gtk_file_chooser_embed_class_init, /* class_init */
};
file_chooser_embed_type = g_type_register_static (G_TYPE_INTERFACE,
I_("GtkFileChooserEmbed"),
&file_chooser_embed_info, 0);
g_type_interface_add_prerequisite (file_chooser_embed_type, GTK_TYPE_WIDGET);
}
return file_chooser_embed_type;
}
static void
gtk_file_chooser_embed_class_init (gpointer g_iface)
{
GType iface_type = G_TYPE_FROM_INTERFACE (g_iface);
g_signal_new (I_("response-requested"),
iface_type,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkFileChooserEmbedIface, response_requested),
NULL, NULL,
NULL,
G_TYPE_NONE, 0);
}
gboolean
_gtk_file_chooser_embed_should_respond (GtkFileChooserEmbed *chooser_embed)
{
g_return_val_if_fail (GTK_IS_FILE_CHOOSER_EMBED (chooser_embed), FALSE);
return GTK_FILE_CHOOSER_EMBED_GET_IFACE (chooser_embed)->should_respond (chooser_embed);
}
void
_gtk_file_chooser_embed_initial_focus (GtkFileChooserEmbed *chooser_embed)
{
g_return_if_fail (GTK_IS_FILE_CHOOSER_EMBED (chooser_embed));
GTK_FILE_CHOOSER_EMBED_GET_IFACE (chooser_embed)->initial_focus (chooser_embed);
}
+61
View File
@@ -0,0 +1,61 @@
/* GTK - The GIMP Toolkit
* gtkfilechooserembed.h: Abstract sizing interface for file selector implementations
* Copyright (C) 2004, Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GTK_FILE_CHOOSER_EMBED_H__
#define __GTK_FILE_CHOOSER_EMBED_H__
#include <gtk/gtkwidget.h>
G_BEGIN_DECLS
#define GTK_TYPE_FILE_CHOOSER_EMBED (_gtk_file_chooser_embed_get_type ())
#define GTK_FILE_CHOOSER_EMBED(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_FILE_CHOOSER_EMBED, GtkFileChooserEmbed))
#define GTK_IS_FILE_CHOOSER_EMBED(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_FILE_CHOOSER_EMBED))
#define GTK_FILE_CHOOSER_EMBED_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GTK_TYPE_FILE_CHOOSER_EMBED, GtkFileChooserEmbedIface))
typedef struct _GtkFileChooserEmbed GtkFileChooserEmbed;
typedef struct _GtkFileChooserEmbedIface GtkFileChooserEmbedIface;
struct _GtkFileChooserEmbedIface
{
GTypeInterface base_iface;
/* Methods
*/
gboolean (*should_respond) (GtkFileChooserEmbed *chooser_embed);
void (*initial_focus) (GtkFileChooserEmbed *chooser_embed);
/* Signals
*/
void (*response_requested) (GtkFileChooserEmbed *chooser_embed);
};
GType _gtk_file_chooser_embed_get_type (void) G_GNUC_CONST;
gboolean _gtk_file_chooser_embed_should_respond (GtkFileChooserEmbed *chooser_embed);
void _gtk_file_chooser_embed_initial_focus (GtkFileChooserEmbed *chooser_embed);
void _gtk_file_chooser_embed_delegate_iface_init (GtkFileChooserEmbedIface *iface);
void _gtk_file_chooser_embed_set_delegate (GtkFileChooserEmbed *receiver,
GtkFileChooserEmbed *delegate);
G_END_DECLS
#endif /* __GTK_FILE_CHOOSER_EMBED_H__ */
+51 -9
View File
@@ -25,7 +25,7 @@
#include "gtkcelllayout.h"
#include "gtkcellrenderertext.h"
#include "gtkentryprivate.h"
#include "gtkfilechooserutils.h"
#include "gtkfilesystemmodel.h"
#include "gtklabel.h"
#include "gtkmain.h"
#include "gtksizerequest.h"
@@ -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;
+1
View File
@@ -19,6 +19,7 @@
#ifndef __GTK_FILE_CHOOSER_ENTRY_H__
#define __GTK_FILE_CHOOSER_ENTRY_H__
#include "gtkfilesystem.h"
#include "gtkfilechooser.h"
G_BEGIN_DECLS
+1 -1
View File
@@ -148,7 +148,7 @@ void
gtk_file_chooser_error_stack_set_custom_error (GtkFileChooserErrorStack *self,
const char *label_text)
{
GtkWidget *label = gtk_stack_get_child_by_name (GTK_STACK (self->stack), "custom");
GtkWidget *label = gtk_stack_get_child_by_name (GTK_STACK (self->stack), "cutsom");
gtk_label_set_text (GTK_LABEL (label), label_text);
+26 -15
View File
@@ -28,6 +28,8 @@
#include "gtkfilechooserwidget.h"
#include "gtkfilechooserwidgetprivate.h"
#include "gtkfilechooserutils.h"
#include "gtkfilechooserembed.h"
#include "gtkfilesystem.h"
#include "gtksizerequest.h"
#include "gtktypebuiltins.h"
#include "gtkintl.h"
@@ -156,8 +158,21 @@
* possible to use with #GtkFileChooserNative, as such use would
* prohibit the use of a native dialog.
*
* No operations that change the dialog work while the dialog is visible.
* Set all the properties that are required before showing the dialog.
* There is no support for the signals that are emitted when the user
* navigates in the dialog, including:
* * #GtkFileChooser::current-folder-changed
* * #GtkFileChooser::selection-changed
* * #GtkFileChooser::file-activated
*
* You can also not use the methods that directly control user navigation:
* * gtk_file_chooser_unselect_filename()
* * gtk_file_chooser_select_all()
* * gtk_file_chooser_unselect_all()
*
* If you need any of the above you will have to use #GtkFileChooserDialog directly.
*
* No operations that change the dialog work while the dialog is visible. Set
* all the properties that are required before showing the dialog.
*
* ## Win32 details ## {#gtkfilechooserdialognative-win32}
*
@@ -165,7 +180,7 @@
* used. It supports many of the features that #GtkFileChooserDialog
* does, but there are some things it does not handle:
*
* * Any #GtkFileFilter added using a mimetype
* * Any #GtkFileFilter added using a mimetype or custom filter.
*
* If any of these features are used the regular #GtkFileChooserDialog
* will be used in place of the native one.
@@ -175,7 +190,10 @@
* When the org.freedesktop.portal.FileChooser portal is available on the
* session bus, it is used to bring up an out-of-process file chooser. Depending
* on the kind of session the application is running in, this may or may not
* be a GTK file chooser.
* be a GTK+ file chooser. In this situation, the following things are not
* supported and will be silently ignored:
*
* * Any #GtkFileFilter added with a custom filter.
*
* ## macOS details ## {#gtkfilechooserdialognative-macos}
*
@@ -183,6 +201,8 @@
* file chooser dialogs. Some features provided by #GtkFileChooserDialog are
* not supported:
*
* * Any #GtkFileFilter added with a custom filter.
*
* * Shortcut folders.
*/
@@ -663,7 +683,7 @@ gtk_file_chooser_native_set_current_name (GtkFileChooser *chooser,
g_clear_object (&self->current_file);
}
static GListModel *
static GSList *
gtk_file_chooser_native_get_files (GtkFileChooser *chooser)
{
GtkFileChooserNative *self = GTK_FILE_CHOOSER_NATIVE (chooser);
@@ -673,16 +693,7 @@ gtk_file_chooser_native_get_files (GtkFileChooser *chooser)
case MODE_PORTAL:
case MODE_WIN32:
case MODE_QUARTZ:
{
GListStore *store;
GSList *l;
store = g_list_store_new (G_TYPE_FILE);
for (l = self->custom_files; l; l = l->next)
g_list_store_append (store, l->data);
return G_LIST_MODEL (store);
}
return g_slist_copy_deep (self->custom_files, (GCopyFunc)g_object_ref, NULL);
case MODE_FALLBACK:
default:
+12 -19
View File
@@ -28,6 +28,8 @@
#include "gtkfilechooserwidget.h"
#include "gtkfilechooserwidgetprivate.h"
#include "gtkfilechooserutils.h"
#include "gtkfilechooserembed.h"
#include "gtkfilesystem.h"
#include "gtksizerequest.h"
#include "gtktypebuiltins.h"
#include "gtkintl.h"
@@ -124,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
@@ -135,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);
@@ -268,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);
}
+16 -36
View File
@@ -28,6 +28,8 @@
#include "gtkfilechooserwidget.h"
#include "gtkfilechooserwidgetprivate.h"
#include "gtkfilechooserutils.h"
#include "gtkfilechooserembed.h"
#include "gtkfilesystem.h"
#include "gtksizerequest.h"
#include "gtktypebuiltins.h"
#include "gtkintl.h"
@@ -97,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
@@ -306,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
@@ -451,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];
@@ -467,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));
}
@@ -485,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);
+20 -46
View File
@@ -34,6 +34,8 @@
#include "gtkfilechooserwidget.h"
#include "gtkfilechooserwidgetprivate.h"
#include "gtkfilechooserutils.h"
#include "gtkfilechooserembed.h"
#include "gtkfilesystem.h"
#include "gtksizerequest.h"
#include "gtktypebuiltins.h"
#include "gtkintl.h"
@@ -64,7 +66,7 @@ typedef struct {
char *cancel_label;
char *title;
GListModel *shortcut_files;
GSList *shortcut_files;
GArray *choices_selections;
GFile *current_folder;
@@ -242,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;
}
@@ -328,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);
@@ -463,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);
@@ -529,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);
@@ -541,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)
@@ -594,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);
@@ -634,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;
@@ -761,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;
@@ -885,28 +864,24 @@ 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;
}
g_object_unref (filter);
}
self->current_filter = gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (self));
}
@@ -914,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);
+28 -31
View File
@@ -20,6 +20,7 @@
#define __GTK_FILE_CHOOSER_PRIVATE_H__
#include "gtkfilechooser.h"
#include "gtkfilesystem.h"
#include "gtkfilesystemmodel.h"
#include "gtkliststore.h"
#include "gtkrecentmanager.h"
@@ -57,33 +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);
GListModel * (*get_files) (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
*/
@@ -107,13 +109,8 @@ struct _GtkFileChooserIface
const char *id);
};
void gtk_file_chooser_select_all (GtkFileChooser *chooser);
void gtk_file_chooser_unselect_all (GtkFileChooser *chooser);
gboolean gtk_file_chooser_select_file (GtkFileChooser *chooser,
GFile *file,
GError **error);
void gtk_file_chooser_unselect_file (GtkFileChooser *chooser,
GFile *file);
GtkFileSystem *_gtk_file_chooser_get_file_system (GtkFileChooser *chooser);
G_END_DECLS
#endif /* __GTK_FILE_CHOOSER_PRIVATE_H__ */
+62 -99
View File
@@ -20,6 +20,7 @@
#include "config.h"
#include "gtkfilechooserutils.h"
#include "gtkfilechooser.h"
#include "gtkfilesystem.h"
#include "gtktypebuiltins.h"
#include "gtkintl.h"
@@ -38,22 +39,29 @@ static void delegate_unselect_file (GtkFileChooser *choose
GFile *file);
static void delegate_select_all (GtkFileChooser *chooser);
static void delegate_unselect_all (GtkFileChooser *chooser);
static GListModel * delegate_get_files (GtkFileChooser *chooser);
static GSList * delegate_get_files (GtkFileChooser *chooser);
static GtkFileSystem *delegate_get_file_system (GtkFileChooser *chooser);
static void delegate_add_filter (GtkFileChooser *chooser,
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);
static void delegate_current_folder_changed (GtkFileChooser *chooser,
gpointer data);
static void delegate_selection_changed (GtkFileChooser *chooser,
gpointer data);
static void delegate_file_activated (GtkFileChooser *chooser,
gpointer data);
static void delegate_add_choice (GtkFileChooser *chooser,
const char *id,
@@ -84,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");
}
/**
@@ -126,12 +128,13 @@ _gtk_file_chooser_delegate_iface_init (GtkFileChooserIface *iface)
iface->select_all = delegate_select_all;
iface->unselect_all = delegate_unselect_all;
iface->get_files = delegate_get_files;
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;
@@ -159,6 +162,12 @@ _gtk_file_chooser_set_delegate (GtkFileChooser *receiver,
g_object_set_data (G_OBJECT (receiver), I_("gtk-file-chooser-delegate"), delegate);
g_signal_connect (delegate, "notify",
G_CALLBACK (delegate_notify), receiver);
g_signal_connect (delegate, "current-folder-changed",
G_CALLBACK (delegate_current_folder_changed), receiver);
g_signal_connect (delegate, "selection-changed",
G_CALLBACK (delegate_selection_changed), receiver);
g_signal_connect (delegate, "file-activated",
G_CALLBACK (delegate_file_activated), receiver);
}
GQuark
@@ -206,12 +215,18 @@ delegate_unselect_all (GtkFileChooser *chooser)
gtk_file_chooser_unselect_all (get_delegate (chooser));
}
static GListModel *
static GSList *
delegate_get_files (GtkFileChooser *chooser)
{
return gtk_file_chooser_get_files (get_delegate (chooser));
}
static GtkFileSystem *
delegate_get_file_system (GtkFileChooser *chooser)
{
return _gtk_file_chooser_get_file_system (get_delegate (chooser));
}
static void
delegate_add_filter (GtkFileChooser *chooser,
GtkFileFilter *filter)
@@ -226,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
@@ -248,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
@@ -294,6 +309,27 @@ delegate_notify (GObject *object,
g_object_notify (data, pspec->name);
}
static void
delegate_selection_changed (GtkFileChooser *chooser,
gpointer data)
{
g_signal_emit_by_name (data, "selection-changed");
}
static void
delegate_current_folder_changed (GtkFileChooser *chooser,
gpointer data)
{
g_signal_emit_by_name (data, "current-folder-changed");
}
static void
delegate_file_activated (GtkFileChooser *chooser,
gpointer data)
{
g_signal_emit_by_name (data, "file-activated");
}
GSettings *
_gtk_file_chooser_get_settings_for_widget (GtkWidget *widget)
{
@@ -402,76 +438,3 @@ delegate_get_choice (GtkFileChooser *chooser,
{
return gtk_file_chooser_get_choice (get_delegate (chooser), id);
}
gboolean
_gtk_file_info_consider_as_directory (GFileInfo *info)
{
GFileType type = g_file_info_get_file_type (info);
return (type == G_FILE_TYPE_DIRECTORY ||
type == G_FILE_TYPE_MOUNTABLE ||
type == G_FILE_TYPE_SHORTCUT);
}
gboolean
_gtk_file_has_native_path (GFile *file)
{
char *local_file_path;
gboolean has_native_path;
/* Don't use g_file_is_native(), as we want to support FUSE paths if available */
local_file_path = g_file_get_path (file);
has_native_path = (local_file_path != NULL);
g_free (local_file_path);
return has_native_path;
}
gboolean
_gtk_file_consider_as_remote (GFile *file)
{
GFileInfo *info;
gboolean is_remote;
info = g_file_query_filesystem_info (file, G_FILE_ATTRIBUTE_FILESYSTEM_REMOTE, NULL, NULL);
if (info)
{
is_remote = g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_FILESYSTEM_REMOTE);
g_object_unref (info);
}
else
is_remote = FALSE;
return is_remote;
}
GIcon *
_gtk_file_info_get_icon (GFileInfo *info,
int icon_size,
int scale)
{
GIcon *icon;
GdkPixbuf *pixbuf;
const gchar *thumbnail_path;
thumbnail_path = g_file_info_get_attribute_byte_string (info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH);
if (thumbnail_path)
{
pixbuf = gdk_pixbuf_new_from_file_at_size (thumbnail_path,
icon_size*scale, icon_size*scale,
NULL);
if (pixbuf != NULL)
return G_ICON (pixbuf);
}
icon = g_file_info_get_icon (info);
if (icon)
return g_object_ref (icon);
/* Use general fallback for all files without icon */
icon = g_themed_icon_new ("text-x-generic");
return icon;
}
+1 -10
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);
@@ -49,13 +47,6 @@ GSettings *_gtk_file_chooser_get_settings_for_widget (GtkWidget *widget);
gchar * _gtk_file_chooser_label_for_file (GFile *file);
gboolean _gtk_file_info_consider_as_directory (GFileInfo *info);
gboolean _gtk_file_has_native_path (GFile *file);
gboolean _gtk_file_consider_as_remote (GFile *file);
GIcon * _gtk_file_info_get_icon (GFileInfo *info,
int icon_size,
int scale);
G_END_DECLS
#endif /* __GTK_FILE_CHOOSER_UTILS_H__ */
+357 -299
View File
File diff suppressed because it is too large Load Diff
-6
View File
@@ -30,12 +30,6 @@ void
gtk_file_chooser_widget_set_save_entry (GtkFileChooserWidget *chooser,
GtkWidget *entry);
gboolean
gtk_file_chooser_widget_should_respond (GtkFileChooserWidget *chooser);
void
gtk_file_chooser_widget_initial_focus (GtkFileChooserWidget *chooser);
G_END_DECLS
#endif /* __GTK_FILE_CHOOSER_WIDGET_PRIVATE_H__ */
+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
+823
View File
@@ -0,0 +1,823 @@
/* GTK - The GIMP Toolkit
* gtkfilesystem.c: Filesystem abstraction functions.
* Copyright (C) 2003, Red Hat, Inc.
* Copyright (C) 2007-2008 Carlos Garnacho
*
* 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/>.
*
* Authors: Carlos Garnacho <carlos@imendio.com>
*/
#include "config.h"
#include "gtkfilesystem.h"
#include <string.h>
#include <glib/gi18n-lib.h>
#include "gtkfilechooser.h"
#include "gtkintl.h"
#include "gtkprivate.h"
#include "gtkstylecontextprivate.h"
/* #define DEBUG_MODE */
#ifdef DEBUG_MODE
#define DEBUG(x) g_debug (x);
#else
#define DEBUG(x)
#endif
#define FILES_PER_QUERY 100
/* The pointers we return for a GtkFileSystemVolume are opaque tokens; they are
* really pointers to GDrive, GVolume or GMount objects. We need an extra
* token for the fake File System volume. So, well return a pointer to
* this particular string.
*/
static const gchar *root_volume_token = N_("File System");
#define IS_ROOT_VOLUME(volume) ((gpointer) (volume) == (gpointer) root_volume_token)
enum {
PROP_0,
PROP_FILE,
PROP_ENUMERATOR,
PROP_ATTRIBUTES
};
enum {
VOLUMES_CHANGED,
FS_LAST_SIGNAL
};
enum {
FILES_ADDED,
FILES_REMOVED,
FILES_CHANGED,
FINISHED_LOADING,
DELETED,
FOLDER_LAST_SIGNAL
};
static guint fs_signals [FS_LAST_SIGNAL] = { 0, };
typedef struct AsyncFuncData AsyncFuncData;
struct GtkFileSystemPrivate
{
GVolumeMonitor *volume_monitor;
/* This list contains elements that can be
* of type GDrive, GVolume and GMount
*/
GSList *volumes;
};
struct AsyncFuncData
{
GtkFileSystem *file_system;
GFile *file;
GCancellable *cancellable;
gpointer callback;
gpointer data;
};
G_DEFINE_TYPE_WITH_PRIVATE (GtkFileSystem, _gtk_file_system, G_TYPE_OBJECT)
/* GtkFileSystem methods */
static void
volumes_changed (GVolumeMonitor *volume_monitor,
gpointer volume,
gpointer user_data)
{
GtkFileSystem *file_system = user_data;
g_signal_emit (file_system, fs_signals[VOLUMES_CHANGED], 0, volume);
}
static void
gtk_file_system_dispose (GObject *object)
{
GtkFileSystem *file_system = GTK_FILE_SYSTEM (object);
GtkFileSystemPrivate *priv = file_system->priv;
DEBUG ("dispose");
if (priv->volumes)
{
g_slist_free_full (priv->volumes, g_object_unref);
priv->volumes = NULL;
}
if (priv->volume_monitor)
{
g_signal_handlers_disconnect_by_func (priv->volume_monitor, volumes_changed, object);
g_object_unref (priv->volume_monitor);
priv->volume_monitor = NULL;
}
G_OBJECT_CLASS (_gtk_file_system_parent_class)->dispose (object);
}
static void
_gtk_file_system_class_init (GtkFileSystemClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->dispose = gtk_file_system_dispose;
fs_signals[VOLUMES_CHANGED] =
g_signal_new (I_("volumes-changed"),
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkFileSystemClass, volumes_changed),
NULL, NULL,
NULL,
G_TYPE_NONE, 0);
}
static gboolean
mount_referenced_by_volume_activation_root (GList *volumes, GMount *mount)
{
GList *l;
GFile *mount_root;
gboolean ret;
ret = FALSE;
mount_root = g_mount_get_root (mount);
for (l = volumes; l != NULL; l = l->next)
{
GVolume *volume = G_VOLUME (l->data);
GFile *volume_activation_root;
volume_activation_root = g_volume_get_activation_root (volume);
if (volume_activation_root != NULL)
{
if (g_file_has_prefix (volume_activation_root, mount_root))
{
ret = TRUE;
g_object_unref (volume_activation_root);
break;
}
g_object_unref (volume_activation_root);
}
}
g_object_unref (mount_root);
return ret;
}
static void
get_volumes_list (GtkFileSystem *file_system)
{
GtkFileSystemPrivate *priv = file_system->priv;
GList *l, *ll;
GList *drives;
GList *volumes;
GList *mounts;
GDrive *drive;
GVolume *volume;
GMount *mount;
if (priv->volumes)
{
g_slist_free_full (priv->volumes, g_object_unref);
priv->volumes = NULL;
}
/* first go through all connected drives */
drives = g_volume_monitor_get_connected_drives (priv->volume_monitor);
for (l = drives; l != NULL; l = l->next)
{
drive = l->data;
volumes = g_drive_get_volumes (drive);
if (volumes)
{
for (ll = volumes; ll != NULL; ll = ll->next)
{
volume = ll->data;
mount = g_volume_get_mount (volume);
if (mount)
{
/* Show mounted volume */
priv->volumes = g_slist_prepend (priv->volumes, g_object_ref (mount));
g_object_unref (mount);
}
else
{
/* Do show the unmounted volumes in the sidebar;
* this is so the user can mount it (in case automounting
* is off).
*
* Also, even if automounting is enabled, this gives a visual
* cue that the user should remember to yank out the media if
* he just unmounted it.
*/
priv->volumes = g_slist_prepend (priv->volumes, g_object_ref (volume));
}
g_object_unref (volume);
}
g_list_free (volumes);
}
else if (g_drive_is_media_removable (drive) && !g_drive_is_media_check_automatic (drive))
{
/* If the drive has no mountable volumes and we cannot detect media change.. we
* display the drive in the sidebar so the user can manually poll the drive by
* right clicking and selecting "Rescan..."
*
* This is mainly for drives like floppies where media detection doesn't
* work.. but it's also for human beings who like to turn off media detection
* in the OS to save battery juice.
*/
priv->volumes = g_slist_prepend (priv->volumes, g_object_ref (drive));
}
g_object_unref (drive);
}
g_list_free (drives);
/* add all volumes that is not associated with a drive */
volumes = g_volume_monitor_get_volumes (priv->volume_monitor);
for (l = volumes; l != NULL; l = l->next)
{
volume = l->data;
drive = g_volume_get_drive (volume);
if (drive)
{
g_object_unref (drive);
continue;
}
mount = g_volume_get_mount (volume);
if (mount)
{
/* show this mount */
priv->volumes = g_slist_prepend (priv->volumes, g_object_ref (mount));
g_object_unref (mount);
}
else
{
/* see comment above in why we add an icon for a volume */
priv->volumes = g_slist_prepend (priv->volumes, g_object_ref (volume));
}
g_object_unref (volume);
}
/* add mounts that has no volume (/etc/mtab mounts, ftp, sftp,...) */
mounts = g_volume_monitor_get_mounts (priv->volume_monitor);
for (l = mounts; l != NULL; l = l->next)
{
mount = l->data;
volume = g_mount_get_volume (mount);
if (volume)
{
g_object_unref (volume);
continue;
}
/* if there's exists one or more volumes with an activation root inside the mount,
* don't display the mount
*/
if (mount_referenced_by_volume_activation_root (volumes, mount))
{
g_object_unref (mount);
continue;
}
/* show this mount */
priv->volumes = g_slist_prepend (priv->volumes, g_object_ref (mount));
g_object_unref (mount);
}
g_list_free (volumes);
g_list_free (mounts);
}
static void
_gtk_file_system_init (GtkFileSystem *file_system)
{
GtkFileSystemPrivate *priv;
DEBUG ("init");
file_system->priv = priv = _gtk_file_system_get_instance_private (file_system);
/* Volumes */
priv->volume_monitor = g_volume_monitor_get ();
g_signal_connect (priv->volume_monitor, "mount-added",
G_CALLBACK (volumes_changed), file_system);
g_signal_connect (priv->volume_monitor, "mount-removed",
G_CALLBACK (volumes_changed), file_system);
g_signal_connect (priv->volume_monitor, "mount-changed",
G_CALLBACK (volumes_changed), file_system);
g_signal_connect (priv->volume_monitor, "volume-added",
G_CALLBACK (volumes_changed), file_system);
g_signal_connect (priv->volume_monitor, "volume-removed",
G_CALLBACK (volumes_changed), file_system);
g_signal_connect (priv->volume_monitor, "volume-changed",
G_CALLBACK (volumes_changed), file_system);
g_signal_connect (priv->volume_monitor, "drive-connected",
G_CALLBACK (volumes_changed), file_system);
g_signal_connect (priv->volume_monitor, "drive-disconnected",
G_CALLBACK (volumes_changed), file_system);
g_signal_connect (priv->volume_monitor, "drive-changed",
G_CALLBACK (volumes_changed), file_system);
}
/* GtkFileSystem public methods */
GtkFileSystem *
_gtk_file_system_new (void)
{
return g_object_new (GTK_TYPE_FILE_SYSTEM, NULL);
}
GSList *
_gtk_file_system_list_volumes (GtkFileSystem *file_system)
{
GtkFileSystemPrivate *priv = file_system->priv;
GSList *list;
DEBUG ("list_volumes");
get_volumes_list (file_system);
list = g_slist_copy (priv->volumes);
#ifndef G_OS_WIN32
/* Prepend root volume */
list = g_slist_prepend (list, (gpointer) root_volume_token);
#endif
return list;
}
static void
free_async_data (AsyncFuncData *async_data)
{
g_object_unref (async_data->file_system);
g_object_unref (async_data->file);
g_object_unref (async_data->cancellable);
g_free (async_data);
}
static void
query_info_callback (GObject *source_object,
GAsyncResult *result,
gpointer user_data)
{
AsyncFuncData *async_data;
GError *error = NULL;
GFileInfo *file_info;
GFile *file;
DEBUG ("query_info_callback");
file = G_FILE (source_object);
async_data = (AsyncFuncData *) user_data;
file_info = g_file_query_info_finish (file, result, &error);
if (async_data->callback)
{
((GtkFileSystemGetInfoCallback) async_data->callback) (async_data->cancellable,
file_info, error, async_data->data);
}
if (file_info)
g_object_unref (file_info);
if (error)
g_error_free (error);
free_async_data (async_data);
}
GCancellable *
_gtk_file_system_get_info (GtkFileSystem *file_system,
GFile *file,
const gchar *attributes,
GtkFileSystemGetInfoCallback callback,
gpointer data)
{
GCancellable *cancellable;
AsyncFuncData *async_data;
g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
g_return_val_if_fail (G_IS_FILE (file), NULL);
cancellable = g_cancellable_new ();
async_data = g_new0 (AsyncFuncData, 1);
async_data->file_system = g_object_ref (file_system);
async_data->file = g_object_ref (file);
async_data->cancellable = g_object_ref (cancellable);
async_data->callback = callback;
async_data->data = data;
g_file_query_info_async (file,
attributes,
G_FILE_QUERY_INFO_NONE,
G_PRIORITY_DEFAULT,
cancellable,
query_info_callback,
async_data);
return cancellable;
}
static void
drive_poll_for_media_cb (GObject *source_object,
GAsyncResult *result,
gpointer user_data)
{
AsyncFuncData *async_data;
GError *error = NULL;
g_drive_poll_for_media_finish (G_DRIVE (source_object), result, &error);
async_data = (AsyncFuncData *) user_data;
((GtkFileSystemVolumeMountCallback) async_data->callback) (async_data->cancellable,
(GtkFileSystemVolume *) source_object,
error, async_data->data);
if (error)
g_error_free (error);
}
static void
volume_mount_cb (GObject *source_object,
GAsyncResult *result,
gpointer user_data)
{
AsyncFuncData *async_data;
GError *error = NULL;
g_volume_mount_finish (G_VOLUME (source_object), result, &error);
async_data = (AsyncFuncData *) user_data;
((GtkFileSystemVolumeMountCallback) async_data->callback) (async_data->cancellable,
(GtkFileSystemVolume *) source_object,
error, async_data->data);
if (error)
g_error_free (error);
}
GCancellable *
_gtk_file_system_mount_volume (GtkFileSystem *file_system,
GtkFileSystemVolume *volume,
GMountOperation *mount_operation,
GtkFileSystemVolumeMountCallback callback,
gpointer data)
{
GCancellable *cancellable;
AsyncFuncData *async_data;
gboolean handled = FALSE;
DEBUG ("volume_mount");
cancellable = g_cancellable_new ();
async_data = g_new0 (AsyncFuncData, 1);
async_data->file_system = g_object_ref (file_system);
async_data->cancellable = g_object_ref (cancellable);
async_data->callback = callback;
async_data->data = data;
if (G_IS_DRIVE (volume))
{
/* this path happens for drives that are not polled by the OS and where the last media
* check indicated that no media was available. So the thing to do here is to
* invoke poll_for_media() on the drive
*/
g_drive_poll_for_media (G_DRIVE (volume), cancellable, drive_poll_for_media_cb, async_data);
handled = TRUE;
}
else if (G_IS_VOLUME (volume))
{
g_volume_mount (G_VOLUME (volume), G_MOUNT_MOUNT_NONE, mount_operation, cancellable, volume_mount_cb, async_data);
handled = TRUE;
}
if (!handled)
free_async_data (async_data);
return cancellable;
}
static void
enclosing_volume_mount_cb (GObject *source_object,
GAsyncResult *result,
gpointer user_data)
{
GtkFileSystemVolume *volume;
AsyncFuncData *async_data;
GError *error = NULL;
async_data = (AsyncFuncData *) user_data;
g_file_mount_enclosing_volume_finish (G_FILE (source_object), result, &error);
volume = _gtk_file_system_get_volume_for_file (async_data->file_system, G_FILE (source_object));
/* Silently drop G_IO_ERROR_ALREADY_MOUNTED error for gvfs backends without visible mounts. */
/* Better than doing query_info with additional I/O every time. */
if (error && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_ALREADY_MOUNTED))
g_clear_error (&error);
((GtkFileSystemVolumeMountCallback) async_data->callback) (async_data->cancellable, volume,
error, async_data->data);
if (error)
g_error_free (error);
_gtk_file_system_volume_unref (volume);
}
GCancellable *
_gtk_file_system_mount_enclosing_volume (GtkFileSystem *file_system,
GFile *file,
GMountOperation *mount_operation,
GtkFileSystemVolumeMountCallback callback,
gpointer data)
{
GCancellable *cancellable;
AsyncFuncData *async_data;
g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
g_return_val_if_fail (G_IS_FILE (file), NULL);
DEBUG ("mount_enclosing_volume");
cancellable = g_cancellable_new ();
async_data = g_new0 (AsyncFuncData, 1);
async_data->file_system = g_object_ref (file_system);
async_data->file = g_object_ref (file);
async_data->cancellable = g_object_ref (cancellable);
async_data->callback = callback;
async_data->data = data;
g_file_mount_enclosing_volume (file,
G_MOUNT_MOUNT_NONE,
mount_operation,
cancellable,
enclosing_volume_mount_cb,
async_data);
return cancellable;
}
GtkFileSystemVolume *
_gtk_file_system_get_volume_for_file (GtkFileSystem *file_system,
GFile *file)
{
GMount *mount;
DEBUG ("get_volume_for_file");
mount = g_file_find_enclosing_mount (file, NULL, NULL);
if (!mount && g_file_is_native (file))
return (GtkFileSystemVolume *) root_volume_token;
return (GtkFileSystemVolume *) mount;
}
/* GtkFileSystemVolume public methods */
gchar *
_gtk_file_system_volume_get_display_name (GtkFileSystemVolume *volume)
{
DEBUG ("volume_get_display_name");
if (IS_ROOT_VOLUME (volume))
return g_strdup (_(root_volume_token));
if (G_IS_DRIVE (volume))
return g_drive_get_name (G_DRIVE (volume));
else if (G_IS_MOUNT (volume))
return g_mount_get_name (G_MOUNT (volume));
else if (G_IS_VOLUME (volume))
return g_volume_get_name (G_VOLUME (volume));
return NULL;
}
gboolean
_gtk_file_system_volume_is_mounted (GtkFileSystemVolume *volume)
{
gboolean mounted;
DEBUG ("volume_is_mounted");
if (IS_ROOT_VOLUME (volume))
return TRUE;
mounted = FALSE;
if (G_IS_MOUNT (volume))
mounted = TRUE;
else if (G_IS_VOLUME (volume))
{
GMount *mount;
mount = g_volume_get_mount (G_VOLUME (volume));
if (mount)
{
mounted = TRUE;
g_object_unref (mount);
}
}
return mounted;
}
GFile *
_gtk_file_system_volume_get_root (GtkFileSystemVolume *volume)
{
GFile *file = NULL;
DEBUG ("volume_get_base");
if (IS_ROOT_VOLUME (volume))
return g_file_new_for_uri ("file:///");
if (G_IS_MOUNT (volume))
file = g_mount_get_root (G_MOUNT (volume));
else if (G_IS_VOLUME (volume))
{
GMount *mount;
mount = g_volume_get_mount (G_VOLUME (volume));
if (mount)
{
file = g_mount_get_root (mount);
g_object_unref (mount);
}
}
return file;
}
GIcon *
_gtk_file_system_volume_get_icon (GtkFileSystemVolume *volume)
{
GIcon *icon = NULL;
if (IS_ROOT_VOLUME (volume))
icon = g_themed_icon_new ("drive-harddisk");
else if (G_IS_DRIVE (volume))
icon = g_drive_get_icon (G_DRIVE (volume));
else if (G_IS_VOLUME (volume))
icon = g_volume_get_icon (G_VOLUME (volume));
else if (G_IS_MOUNT (volume))
icon = g_mount_get_icon (G_MOUNT (volume));
return icon;
}
GIcon *
_gtk_file_system_volume_get_symbolic_icon (GtkFileSystemVolume *volume)
{
if (IS_ROOT_VOLUME (volume))
return g_themed_icon_new ("drive-harddisk-symbolic");
else if (G_IS_DRIVE (volume))
return g_drive_get_symbolic_icon (G_DRIVE (volume));
else if (G_IS_VOLUME (volume))
return g_volume_get_symbolic_icon (G_VOLUME (volume));
else if (G_IS_MOUNT (volume))
return g_mount_get_symbolic_icon (G_MOUNT (volume));
else
return NULL;
}
GtkFileSystemVolume *
_gtk_file_system_volume_ref (GtkFileSystemVolume *volume)
{
if (IS_ROOT_VOLUME (volume))
return volume;
if (G_IS_MOUNT (volume) ||
G_IS_VOLUME (volume) ||
G_IS_DRIVE (volume))
g_object_ref (volume);
return volume;
}
void
_gtk_file_system_volume_unref (GtkFileSystemVolume *volume)
{
/* Root volume doesn't need to be freed */
if (IS_ROOT_VOLUME (volume))
return;
if (G_IS_MOUNT (volume) ||
G_IS_VOLUME (volume) ||
G_IS_DRIVE (volume))
g_object_unref (volume);
}
/* GFileInfo helper functions */
GIcon *
_gtk_file_info_get_icon (GFileInfo *info,
int icon_size,
int scale)
{
GIcon *icon;
GdkPixbuf *pixbuf;
const gchar *thumbnail_path;
thumbnail_path = g_file_info_get_attribute_byte_string (info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH);
if (thumbnail_path)
{
pixbuf = gdk_pixbuf_new_from_file_at_size (thumbnail_path,
icon_size*scale, icon_size*scale,
NULL);
if (pixbuf != NULL)
return G_ICON (pixbuf);
}
icon = g_file_info_get_icon (info);
if (icon)
return g_object_ref (icon);
/* Use general fallback for all files without icon */
icon = g_themed_icon_new ("text-x-generic");
return icon;
}
gboolean
_gtk_file_info_consider_as_directory (GFileInfo *info)
{
GFileType type = g_file_info_get_file_type (info);
return (type == G_FILE_TYPE_DIRECTORY ||
type == G_FILE_TYPE_MOUNTABLE ||
type == G_FILE_TYPE_SHORTCUT);
}
gboolean
_gtk_file_has_native_path (GFile *file)
{
char *local_file_path;
gboolean has_native_path;
/* Don't use g_file_is_native(), as we want to support FUSE paths if available */
local_file_path = g_file_get_path (file);
has_native_path = (local_file_path != NULL);
g_free (local_file_path);
return has_native_path;
}
gboolean
_gtk_file_consider_as_remote (GFile *file)
{
GFileInfo *info;
gboolean is_remote;
info = g_file_query_filesystem_info (file, G_FILE_ATTRIBUTE_FILESYSTEM_REMOTE, NULL, NULL);
if (info)
{
is_remote = g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_FILESYSTEM_REMOTE);
g_object_unref (info);
}
else
is_remote = FALSE;
return is_remote;
}
+116
View File
@@ -0,0 +1,116 @@
/* GTK - The GIMP Toolkit
* gtkfilesystem.h: Filesystem abstraction functions.
* Copyright (C) 2003, Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GTK_FILE_SYSTEM_H__
#define __GTK_FILE_SYSTEM_H__
#include <gio/gio.h>
#include <gtk/gtkwidget.h> /* For icon handling */
G_BEGIN_DECLS
#define GTK_TYPE_FILE_SYSTEM (_gtk_file_system_get_type ())
#define GTK_FILE_SYSTEM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GTK_TYPE_FILE_SYSTEM, GtkFileSystem))
#define GTK_FILE_SYSTEM_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GTK_TYPE_FILE_SYSTEM, GtkFileSystemClass))
#define GTK_IS_FILE_SYSTEM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GTK_TYPE_FILE_SYSTEM))
#define GTK_IS_FILE_SYSTEM_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GTK_TYPE_FILE_SYSTEM))
#define GTK_FILE_SYSTEM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GTK_TYPE_FILE_SYSTEM, GtkFileSystemClass))
typedef struct GtkFileSystem GtkFileSystem;
typedef struct GtkFileSystemPrivate GtkFileSystemPrivate;
typedef struct GtkFileSystemClass GtkFileSystemClass;
typedef struct GtkFileSystemVolume GtkFileSystemVolume; /* opaque struct */
struct GtkFileSystem
{
GObject parent_object;
GtkFileSystemPrivate *priv;
};
struct GtkFileSystemClass
{
GObjectClass parent_class;
void (*volumes_changed) (GtkFileSystem *file_system);
};
typedef void (* GtkFileSystemGetInfoCallback) (GCancellable *cancellable,
GFileInfo *file_info,
const GError *error,
gpointer data);
typedef void (* GtkFileSystemVolumeMountCallback) (GCancellable *cancellable,
GtkFileSystemVolume *volume,
const GError *error,
gpointer data);
/* GtkFileSystem methods */
GType _gtk_file_system_get_type (void) G_GNUC_CONST;
GtkFileSystem * _gtk_file_system_new (void);
GSList * _gtk_file_system_list_volumes (GtkFileSystem *file_system);
GCancellable * _gtk_file_system_get_info (GtkFileSystem *file_system,
GFile *file,
const gchar *attributes,
GtkFileSystemGetInfoCallback callback,
gpointer data);
GCancellable * _gtk_file_system_mount_volume (GtkFileSystem *file_system,
GtkFileSystemVolume *volume,
GMountOperation *mount_operation,
GtkFileSystemVolumeMountCallback callback,
gpointer data);
GCancellable * _gtk_file_system_mount_enclosing_volume (GtkFileSystem *file_system,
GFile *file,
GMountOperation *mount_operation,
GtkFileSystemVolumeMountCallback callback,
gpointer data);
GtkFileSystemVolume * _gtk_file_system_get_volume_for_file (GtkFileSystem *file_system,
GFile *file);
/* GtkFileSystemVolume methods */
gchar * _gtk_file_system_volume_get_display_name (GtkFileSystemVolume *volume);
gboolean _gtk_file_system_volume_is_mounted (GtkFileSystemVolume *volume);
GFile * _gtk_file_system_volume_get_root (GtkFileSystemVolume *volume);
GIcon * _gtk_file_system_volume_get_symbolic_icon (GtkFileSystemVolume *volume);
GIcon * _gtk_file_system_volume_get_icon (GtkFileSystemVolume *volume);
GtkFileSystemVolume *_gtk_file_system_volume_ref (GtkFileSystemVolume *volume);
void _gtk_file_system_volume_unref (GtkFileSystemVolume *volume);
/* GFileInfo helper functions */
GIcon * _gtk_file_info_get_icon (GFileInfo *info,
int icon_size,
int scale);
gboolean _gtk_file_info_consider_as_directory (GFileInfo *info);
/* GFile helper functions */
gboolean _gtk_file_has_native_path (GFile *file);
gboolean _gtk_file_consider_as_remote (GFile *file);
G_END_DECLS
#endif /* __GTK_FILE_SYSTEM_H__ */
+57 -5
View File
@@ -23,13 +23,12 @@
#include <stdlib.h>
#include <string.h>
#include "gtkfilechooserutils.h"
#include "gtkfilesystem.h"
#include "gtkintl.h"
#include "gtkmarshalers.h"
#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 - 1);
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 ();
/* fall thru */
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_("Filter 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
+42 -6
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,12 +299,13 @@ 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),
node);
node->list = self;
added += g_list_model_get_n_items (node->model);
added +=g_list_model_get_n_items (node->model);
}
return added;
@@ -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);
}
+6 -6
View File
@@ -1092,7 +1092,7 @@ gtk_grid_view_class_init (GtkGridViewClass *klass)
g_param_spec_object ("model",
P_("Model"),
P_("Model for the items displayed"),
GTK_TYPE_SELECTION_MODEL,
G_TYPE_LIST_MODEL,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
@@ -1235,7 +1235,7 @@ gtk_grid_view_new_with_factory (GtkListItemFactory *factory)
*
* Returns: (nullable) (transfer none): The model in use
**/
GtkSelectionModel *
GListModel *
gtk_grid_view_get_model (GtkGridView *self)
{
g_return_val_if_fail (GTK_IS_GRID_VIEW (self), NULL);
@@ -1248,14 +1248,14 @@ gtk_grid_view_get_model (GtkGridView *self)
* @self: a #GtkGridView
* @model: (allow-none) (transfer none): the model to use or %NULL for none
*
* Sets the #GtkSelectionModel to use for
* Sets the #GListModel to use for
**/
void
gtk_grid_view_set_model (GtkGridView *self,
GtkSelectionModel *model)
gtk_grid_view_set_model (GtkGridView *self,
GListModel *model)
{
g_return_if_fail (GTK_IS_GRID_VIEW (self));
g_return_if_fail (model == NULL || GTK_IS_SELECTION_MODEL (model));
g_return_if_fail (model == NULL || G_IS_LIST_MODEL (model));
if (!gtk_list_base_set_model (GTK_LIST_BASE (self), model))
return;
+2 -3
View File
@@ -25,7 +25,6 @@
#endif
#include <gtk/gtklistbase.h>
#include <gtk/gtkselectionmodel.h>
G_BEGIN_DECLS
@@ -54,10 +53,10 @@ GDK_AVAILABLE_IN_ALL
GtkWidget * gtk_grid_view_new_with_factory (GtkListItemFactory *factory);
GDK_AVAILABLE_IN_ALL
GtkSelectionModel * gtk_grid_view_get_model (GtkGridView *self);
GListModel * gtk_grid_view_get_model (GtkGridView *self);
GDK_AVAILABLE_IN_ALL
void gtk_grid_view_set_model (GtkGridView *self,
GtkSelectionModel *model);
GListModel *model);
GDK_AVAILABLE_IN_ALL
void gtk_grid_view_set_factory (GtkGridView *self,
GtkListItemFactory *factory);

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