forked from AuroraMiddleware/gtk
Merge branch 'gbsneto/filechooser-column-view' into 'main'
Port filechooser to GtkColumnView See merge request GNOME/gtk!5108
This commit is contained in:
commit
c09ba28b06
@ -27,6 +27,8 @@
|
|||||||
#include "gtkmarshalers.h"
|
#include "gtkmarshalers.h"
|
||||||
#include "gtkwidgetprivate.h"
|
#include "gtkwidgetprivate.h"
|
||||||
#include "gsettings-mapping.h"
|
#include "gsettings-mapping.h"
|
||||||
|
#include "gtkdebug.h"
|
||||||
|
#include "gtkprivate.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -846,9 +848,15 @@ gtk_action_muxer_activate_action (GtkActionMuxer *muxer,
|
|||||||
if (!_gtk_bitmask_get (muxer->widget_actions_disabled, position))
|
if (!_gtk_bitmask_get (muxer->widget_actions_disabled, position))
|
||||||
{
|
{
|
||||||
if (action->activate)
|
if (action->activate)
|
||||||
action->activate (muxer->widget, action->name, parameter);
|
{
|
||||||
|
GTK_DEBUG (ACTIONS, "%s: activate action", action->name);
|
||||||
|
action->activate (muxer->widget, action->name, parameter);
|
||||||
|
}
|
||||||
else if (action->pspec)
|
else if (action->pspec)
|
||||||
prop_action_activate (muxer->widget, action, parameter);
|
{
|
||||||
|
GTK_DEBUG (ACTIONS, "%s: activate prop action", action->pspec->name);
|
||||||
|
prop_action_activate (muxer->widget, action, parameter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
297
gtk/gtkfilechoosercell.c
Normal file
297
gtk/gtkfilechoosercell.c
Normal file
@ -0,0 +1,297 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2022 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.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: Matthias Clasen <mclasen@redhat.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "gtkfilechoosercellprivate.h"
|
||||||
|
|
||||||
|
#include "gtkprivate.h"
|
||||||
|
#include "gtkbinlayout.h"
|
||||||
|
#include "gtkdragsource.h"
|
||||||
|
#include "gtkgestureclick.h"
|
||||||
|
#include "gtkgesturelongpress.h"
|
||||||
|
#include "gtkicontheme.h"
|
||||||
|
#include "gtklistitem.h"
|
||||||
|
#include "gtkselectionmodel.h"
|
||||||
|
#include "gtkfilechooserutils.h"
|
||||||
|
#include "gtkfilechooserwidget.h"
|
||||||
|
#include "gtkfilechooserwidgetprivate.h"
|
||||||
|
|
||||||
|
struct _GtkFileChooserCell
|
||||||
|
{
|
||||||
|
GtkWidget parent_instance;
|
||||||
|
|
||||||
|
GFileInfo *item;
|
||||||
|
gboolean selected;
|
||||||
|
guint position;
|
||||||
|
|
||||||
|
gboolean show_time;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _GtkFileChooserCellClass
|
||||||
|
{
|
||||||
|
GtkWidgetClass parent_class;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (GtkFileChooserCell, gtk_file_chooser_cell, GTK_TYPE_WIDGET)
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PROP_POSITION = 1,
|
||||||
|
PROP_SELECTED,
|
||||||
|
PROP_ITEM,
|
||||||
|
PROP_SHOW_TIME,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ICON_SIZE 16
|
||||||
|
|
||||||
|
static void
|
||||||
|
popup_menu (GtkFileChooserCell *self,
|
||||||
|
double x,
|
||||||
|
double y)
|
||||||
|
{
|
||||||
|
GtkWidget *widget = GTK_WIDGET (self);
|
||||||
|
GtkWidget *impl;
|
||||||
|
double xx, yy;
|
||||||
|
|
||||||
|
impl = gtk_widget_get_ancestor (widget, GTK_TYPE_FILE_CHOOSER_WIDGET);
|
||||||
|
|
||||||
|
gtk_widget_translate_coordinates (widget, GTK_WIDGET (impl),
|
||||||
|
x, y, &xx, &yy);
|
||||||
|
|
||||||
|
gtk_widget_activate_action (widget, "item.popup-file-list-menu",
|
||||||
|
"(udd)", self->position, xx, yy);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
file_chooser_cell_clicked (GtkEventController *controller,
|
||||||
|
int n_press,
|
||||||
|
double x,
|
||||||
|
double y)
|
||||||
|
{
|
||||||
|
GtkWidget *widget = gtk_event_controller_get_widget (controller);
|
||||||
|
GtkFileChooserCell *self = GTK_FILE_CHOOSER_CELL (widget);
|
||||||
|
|
||||||
|
popup_menu (self, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
file_chooser_cell_long_pressed (GtkEventController *controller,
|
||||||
|
double x,
|
||||||
|
double y)
|
||||||
|
{
|
||||||
|
GtkWidget *widget = gtk_event_controller_get_widget (controller);
|
||||||
|
GtkFileChooserCell *self = GTK_FILE_CHOOSER_CELL (widget);
|
||||||
|
|
||||||
|
popup_menu (self, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GdkContentProvider *
|
||||||
|
drag_prepare_cb (GtkDragSource *source,
|
||||||
|
double x,
|
||||||
|
double y,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GdkContentProvider *provider;
|
||||||
|
GSList *selection;
|
||||||
|
GtkFileChooserWidget *impl;
|
||||||
|
GtkIconTheme *icon_theme;
|
||||||
|
GIcon *icon;
|
||||||
|
int scale;
|
||||||
|
GtkIconPaintable *paintable;
|
||||||
|
GtkFileChooserCell *self = user_data;
|
||||||
|
|
||||||
|
impl = GTK_FILE_CHOOSER_WIDGET (gtk_widget_get_ancestor (GTK_WIDGET (self),
|
||||||
|
GTK_TYPE_FILE_CHOOSER_WIDGET));
|
||||||
|
|
||||||
|
if (!self->selected)
|
||||||
|
{
|
||||||
|
gtk_selection_model_select_item (gtk_file_chooser_widget_get_selection_model (impl),
|
||||||
|
self->position, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
selection = gtk_file_chooser_widget_get_selected_files (impl);
|
||||||
|
if (!selection)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
scale = gtk_widget_get_scale_factor (GTK_WIDGET (self));
|
||||||
|
icon_theme = gtk_icon_theme_get_for_display (gtk_widget_get_display (GTK_WIDGET (self)));
|
||||||
|
|
||||||
|
icon = _gtk_file_info_get_icon (self->item, ICON_SIZE, scale, icon_theme);
|
||||||
|
|
||||||
|
paintable = gtk_icon_theme_lookup_by_gicon (icon_theme,icon, ICON_SIZE, scale, GTK_TEXT_DIR_NONE, 0);
|
||||||
|
|
||||||
|
gtk_drag_source_set_icon (source, GDK_PAINTABLE (paintable), x, y);
|
||||||
|
|
||||||
|
provider = gdk_content_provider_new_typed (GDK_TYPE_FILE_LIST, selection);
|
||||||
|
g_slist_free_full (selection, g_object_unref);
|
||||||
|
g_object_unref (paintable);
|
||||||
|
g_object_unref (icon);
|
||||||
|
|
||||||
|
return provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_file_chooser_cell_realize (GtkWidget *widget)
|
||||||
|
{
|
||||||
|
GtkFileChooserCell *self = GTK_FILE_CHOOSER_CELL (widget);
|
||||||
|
GtkFileChooserWidget *impl;
|
||||||
|
|
||||||
|
impl = GTK_FILE_CHOOSER_WIDGET (gtk_widget_get_ancestor (GTK_WIDGET (self),
|
||||||
|
GTK_TYPE_FILE_CHOOSER_WIDGET));
|
||||||
|
|
||||||
|
g_object_bind_property (impl, "show-time", self, "show-time", G_BINDING_SYNC_CREATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_file_chooser_cell_init (GtkFileChooserCell *self)
|
||||||
|
{
|
||||||
|
GtkGesture *gesture;
|
||||||
|
GtkDragSource *drag_source;
|
||||||
|
|
||||||
|
gesture = gtk_gesture_click_new ();
|
||||||
|
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY);
|
||||||
|
g_signal_connect (gesture, "pressed", G_CALLBACK (file_chooser_cell_clicked), NULL);
|
||||||
|
gtk_widget_add_controller (GTK_WIDGET (self), GTK_EVENT_CONTROLLER (gesture));
|
||||||
|
|
||||||
|
gesture = gtk_gesture_long_press_new ();
|
||||||
|
g_signal_connect (gesture, "pressed", G_CALLBACK (file_chooser_cell_long_pressed), NULL);
|
||||||
|
|
||||||
|
drag_source = gtk_drag_source_new ();
|
||||||
|
gtk_widget_add_controller (GTK_WIDGET (self), GTK_EVENT_CONTROLLER (drag_source));
|
||||||
|
g_signal_connect (drag_source, "prepare", G_CALLBACK (drag_prepare_cb), self);
|
||||||
|
|
||||||
|
g_signal_connect (self, "realize", G_CALLBACK (gtk_file_chooser_cell_realize), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_file_chooser_cell_dispose (GObject *object)
|
||||||
|
{
|
||||||
|
GtkWidget *child;
|
||||||
|
|
||||||
|
while ((child = gtk_widget_get_first_child (GTK_WIDGET (object))))
|
||||||
|
gtk_widget_unparent (child);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (gtk_file_chooser_cell_parent_class)->dispose (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_file_chooser_cell_set_property (GObject *object,
|
||||||
|
guint prop_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
GtkFileChooserCell *self = GTK_FILE_CHOOSER_CELL (object);
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_POSITION:
|
||||||
|
self->position = g_value_get_uint (value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_SELECTED:
|
||||||
|
self->selected = g_value_get_boolean (value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_ITEM:
|
||||||
|
self->item = g_value_get_object (value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_SHOW_TIME:
|
||||||
|
self->show_time = g_value_get_boolean (value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_file_chooser_cell_get_property (GObject *object,
|
||||||
|
guint prop_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
GtkFileChooserCell *self = GTK_FILE_CHOOSER_CELL (object);
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_POSITION:
|
||||||
|
g_value_set_uint (value, self->position);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_SELECTED:
|
||||||
|
g_value_set_boolean (value, self->selected);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_ITEM:
|
||||||
|
g_value_set_object (value, self->item);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_SHOW_TIME:
|
||||||
|
g_value_set_boolean (value, self->show_time);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_file_chooser_cell_class_init (GtkFileChooserCellClass *klass)
|
||||||
|
{
|
||||||
|
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
object_class->dispose = gtk_file_chooser_cell_dispose;
|
||||||
|
object_class->set_property = gtk_file_chooser_cell_set_property;
|
||||||
|
object_class->get_property = gtk_file_chooser_cell_get_property;
|
||||||
|
|
||||||
|
g_object_class_install_property (object_class, PROP_POSITION,
|
||||||
|
g_param_spec_uint ("position", NULL, NULL,
|
||||||
|
0, G_MAXUINT, 0,
|
||||||
|
GTK_PARAM_READWRITE));
|
||||||
|
|
||||||
|
g_object_class_install_property (object_class, PROP_SELECTED,
|
||||||
|
g_param_spec_boolean ("selected", NULL, NULL,
|
||||||
|
FALSE,
|
||||||
|
GTK_PARAM_READWRITE));
|
||||||
|
|
||||||
|
g_object_class_install_property (object_class, PROP_ITEM,
|
||||||
|
g_param_spec_object ("item", NULL, NULL,
|
||||||
|
G_TYPE_FILE_INFO,
|
||||||
|
GTK_PARAM_READWRITE));
|
||||||
|
|
||||||
|
g_object_class_install_property (object_class, PROP_SHOW_TIME,
|
||||||
|
g_param_spec_boolean ("show-time", NULL, NULL,
|
||||||
|
FALSE,
|
||||||
|
GTK_PARAM_READWRITE));
|
||||||
|
|
||||||
|
gtk_widget_class_set_css_name (widget_class, I_("filelistcell"));
|
||||||
|
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
GtkFileChooserCell *
|
||||||
|
gtk_file_chooser_cell_new (void)
|
||||||
|
{
|
||||||
|
return g_object_new (GTK_TYPE_FILE_CHOOSER_CELL, NULL);
|
||||||
|
}
|
37
gtk/gtkfilechoosercellprivate.h
Normal file
37
gtk/gtkfilechoosercellprivate.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2022 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.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: Matthias Clasen
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GTK_FILE_CHOOSER_CELL_PRIVATE_H__
|
||||||
|
#define __GTK_FILE_CHOOSER_CELL_PRIVATE_H__
|
||||||
|
|
||||||
|
#include <gtk/gtkwidget.h>
|
||||||
|
#include <gtk/gtkexpression.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define GTK_TYPE_FILE_CHOOSER_CELL (gtk_file_chooser_cell_get_type ())
|
||||||
|
|
||||||
|
GDK_AVAILABLE_IN_ALL
|
||||||
|
G_DECLARE_FINAL_TYPE (GtkFileChooserCell, gtk_file_chooser_cell, GTK, FILE_CHOOSER_CELL, GtkWidget)
|
||||||
|
|
||||||
|
GtkFileChooserCell * gtk_file_chooser_cell_new (void);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GTK_FILE_CHOOSER_CELL_PRIVATE_H__ */
|
@ -60,7 +60,8 @@ struct _GtkFileChooserEntry
|
|||||||
char *dir_part;
|
char *dir_part;
|
||||||
char *file_part;
|
char *file_part;
|
||||||
|
|
||||||
GtkTreeModel *completion_store;
|
GtkTreeStore *completion_store;
|
||||||
|
GtkFileSystemModel *model;
|
||||||
GtkFileFilter *current_filter;
|
GtkFileFilter *current_filter;
|
||||||
|
|
||||||
guint current_folder_loaded : 1;
|
guint current_folder_loaded : 1;
|
||||||
@ -71,6 +72,7 @@ struct _GtkFileChooserEntry
|
|||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
FILE_INFO_COLUMN,
|
||||||
DISPLAY_NAME_COLUMN,
|
DISPLAY_NAME_COLUMN,
|
||||||
FULL_PATH_COLUMN,
|
FULL_PATH_COLUMN,
|
||||||
N_COLUMNS
|
N_COLUMNS
|
||||||
@ -197,20 +199,21 @@ match_func (GtkEntryCompletion *compl,
|
|||||||
* current file filter (e.g. just jpg files) here. */
|
* current file filter (e.g. just jpg files) here. */
|
||||||
if (chooser_entry->current_filter != NULL)
|
if (chooser_entry->current_filter != NULL)
|
||||||
{
|
{
|
||||||
GFile *file;
|
|
||||||
GFileInfo *info;
|
GFileInfo *info;
|
||||||
|
|
||||||
file = _gtk_file_system_model_get_file (GTK_FILE_SYSTEM_MODEL (chooser_entry->completion_store),
|
gtk_tree_model_get (GTK_TREE_MODEL (chooser_entry->completion_store),
|
||||||
iter);
|
iter,
|
||||||
info = _gtk_file_system_model_get_info (GTK_FILE_SYSTEM_MODEL (chooser_entry->completion_store),
|
FILE_INFO_COLUMN, &info,
|
||||||
iter);
|
-1);
|
||||||
|
|
||||||
|
g_assert (info != NULL);
|
||||||
|
g_object_unref (info);
|
||||||
|
|
||||||
/* We always allow navigating into subfolders, so don't ever filter directories */
|
/* We always allow navigating into subfolders, so don't ever filter directories */
|
||||||
if (g_file_info_get_file_type (info) != G_FILE_TYPE_REGULAR)
|
if (g_file_info_get_file_type (info) != G_FILE_TYPE_REGULAR)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
if (!g_file_info_has_attribute (info, "standard::file"))
|
g_assert (g_file_info_has_attribute (info, "standard::file"));
|
||||||
g_file_info_set_attribute_object (info, "standard::file", G_OBJECT (file));
|
|
||||||
|
|
||||||
return gtk_filter_match (GTK_FILTER (chooser_entry->current_filter), info);
|
return gtk_filter_match (GTK_FILTER (chooser_entry->current_filter), info);
|
||||||
}
|
}
|
||||||
@ -428,7 +431,7 @@ explicitly_complete (GtkFileChooserEntry *chooser_entry)
|
|||||||
{
|
{
|
||||||
chooser_entry->complete_on_load = FALSE;
|
chooser_entry->complete_on_load = FALSE;
|
||||||
|
|
||||||
if (chooser_entry->completion_store)
|
if (chooser_entry->model)
|
||||||
{
|
{
|
||||||
char *completion, *text;
|
char *completion, *text;
|
||||||
gsize completion_len, text_len;
|
gsize completion_len, text_len;
|
||||||
@ -539,77 +542,93 @@ update_inline_completion (GtkFileChooserEntry *chooser_entry)
|
|||||||
static void
|
static void
|
||||||
discard_completion_store (GtkFileChooserEntry *chooser_entry)
|
discard_completion_store (GtkFileChooserEntry *chooser_entry)
|
||||||
{
|
{
|
||||||
if (!chooser_entry->completion_store)
|
if (!chooser_entry->model)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
g_assert (chooser_entry->completion_store != NULL);
|
||||||
|
|
||||||
gtk_entry_completion_set_model (gtk_entry_get_completion (GTK_ENTRY (chooser_entry)), NULL);
|
gtk_entry_completion_set_model (gtk_entry_get_completion (GTK_ENTRY (chooser_entry)), NULL);
|
||||||
update_inline_completion (chooser_entry);
|
update_inline_completion (chooser_entry);
|
||||||
g_object_unref (chooser_entry->completion_store);
|
g_clear_object (&chooser_entry->completion_store);
|
||||||
chooser_entry->completion_store = NULL;
|
g_clear_object (&chooser_entry->model);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static void
|
||||||
completion_store_set (GtkFileSystemModel *model,
|
model_items_changed_cb (GListModel *model,
|
||||||
GFile *file,
|
guint position,
|
||||||
GFileInfo *info,
|
guint removed,
|
||||||
int column,
|
guint added,
|
||||||
GValue *value,
|
GtkFileChooserEntry *self)
|
||||||
gpointer data)
|
|
||||||
{
|
{
|
||||||
GtkFileChooserEntry *chooser_entry = data;
|
if (removed > 0)
|
||||||
|
|
||||||
const char *prefix = "";
|
|
||||||
const char *suffix = "";
|
|
||||||
|
|
||||||
switch (column)
|
|
||||||
{
|
{
|
||||||
case FULL_PATH_COLUMN:
|
GtkTreeIter iter;
|
||||||
prefix = chooser_entry->dir_part;
|
|
||||||
G_GNUC_FALLTHROUGH;
|
if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (self->completion_store),
|
||||||
case DISPLAY_NAME_COLUMN:
|
&iter,
|
||||||
|
NULL,
|
||||||
|
position))
|
||||||
|
{
|
||||||
|
while (removed--)
|
||||||
|
gtk_tree_store_remove (self->completion_store, &iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (added-- > 0)
|
||||||
|
{
|
||||||
|
GtkTreeIter iter;
|
||||||
|
GFileInfo *info;
|
||||||
|
const char *suffix = NULL;
|
||||||
|
char *full_path;
|
||||||
|
char *display_name;
|
||||||
|
|
||||||
|
info = g_list_model_get_item (model, position);
|
||||||
|
|
||||||
if (_gtk_file_info_consider_as_directory (info))
|
if (_gtk_file_info_consider_as_directory (info))
|
||||||
suffix = G_DIR_SEPARATOR_S;
|
suffix = G_DIR_SEPARATOR_S;
|
||||||
|
|
||||||
g_value_take_string (value,
|
display_name = g_strconcat (g_file_info_get_display_name (info), suffix, NULL);
|
||||||
g_strconcat (prefix,
|
full_path = g_strconcat (self->dir_part, display_name, NULL);
|
||||||
g_file_info_get_display_name (info),
|
|
||||||
suffix,
|
|
||||||
NULL));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
g_assert_not_reached ();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
gtk_tree_store_insert_with_values (self->completion_store,
|
||||||
|
&iter, NULL,
|
||||||
|
position,
|
||||||
|
FILE_INFO_COLUMN, info,
|
||||||
|
FULL_PATH_COLUMN, full_path,
|
||||||
|
DISPLAY_NAME_COLUMN, display_name,
|
||||||
|
-1);
|
||||||
|
|
||||||
|
g_clear_object (&info);
|
||||||
|
|
||||||
|
position++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fills the completion store from the contents of the current folder */
|
/* Fills the completion store from the contents of the current folder */
|
||||||
static void
|
static void
|
||||||
populate_completion_store (GtkFileChooserEntry *chooser_entry)
|
populate_completion_store (GtkFileChooserEntry *chooser_entry)
|
||||||
{
|
{
|
||||||
chooser_entry->completion_store = GTK_TREE_MODEL (
|
chooser_entry->completion_store = gtk_tree_store_new (N_COLUMNS,
|
||||||
|
G_TYPE_FILE_INFO,
|
||||||
|
G_TYPE_STRING,
|
||||||
|
G_TYPE_STRING);
|
||||||
|
|
||||||
|
chooser_entry->model =
|
||||||
_gtk_file_system_model_new_for_directory (chooser_entry->current_folder_file,
|
_gtk_file_system_model_new_for_directory (chooser_entry->current_folder_file,
|
||||||
"standard::name,standard::display-name,standard::type,"
|
"standard::name,standard::display-name,standard::type,"
|
||||||
"standard::content-type",
|
"standard::content-type");
|
||||||
completion_store_set,
|
g_signal_connect (chooser_entry->model, "items-changed",
|
||||||
chooser_entry,
|
G_CALLBACK (model_items_changed_cb), chooser_entry);
|
||||||
N_COLUMNS,
|
g_signal_connect (chooser_entry->model, "finished-loading",
|
||||||
G_TYPE_STRING,
|
|
||||||
G_TYPE_STRING));
|
|
||||||
g_signal_connect (chooser_entry->completion_store, "finished-loading",
|
|
||||||
G_CALLBACK (finished_loading_cb), chooser_entry);
|
G_CALLBACK (finished_loading_cb), chooser_entry);
|
||||||
|
|
||||||
_gtk_file_system_model_set_filter_folders (GTK_FILE_SYSTEM_MODEL (chooser_entry->completion_store),
|
_gtk_file_system_model_set_filter_folders (chooser_entry->model, TRUE);
|
||||||
TRUE);
|
_gtk_file_system_model_set_show_files (chooser_entry->model,
|
||||||
_gtk_file_system_model_set_show_files (GTK_FILE_SYSTEM_MODEL (chooser_entry->completion_store),
|
|
||||||
chooser_entry->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
|
chooser_entry->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
|
||||||
chooser_entry->action == GTK_FILE_CHOOSER_ACTION_SAVE);
|
chooser_entry->action == GTK_FILE_CHOOSER_ACTION_SAVE);
|
||||||
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (chooser_entry->completion_store),
|
|
||||||
DISPLAY_NAME_COLUMN, GTK_SORT_ASCENDING);
|
|
||||||
|
|
||||||
gtk_entry_completion_set_model (gtk_entry_get_completion (GTK_ENTRY (chooser_entry)),
|
gtk_entry_completion_set_model (gtk_entry_get_completion (GTK_ENTRY (chooser_entry)),
|
||||||
chooser_entry->completion_store);
|
GTK_TREE_MODEL (chooser_entry->completion_store));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Callback when the current folder finishes loading */
|
/* Callback when the current folder finishes loading */
|
||||||
@ -658,11 +677,7 @@ set_completion_folder (GtkFileChooserEntry *chooser_entry,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chooser_entry->current_folder_file)
|
g_clear_object (&chooser_entry->current_folder_file);
|
||||||
{
|
|
||||||
g_object_unref (chooser_entry->current_folder_file);
|
|
||||||
chooser_entry->current_folder_file = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free (chooser_entry->dir_part);
|
g_free (chooser_entry->dir_part);
|
||||||
chooser_entry->dir_part = g_strdup (dir_part);
|
chooser_entry->dir_part = g_strdup (dir_part);
|
||||||
@ -710,7 +725,7 @@ refresh_current_folder_and_file_part (GtkFileChooserEntry *chooser_entry)
|
|||||||
|
|
||||||
g_free (dir_part);
|
g_free (dir_part);
|
||||||
|
|
||||||
if (chooser_entry->completion_store &&
|
if (chooser_entry->model &&
|
||||||
(g_strcmp0 (old_file_part, chooser_entry->file_part) != 0))
|
(g_strcmp0 (old_file_part, chooser_entry->file_part) != 0))
|
||||||
{
|
{
|
||||||
GtkFileFilter *filter;
|
GtkFileFilter *filter;
|
||||||
@ -720,8 +735,7 @@ refresh_current_folder_and_file_part (GtkFileChooserEntry *chooser_entry)
|
|||||||
pattern = g_strconcat (chooser_entry->file_part, "*", NULL);
|
pattern = g_strconcat (chooser_entry->file_part, "*", NULL);
|
||||||
gtk_file_filter_add_pattern (filter, pattern);
|
gtk_file_filter_add_pattern (filter, pattern);
|
||||||
|
|
||||||
_gtk_file_system_model_set_filter (GTK_FILE_SYSTEM_MODEL (chooser_entry->completion_store),
|
_gtk_file_system_model_set_filter (chooser_entry->model, filter);
|
||||||
filter);
|
|
||||||
|
|
||||||
g_free (pattern);
|
g_free (pattern);
|
||||||
g_object_unref (filter);
|
g_object_unref (filter);
|
||||||
@ -940,8 +954,8 @@ _gtk_file_chooser_entry_set_action (GtkFileChooserEntry *chooser_entry,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chooser_entry->completion_store)
|
if (chooser_entry->model)
|
||||||
_gtk_file_system_model_set_show_files (GTK_FILE_SYSTEM_MODEL (chooser_entry->completion_store),
|
_gtk_file_system_model_set_show_files (chooser_entry->model,
|
||||||
action == GTK_FILE_CHOOSER_ACTION_OPEN ||
|
action == GTK_FILE_CHOOSER_ACTION_OPEN ||
|
||||||
action == GTK_FILE_CHOOSER_ACTION_SAVE);
|
action == GTK_FILE_CHOOSER_ACTION_SAVE);
|
||||||
|
|
||||||
@ -971,17 +985,14 @@ gboolean
|
|||||||
_gtk_file_chooser_entry_get_is_folder (GtkFileChooserEntry *chooser_entry,
|
_gtk_file_chooser_entry_get_is_folder (GtkFileChooserEntry *chooser_entry,
|
||||||
GFile *file)
|
GFile *file)
|
||||||
{
|
{
|
||||||
GtkTreeIter iter;
|
|
||||||
GFileInfo *info;
|
GFileInfo *info;
|
||||||
|
|
||||||
if (chooser_entry->completion_store == NULL ||
|
if (chooser_entry->model == NULL)
|
||||||
!_gtk_file_system_model_get_iter_for_file (GTK_FILE_SYSTEM_MODEL (chooser_entry->completion_store),
|
|
||||||
&iter,
|
|
||||||
file))
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
info = _gtk_file_system_model_get_info (GTK_FILE_SYSTEM_MODEL (chooser_entry->completion_store),
|
info = _gtk_file_system_model_get_info_for_file (chooser_entry->model, file);
|
||||||
&iter);
|
if (!info)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
return _gtk_file_info_consider_as_directory (info);
|
return _gtk_file_info_consider_as_directory (info);
|
||||||
}
|
}
|
||||||
|
@ -479,3 +479,12 @@ _gtk_file_info_get_icon (GFileInfo *info,
|
|||||||
icon = g_themed_icon_new ("text-x-generic");
|
icon = g_themed_icon_new ("text-x-generic");
|
||||||
return icon;
|
return icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GFile *
|
||||||
|
_gtk_file_info_get_file (GFileInfo *info)
|
||||||
|
{
|
||||||
|
g_assert (G_IS_FILE_INFO (info));
|
||||||
|
g_assert (g_file_info_has_attribute (info, "standard::file"));
|
||||||
|
|
||||||
|
return G_FILE (g_file_info_get_attribute_object (info, "standard::file"));
|
||||||
|
}
|
||||||
|
@ -58,6 +58,8 @@ GIcon * _gtk_file_info_get_icon (GFileInfo *info,
|
|||||||
int scale,
|
int scale,
|
||||||
GtkIconTheme *icon_theme);
|
GtkIconTheme *icon_theme);
|
||||||
|
|
||||||
|
GFile * _gtk_file_info_get_file (GFileInfo *info);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GTK_FILE_CHOOSER_UTILS_H__ */
|
#endif /* __GTK_FILE_CHOOSER_UTILS_H__ */
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include "gtkfilechooserwidget.h"
|
#include "gtkfilechooserwidget.h"
|
||||||
|
#include "gtkselectionmodel.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
@ -36,6 +37,12 @@ gtk_file_chooser_widget_should_respond (GtkFileChooserWidget *chooser);
|
|||||||
void
|
void
|
||||||
gtk_file_chooser_widget_initial_focus (GtkFileChooserWidget *chooser);
|
gtk_file_chooser_widget_initial_focus (GtkFileChooserWidget *chooser);
|
||||||
|
|
||||||
|
GSList *
|
||||||
|
gtk_file_chooser_widget_get_selected_files (GtkFileChooserWidget *impl);
|
||||||
|
|
||||||
|
GtkSelectionModel *
|
||||||
|
gtk_file_chooser_widget_get_selection_model (GtkFileChooserWidget *chooser);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GTK_FILE_CHOOSER_WIDGET_PRIVATE_H__ */
|
#endif /* __GTK_FILE_CHOOSER_WIDGET_PRIVATE_H__ */
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -21,7 +21,6 @@
|
|||||||
|
|
||||||
#include <gio/gio.h>
|
#include <gio/gio.h>
|
||||||
#include <gtk/gtkfilefilter.h>
|
#include <gtk/gtkfilefilter.h>
|
||||||
#include <gtk/deprecated/gtktreemodel.h>
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
@ -33,39 +32,13 @@ typedef struct _GtkFileSystemModel GtkFileSystemModel;
|
|||||||
|
|
||||||
GType _gtk_file_system_model_get_type (void) G_GNUC_CONST;
|
GType _gtk_file_system_model_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
typedef gboolean (*GtkFileSystemModelGetValue) (GtkFileSystemModel *model,
|
GtkFileSystemModel *_gtk_file_system_model_new (void);
|
||||||
GFile *file,
|
GtkFileSystemModel *_gtk_file_system_model_new_for_directory(GFile *dir,
|
||||||
GFileInfo *info,
|
const char *attributes);
|
||||||
int column,
|
|
||||||
GValue *value,
|
|
||||||
gpointer user_data);
|
|
||||||
|
|
||||||
GtkFileSystemModel *_gtk_file_system_model_new (GtkFileSystemModelGetValue get_func,
|
|
||||||
gpointer get_data,
|
|
||||||
guint n_columns,
|
|
||||||
...);
|
|
||||||
GtkFileSystemModel *_gtk_file_system_model_new_for_directory(GFile * dir,
|
|
||||||
const char * attributes,
|
|
||||||
GtkFileSystemModelGetValue get_func,
|
|
||||||
gpointer get_data,
|
|
||||||
guint n_columns,
|
|
||||||
...);
|
|
||||||
GFile * _gtk_file_system_model_get_directory (GtkFileSystemModel *model);
|
GFile * _gtk_file_system_model_get_directory (GtkFileSystemModel *model);
|
||||||
GCancellable * _gtk_file_system_model_get_cancellable (GtkFileSystemModel *model);
|
GCancellable * _gtk_file_system_model_get_cancellable (GtkFileSystemModel *model);
|
||||||
gboolean _gtk_file_system_model_iter_is_visible (GtkFileSystemModel *model,
|
GFileInfo * _gtk_file_system_model_get_info_for_file(GtkFileSystemModel *model,
|
||||||
GtkTreeIter *iter);
|
|
||||||
gboolean _gtk_file_system_model_iter_is_filtered_out (GtkFileSystemModel *model,
|
|
||||||
GtkTreeIter *iter);
|
|
||||||
GFileInfo * _gtk_file_system_model_get_info (GtkFileSystemModel *model,
|
|
||||||
GtkTreeIter *iter);
|
|
||||||
gboolean _gtk_file_system_model_get_iter_for_file(GtkFileSystemModel *model,
|
|
||||||
GtkTreeIter *iter,
|
|
||||||
GFile *file);
|
GFile *file);
|
||||||
GFile * _gtk_file_system_model_get_file (GtkFileSystemModel *model,
|
|
||||||
GtkTreeIter *iter);
|
|
||||||
const GValue * _gtk_file_system_model_get_value (GtkFileSystemModel *model,
|
|
||||||
GtkTreeIter * iter,
|
|
||||||
int column);
|
|
||||||
|
|
||||||
void _gtk_file_system_model_add_and_query_file (GtkFileSystemModel *model,
|
void _gtk_file_system_model_add_and_query_file (GtkFileSystemModel *model,
|
||||||
GFile *file,
|
GFile *file,
|
||||||
@ -88,8 +61,6 @@ void _gtk_file_system_model_set_show_files (GtkFileSystemModel
|
|||||||
gboolean show_files);
|
gboolean show_files);
|
||||||
void _gtk_file_system_model_set_filter_folders (GtkFileSystemModel *model,
|
void _gtk_file_system_model_set_filter_folders (GtkFileSystemModel *model,
|
||||||
gboolean show_folders);
|
gboolean show_folders);
|
||||||
void _gtk_file_system_model_clear_cache (GtkFileSystemModel *model,
|
|
||||||
int column);
|
|
||||||
|
|
||||||
void _gtk_file_system_model_set_filter (GtkFileSystemModel *model,
|
void _gtk_file_system_model_set_filter (GtkFileSystemModel *model,
|
||||||
GtkFileFilter *filter);
|
GtkFileFilter *filter);
|
||||||
|
255
gtk/gtkfilethumbnail.c
Normal file
255
gtk/gtkfilethumbnail.c
Normal file
@ -0,0 +1,255 @@
|
|||||||
|
/* gtkfilethumbnail.c
|
||||||
|
*
|
||||||
|
* Copyright 2022 Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||||
|
*
|
||||||
|
* This file 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 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This file 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 program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "gtkfilethumbnail.h"
|
||||||
|
|
||||||
|
#include "gtkbinlayout.h"
|
||||||
|
#include "gtkfilechooserutils.h"
|
||||||
|
#include "gtkimage.h"
|
||||||
|
#include "gtkprivate.h"
|
||||||
|
#include "gtkwidget.h"
|
||||||
|
|
||||||
|
#define ICON_SIZE 16
|
||||||
|
|
||||||
|
struct _GtkFileThumbnail
|
||||||
|
{
|
||||||
|
GtkWidget parent;
|
||||||
|
|
||||||
|
GtkWidget *image;
|
||||||
|
|
||||||
|
GCancellable *cancellable;
|
||||||
|
GFileInfo *info;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GtkWidgetClass parent;
|
||||||
|
} GtkFileThumbnailClass;
|
||||||
|
|
||||||
|
G_DEFINE_FINAL_TYPE (GtkFileThumbnail, _gtk_file_thumbnail, GTK_TYPE_WIDGET)
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PROP_0,
|
||||||
|
PROP_INFO,
|
||||||
|
N_PROPS,
|
||||||
|
};
|
||||||
|
|
||||||
|
static GParamSpec *properties [N_PROPS];
|
||||||
|
|
||||||
|
static void
|
||||||
|
copy_attribute (GFileInfo *to,
|
||||||
|
GFileInfo *from,
|
||||||
|
const char *attribute)
|
||||||
|
{
|
||||||
|
GFileAttributeType type;
|
||||||
|
gpointer value;
|
||||||
|
|
||||||
|
if (g_file_info_get_attribute_data (from, attribute, &type, &value, NULL))
|
||||||
|
g_file_info_set_attribute (to, attribute, type, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
update_image (GtkFileThumbnail *self)
|
||||||
|
{
|
||||||
|
GtkIconTheme *icon_theme;
|
||||||
|
GIcon *icon;
|
||||||
|
int scale;
|
||||||
|
|
||||||
|
if (!g_file_info_has_attribute (self->info, G_FILE_ATTRIBUTE_STANDARD_ICON))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
scale = gtk_widget_get_scale_factor (GTK_WIDGET (self));
|
||||||
|
icon_theme = gtk_icon_theme_get_for_display (gtk_widget_get_display (GTK_WIDGET (self)));
|
||||||
|
|
||||||
|
icon = _gtk_file_info_get_icon (self->info, ICON_SIZE, scale, icon_theme);
|
||||||
|
|
||||||
|
gtk_image_set_from_gicon (GTK_IMAGE (self->image), icon);
|
||||||
|
|
||||||
|
g_object_unref (icon);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
thumbnail_queried_cb (GObject *object,
|
||||||
|
GAsyncResult *result,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GtkFileThumbnail *self = user_data; /* might be unreffed if operation was cancelled */
|
||||||
|
GFile *file = G_FILE (object);
|
||||||
|
GFileInfo *queried;
|
||||||
|
|
||||||
|
queried = g_file_query_info_finish (file, result, NULL);
|
||||||
|
if (queried == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
copy_attribute (self->info, queried, G_FILE_ATTRIBUTE_THUMBNAIL_PATH);
|
||||||
|
copy_attribute (self->info, queried, G_FILE_ATTRIBUTE_THUMBNAILING_FAILED);
|
||||||
|
copy_attribute (self->info, queried, G_FILE_ATTRIBUTE_STANDARD_ICON);
|
||||||
|
|
||||||
|
update_image (self);
|
||||||
|
|
||||||
|
g_clear_object (&queried);
|
||||||
|
|
||||||
|
g_clear_object (&self->cancellable);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cancel_thumbnail (GtkFileThumbnail *self)
|
||||||
|
{
|
||||||
|
g_cancellable_cancel (self->cancellable);
|
||||||
|
g_clear_object (&self->cancellable);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_thumbnail (GtkFileThumbnail *self)
|
||||||
|
{
|
||||||
|
if (!self->info)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!update_image (self))
|
||||||
|
{
|
||||||
|
GFile *file;
|
||||||
|
|
||||||
|
if (g_file_info_has_attribute (self->info, "filechooser::queried"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_assert (self->cancellable == NULL);
|
||||||
|
self->cancellable = g_cancellable_new ();
|
||||||
|
|
||||||
|
file = _gtk_file_info_get_file (self->info);
|
||||||
|
g_file_info_set_attribute_boolean (self->info, "filechooser::queried", TRUE);
|
||||||
|
g_file_query_info_async (file,
|
||||||
|
G_FILE_ATTRIBUTE_THUMBNAIL_PATH ","
|
||||||
|
G_FILE_ATTRIBUTE_THUMBNAILING_FAILED ","
|
||||||
|
G_FILE_ATTRIBUTE_STANDARD_ICON,
|
||||||
|
G_FILE_QUERY_INFO_NONE,
|
||||||
|
G_PRIORITY_DEFAULT,
|
||||||
|
self->cancellable,
|
||||||
|
thumbnail_queried_cb,
|
||||||
|
self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_gtk_file_thumbnail_dispose (GObject *object)
|
||||||
|
{
|
||||||
|
GtkFileThumbnail *self = (GtkFileThumbnail *)object;
|
||||||
|
|
||||||
|
_gtk_file_thumbnail_set_info (self, NULL);
|
||||||
|
|
||||||
|
g_clear_pointer (&self->image, gtk_widget_unparent);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (_gtk_file_thumbnail_parent_class)->dispose (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_gtk_file_thumbnail_get_property (GObject *object,
|
||||||
|
guint prop_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
GtkFileThumbnail *self = GTK_FILE_THUMBNAIL (object);
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_INFO:
|
||||||
|
g_value_set_object (value, self->info);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_gtk_file_thumbnail_set_property (GObject *object,
|
||||||
|
guint prop_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
GtkFileThumbnail *self = GTK_FILE_THUMBNAIL (object);
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_INFO:
|
||||||
|
_gtk_file_thumbnail_set_info (self, g_value_get_object (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_gtk_file_thumbnail_class_init (GtkFileThumbnailClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||||
|
|
||||||
|
object_class->dispose = _gtk_file_thumbnail_dispose;
|
||||||
|
object_class->get_property = _gtk_file_thumbnail_get_property;
|
||||||
|
object_class->set_property = _gtk_file_thumbnail_set_property;
|
||||||
|
|
||||||
|
properties[PROP_INFO] =
|
||||||
|
g_param_spec_object ("file-info", NULL, NULL,
|
||||||
|
G_TYPE_FILE_INFO,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||||
|
|
||||||
|
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||||
|
|
||||||
|
gtk_widget_class_set_css_name (widget_class, I_("filethumbnail"));
|
||||||
|
|
||||||
|
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_gtk_file_thumbnail_init (GtkFileThumbnail *self)
|
||||||
|
{
|
||||||
|
self->image = gtk_image_new ();
|
||||||
|
gtk_widget_set_parent (self->image, GTK_WIDGET (self));
|
||||||
|
}
|
||||||
|
|
||||||
|
GFileInfo *
|
||||||
|
_gtk_file_thumbnail_get_info (GtkFileThumbnail *self)
|
||||||
|
{
|
||||||
|
g_assert (GTK_IS_FILE_THUMBNAIL (self));
|
||||||
|
|
||||||
|
return self->info;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_gtk_file_thumbnail_set_info (GtkFileThumbnail *self,
|
||||||
|
GFileInfo *info)
|
||||||
|
{
|
||||||
|
g_assert (GTK_IS_FILE_THUMBNAIL (self));
|
||||||
|
g_assert (info == NULL || G_IS_FILE_INFO (info));
|
||||||
|
|
||||||
|
if (g_set_object (&self->info, info))
|
||||||
|
{
|
||||||
|
cancel_thumbnail (self);
|
||||||
|
get_thumbnail (self);
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_INFO]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
46
gtk/gtkfilethumbnail.h
Normal file
46
gtk/gtkfilethumbnail.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/* gtkfilethumbnail.h
|
||||||
|
*
|
||||||
|
* Copyright 2022 Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||||
|
*
|
||||||
|
* This file 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 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This file 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 program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __GTK_FILE_THUMBNAIL_H__
|
||||||
|
#define __GTK_FILE_THUMBNAIL_H__
|
||||||
|
|
||||||
|
#include <gio/gio.h>
|
||||||
|
|
||||||
|
#include "gtkfilesystemmodel.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define GTK_TYPE_FILE_THUMBNAIL (_gtk_file_thumbnail_get_type ())
|
||||||
|
#define GTK_FILE_THUMBNAIL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_FILE_THUMBNAIL, GtkFileThumbnail))
|
||||||
|
#define GTK_IS_FILE_THUMBNAIL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_FILE_THUMBNAIL))
|
||||||
|
|
||||||
|
typedef struct _GtkFileThumbnail GtkFileThumbnail;
|
||||||
|
|
||||||
|
GType _gtk_file_thumbnail_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
GFileInfo *_gtk_file_thumbnail_get_info (GtkFileThumbnail *self);
|
||||||
|
void _gtk_file_thumbnail_set_info (GtkFileThumbnail *self,
|
||||||
|
GFileInfo *info);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GTK_FILE_THUMBNAIL_H__ */
|
||||||
|
|
@ -24,6 +24,7 @@
|
|||||||
#include <gdk/gdk.h>
|
#include <gdk/gdk.h>
|
||||||
|
|
||||||
#include "gtksearchenginemodelprivate.h"
|
#include "gtksearchenginemodelprivate.h"
|
||||||
|
#include "gtkfilechooserutils.h"
|
||||||
#include "gtkprivate.h"
|
#include "gtkprivate.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -81,37 +82,33 @@ static gboolean
|
|||||||
do_search (gpointer data)
|
do_search (gpointer data)
|
||||||
{
|
{
|
||||||
GtkSearchEngineModel *model = data;
|
GtkSearchEngineModel *model = data;
|
||||||
GtkTreeIter iter;
|
|
||||||
GList *hits = NULL;
|
GList *hits = NULL;
|
||||||
gboolean got_results = FALSE;
|
gboolean got_results = FALSE;
|
||||||
|
|
||||||
if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model->model), &iter))
|
for (guint i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (model->model)); i++)
|
||||||
{
|
{
|
||||||
do
|
GFileInfo *info = g_list_model_get_item (G_LIST_MODEL (model->model), i);
|
||||||
|
|
||||||
|
if (info_matches_query (model->query, info))
|
||||||
{
|
{
|
||||||
GFileInfo *info;
|
GFile *file;
|
||||||
|
GtkSearchHit *hit;
|
||||||
|
|
||||||
info = _gtk_file_system_model_get_info (model->model, &iter);
|
file = _gtk_file_info_get_file (info);
|
||||||
if (info_matches_query (model->query, info))
|
hit = g_new (GtkSearchHit, 1);
|
||||||
{
|
hit->file = g_object_ref (file);
|
||||||
GFile *file;
|
hit->info = g_object_ref (info);
|
||||||
GtkSearchHit *hit;
|
hits = g_list_prepend (hits, hit);
|
||||||
|
|
||||||
file = _gtk_file_system_model_get_file (model->model, &iter);
|
|
||||||
hit = g_new (GtkSearchHit, 1);
|
|
||||||
hit->file = g_object_ref (file);
|
|
||||||
hit->info = g_object_ref (info);
|
|
||||||
hits = g_list_prepend (hits, hit);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
while (gtk_tree_model_iter_next (GTK_TREE_MODEL (model->model), &iter));
|
|
||||||
|
|
||||||
if (hits)
|
g_clear_object (&info);
|
||||||
{
|
}
|
||||||
_gtk_search_engine_hits_added (GTK_SEARCH_ENGINE (model), hits);
|
|
||||||
g_list_free_full (hits, (GDestroyNotify)_gtk_search_hit_free);
|
if (hits)
|
||||||
got_results = TRUE;
|
{
|
||||||
}
|
_gtk_search_engine_hits_added (GTK_SEARCH_ENGINE (model), hits);
|
||||||
|
g_list_free_full (hits, (GDestroyNotify)_gtk_search_hit_free);
|
||||||
|
got_results = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
model->idle = 0;
|
model->idle = 0;
|
||||||
|
@ -114,7 +114,8 @@ free_hit (gpointer data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static GFileInfo *
|
static GFileInfo *
|
||||||
create_file_info (TrackerSparqlCursor *cursor)
|
create_file_info (GFile *file,
|
||||||
|
TrackerSparqlCursor *cursor)
|
||||||
{
|
{
|
||||||
GFileInfo *info;
|
GFileInfo *info;
|
||||||
const char *str;
|
const char *str;
|
||||||
@ -140,6 +141,10 @@ create_file_info (TrackerSparqlCursor *cursor)
|
|||||||
g_date_time_unref (creation);
|
g_date_time_unref (creation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_file_info_set_attribute_object (info, "standard::file", G_OBJECT (file));
|
||||||
|
g_file_info_set_attribute_boolean (info, "filechooser::filtered-out", FALSE);
|
||||||
|
g_file_info_set_attribute_boolean (info, "filechooser::visible", TRUE);
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,7 +180,7 @@ query_callback (TrackerSparqlStatement *statement,
|
|||||||
url = tracker_sparql_cursor_get_string (cursor, 0, NULL);
|
url = tracker_sparql_cursor_get_string (cursor, 0, NULL);
|
||||||
hit = g_slice_new0 (GtkSearchHit);
|
hit = g_slice_new0 (GtkSearchHit);
|
||||||
hit->file = g_file_new_for_uri (url);
|
hit->file = g_file_new_for_uri (url);
|
||||||
hit->info = create_file_info (cursor);
|
hit->info = create_file_info (hit->file, cursor);
|
||||||
hits = g_list_prepend (hits, hit);
|
hits = g_list_prepend (hits, hit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +108,9 @@ gtk_private_sources = files([
|
|||||||
'gtkfilechoosererrorstack.c',
|
'gtkfilechoosererrorstack.c',
|
||||||
'gtkfilechoosernativeportal.c',
|
'gtkfilechoosernativeportal.c',
|
||||||
'gtkfilechooserutils.c',
|
'gtkfilechooserutils.c',
|
||||||
|
'gtkfilechoosercell.c',
|
||||||
'gtkfilesystemmodel.c',
|
'gtkfilesystemmodel.c',
|
||||||
|
'gtkfilethumbnail.c',
|
||||||
'gtkgizmo.c',
|
'gtkgizmo.c',
|
||||||
'gtkiconcache.c',
|
'gtkiconcache.c',
|
||||||
'gtkiconcachevalidator.c',
|
'gtkiconcachevalidator.c',
|
||||||
|
@ -3369,6 +3369,30 @@ columnview row:not(:selected) cell editablelabel.editing text selection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/********************************************************
|
||||||
|
* Complex Lists *
|
||||||
|
* Put padding on the cell content so event controllers *
|
||||||
|
* can cover the whole area. *
|
||||||
|
********************************************************/
|
||||||
|
|
||||||
|
columnview.complex {
|
||||||
|
> listview > row > cell {
|
||||||
|
padding: 0;
|
||||||
|
> * {
|
||||||
|
padding: 8px 6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// shrink vertically for .data-table
|
||||||
|
&.data-table > listview > row > cell {
|
||||||
|
padding: 0;
|
||||||
|
> * {
|
||||||
|
padding-top: 2px;
|
||||||
|
padding-bottom: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*********************
|
/*********************
|
||||||
* App Notifications *
|
* App Notifications *
|
||||||
*********************/
|
*********************/
|
||||||
|
@ -140,103 +140,278 @@
|
|||||||
<property name="hscrollbar-policy">2</property>
|
<property name="hscrollbar-policy">2</property>
|
||||||
<property name="vexpand">1</property>
|
<property name="vexpand">1</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkTreeView" id="browse_files_tree_view">
|
<object class="GtkColumnView" id="browse_files_column_view">
|
||||||
<property name="has-tooltip">1</property>
|
<style>
|
||||||
<property name="enable-search">0</property>
|
<class name="complex"/>
|
||||||
|
</style>
|
||||||
|
<signal name="activate" handler="column_view_row_activated_cb" swapped="no"/>
|
||||||
|
<signal name="keynav-failed" handler="browse_files_column_view_keynav_failed_cb"/>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkGestureLongPress">
|
<object class="GtkColumnViewColumn" id="column_view_name_column">
|
||||||
<property name="touch-only">1</property>
|
|
||||||
<signal name="pressed" handler="long_press_cb" swapped="no"/>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkGestureClick">
|
|
||||||
<property name="button">3</property>
|
|
||||||
<signal name="pressed" handler="click_cb" swapped="no"/>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<signal name="query-tooltip" handler="file_list_query_tooltip_cb" swapped="no"/>
|
|
||||||
<signal name="row-activated" handler="list_row_activated" swapped="no"/>
|
|
||||||
<signal name="keynav-failed" handler="browse_files_tree_view_keynav_failed_cb"/>
|
|
||||||
<child internal-child="selection">
|
|
||||||
<object class="GtkTreeSelection" id="treeview-selection2">
|
|
||||||
<signal name="changed" handler="list_selection_changed" swapped="no"/>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkTreeViewColumn" id="list_name_column">
|
|
||||||
<property name="title" translatable="yes">Name</property>
|
<property name="title" translatable="yes">Name</property>
|
||||||
<property name="resizable">1</property>
|
|
||||||
<property name="expand">1</property>
|
<property name="expand">1</property>
|
||||||
<child>
|
<property name="resizable">1</property>
|
||||||
<object class="GtkCellRendererPixbuf" id="list_pixbuf_renderer">
|
<property name="factory">
|
||||||
<property name="xpad">6</property>
|
<object class="GtkBuilderListItemFactory">
|
||||||
|
<property name="bytes"><![CDATA[
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<interface>
|
||||||
|
<template class="GtkListItem">
|
||||||
|
<property name="child">
|
||||||
|
<object class="GtkFileChooserCell">
|
||||||
|
<binding name="position">
|
||||||
|
<lookup name="position">GtkListItem</lookup>
|
||||||
|
</binding>
|
||||||
|
<binding name="item">
|
||||||
|
<lookup name="item">GtkListItem</lookup>
|
||||||
|
</binding>
|
||||||
|
<binding name="selected">
|
||||||
|
<lookup name="selected">GtkListItem</lookup>
|
||||||
|
</binding>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<binding name="tooltip-text">
|
||||||
|
<closure type="gchararray" function="column_view_get_tooltip_text">
|
||||||
|
<lookup name="item">GtkListItem</lookup>
|
||||||
|
</closure>
|
||||||
|
</binding>
|
||||||
|
<child>
|
||||||
|
<object class="GtkFileThumbnail">
|
||||||
|
<property name="margin-start">6</property>
|
||||||
|
<property name="margin-end">6</property>
|
||||||
|
<binding name="file-info">
|
||||||
|
<lookup name="item">GtkListItem</lookup>
|
||||||
|
</binding>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkInscription">
|
||||||
|
<property name="hexpand">1</property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
<property name="min-chars">10</property>
|
||||||
|
<binding name="text">
|
||||||
|
<closure type="gchararray" function="column_view_get_file_display_name">
|
||||||
|
<lookup name="item">GtkListItem</lookup>
|
||||||
|
</closure>
|
||||||
|
</binding>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</property>
|
||||||
|
</template>
|
||||||
|
</interface>
|
||||||
|
]]></property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</property>
|
||||||
<child>
|
|
||||||
<object class="GtkCellRendererText" id="list_name_renderer">
|
|
||||||
<property name="width-chars">10</property>
|
|
||||||
<property name="ellipsize">3</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkTreeViewColumn" id="list_location_column">
|
<object class="GtkColumnViewColumn" id="column_view_location_column">
|
||||||
<property name="title" translatable="yes">Location</property>
|
<property name="title" translatable="yes">Location</property>
|
||||||
<property name="resizable">1</property>
|
<property name="resizable">1</property>
|
||||||
<property name="visible">0</property>
|
<property name="visible">0</property>
|
||||||
<property name="expand">1</property>
|
<property name="expand">1</property>
|
||||||
<child>
|
<property name="factory">
|
||||||
<object class="GtkCellRendererText" id="list_location_renderer">
|
<object class="GtkBuilderListItemFactory">
|
||||||
<property name="xalign">0</property>
|
<property name="bytes"><![CDATA[
|
||||||
<property name="width-chars">10</property>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<property name="ellipsize">1</property>
|
<interface>
|
||||||
<property name="xpad">6</property>
|
<template class="GtkListItem">
|
||||||
|
<property name="child">
|
||||||
|
<object class="GtkFileChooserCell">
|
||||||
|
<binding name="position">
|
||||||
|
<lookup name="position">GtkListItem</lookup>
|
||||||
|
</binding>
|
||||||
|
<binding name="item">
|
||||||
|
<lookup name="item">GtkListItem</lookup>
|
||||||
|
</binding>
|
||||||
|
<binding name="selected">
|
||||||
|
<lookup name="selected">GtkListItem</lookup>
|
||||||
|
</binding>
|
||||||
|
<child>
|
||||||
|
<object class="GtkInscription">
|
||||||
|
<property name="hexpand">1</property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
<property name="min-chars">10</property>
|
||||||
|
<property name="margin-start">6</property>
|
||||||
|
<property name="margin-end">6</property>
|
||||||
|
<binding name="text">
|
||||||
|
<closure type="gchararray" function="column_view_get_location">
|
||||||
|
<lookup name="item">GtkListItem</lookup>
|
||||||
|
</closure>
|
||||||
|
</binding>
|
||||||
|
<binding name="tooltip-text">
|
||||||
|
<closure type="gchararray" function="column_view_get_tooltip_text">
|
||||||
|
<lookup name="item">GtkListItem</lookup>
|
||||||
|
</closure>
|
||||||
|
</binding>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</property>
|
||||||
|
</template>
|
||||||
|
</interface>
|
||||||
|
]]></property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkTreeViewColumn" id="list_size_column">
|
<object class="GtkColumnViewColumn" id="column_view_size_column">
|
||||||
<property name="title" translatable="yes">Size</property>
|
<property name="title" translatable="yes">Size</property>
|
||||||
<property name="sizing">2</property>
|
<property name="factory">
|
||||||
<child>
|
<object class="GtkBuilderListItemFactory">
|
||||||
<object class="GtkCellRendererText" id="list_size_renderer">
|
<property name="bytes"><![CDATA[
|
||||||
<property name="xalign">0</property>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<property name="xpad">6</property>
|
<interface>
|
||||||
|
<template class="GtkListItem">
|
||||||
|
<property name="child">
|
||||||
|
<object class="GtkFileChooserCell">
|
||||||
|
<binding name="position">
|
||||||
|
<lookup name="position">GtkListItem</lookup>
|
||||||
|
</binding>
|
||||||
|
<binding name="item">
|
||||||
|
<lookup name="item">GtkListItem</lookup>
|
||||||
|
</binding>
|
||||||
|
<binding name="selected">
|
||||||
|
<lookup name="selected">GtkListItem</lookup>
|
||||||
|
</binding>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="hexpand">1</property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
<binding name="label">
|
||||||
|
<closure type="gchararray" function="column_view_get_size">
|
||||||
|
<lookup name="item">GtkListItem</lookup>
|
||||||
|
</closure>
|
||||||
|
</binding>
|
||||||
|
<binding name="tooltip-text">
|
||||||
|
<closure type="gchararray" function="column_view_get_tooltip_text">
|
||||||
|
<lookup name="item">GtkListItem</lookup>
|
||||||
|
</closure>
|
||||||
|
</binding>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</property>
|
||||||
|
</template>
|
||||||
|
</interface>
|
||||||
|
]]></property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkTreeViewColumn" id="list_type_column">
|
<object class="GtkColumnViewColumn" id="column_view_type_column">
|
||||||
<property name="title" translatable="yes">Type</property>
|
<property name="title" translatable="yes">Type</property>
|
||||||
<property name="resizable">1</property>
|
<property name="resizable">1</property>
|
||||||
<child>
|
<property name="factory">
|
||||||
<object class="GtkCellRendererText" id="list_type_renderer">
|
<object class="GtkBuilderListItemFactory">
|
||||||
<property name="xalign">0</property>
|
<property name="bytes"><![CDATA[
|
||||||
<property name="xpad">6</property>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<interface>
|
||||||
|
<template class="GtkListItem">
|
||||||
|
<property name="child">
|
||||||
|
<object class="GtkFileChooserCell">
|
||||||
|
<binding name="position">
|
||||||
|
<lookup name="position">GtkListItem</lookup>
|
||||||
|
</binding>
|
||||||
|
<binding name="item">
|
||||||
|
<lookup name="item">GtkListItem</lookup>
|
||||||
|
</binding>
|
||||||
|
<binding name="selected">
|
||||||
|
<lookup name="selected">GtkListItem</lookup>
|
||||||
|
</binding>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="hexpand">1</property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
<binding name="label">
|
||||||
|
<closure type="gchararray" function="column_view_get_file_type">
|
||||||
|
<lookup name="item">GtkListItem</lookup>
|
||||||
|
</closure>
|
||||||
|
</binding>
|
||||||
|
<binding name="tooltip-text">
|
||||||
|
<closure type="gchararray" function="column_view_get_tooltip_text">
|
||||||
|
<lookup name="item">GtkListItem</lookup>
|
||||||
|
</closure>
|
||||||
|
</binding>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</property>
|
||||||
|
</template>
|
||||||
|
</interface>
|
||||||
|
]]></property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkTreeViewColumn" id="list_time_column">
|
<object class="GtkColumnViewColumn" id="column_view_time_column">
|
||||||
<property name="title" translatable="yes">Modified</property>
|
<property name="title" translatable="yes">Modified</property>
|
||||||
<property name="sizing">2</property>
|
<property name="factory">
|
||||||
<child>
|
<object class="GtkBuilderListItemFactory">
|
||||||
<object class="GtkCellRendererText" id="list_date_renderer">
|
<property name="bytes"><![CDATA[
|
||||||
<property name="xpad">6</property>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<interface>
|
||||||
|
<template class="GtkListItem">
|
||||||
|
<property name="child">
|
||||||
|
<object class="GtkFileChooserCell" id="file_chooser_cell">
|
||||||
|
<binding name="position">
|
||||||
|
<lookup name="position">GtkListItem</lookup>
|
||||||
|
</binding>
|
||||||
|
<binding name="item">
|
||||||
|
<lookup name="item">GtkListItem</lookup>
|
||||||
|
</binding>
|
||||||
|
<binding name="selected">
|
||||||
|
<lookup name="selected">GtkListItem</lookup>
|
||||||
|
</binding>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="spacing">6</property>
|
||||||
|
<binding name="tooltip-text">
|
||||||
|
<closure type="gchararray" function="column_view_get_tooltip_text">
|
||||||
|
<lookup name="item">GtkListItem</lookup>
|
||||||
|
</closure>
|
||||||
|
</binding>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<binding name="label">
|
||||||
|
<closure type="gchararray" function="column_view_get_file_date">
|
||||||
|
<lookup name="item">GtkListItem</lookup>
|
||||||
|
</closure>
|
||||||
|
</binding>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="visible" bind-source="file_chooser_cell" bind-property="show-time" bind-flags="sync-create"/>
|
||||||
|
<binding name="label">
|
||||||
|
<closure type="gchararray" function="column_view_get_file_time">
|
||||||
|
<lookup name="item">GtkListItem</lookup>
|
||||||
|
</closure>
|
||||||
|
</binding>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</property>
|
||||||
|
</template>
|
||||||
|
</interface>
|
||||||
|
]]></property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</property>
|
||||||
<child>
|
|
||||||
<object class="GtkCellRendererText" id="list_time_renderer">
|
|
||||||
<property name="xpad">6</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
|
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
|
Loading…
Reference in New Issue
Block a user