<keycap>Enter</keycap>\r
.\r
</para>\r
+ <para>Additionally a drop-down box permits any of the file <link linkend="Filetypes">Classes</link> to be selected or deselected from the viewed list.</para>\r
<para />\r
</section>\r
<section id="Multipleselection">\r
<listitem>\r
This may be used to define sets of file types, for use in the\r
<emphasis>Grouping</emphasis>\r
- function described above. The drop-down list has 6 entries:\r
+ function described above. The drop-down list has 7 entries:\r
<itemizedlist>\r
<listitem>Unknown</listitem>\r
<listitem>Image</listitem>\r
<listitem>Metadata</listitem>\r
<listitem>Video</listitem>\r
<listitem>Collection</listitem>\r
+ <listitem>Document</listitem>\r
</itemizedlist>\r
</listitem>\r
</varlistentry>\r
return list;
}
+static gboolean file_data_filter_class(FileData *fd, guint filter)
+{
+ gint i;
+
+ for (i = 0; i < FILE_FORMAT_CLASSES; i++)
+ {
+ if (filter & (1 << i))
+ {
+ if ((FileFormatClass)i == filter_file_get_class(fd->path))
+ {
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+GList *file_data_filter_class_list(GList *list, guint filter)
+{
+ GList *work;
+
+ work = list;
+ while (work)
+ {
+ FileData *fd = work->data;
+ GList *link = work;
+ work = work->next;
+
+ if (!file_data_filter_class(fd, filter))
+ {
+ list = g_list_remove_link(list, link);
+ file_data_unref(fd);
+ g_list_free(link);
+ }
+ }
+
+ return list;
+}
+
static void file_data_notify_mark_func(gpointer key, gpointer value, gpointer user_data)
{
FileData *fd = value;
gboolean file_data_filter_file_filter(FileData *fd, GRegex *filter);
GList *file_data_filter_file_filter_list(GList *list, GRegex *filter);
+GList *file_data_filter_class_list(GList *list, guint filter);
+
gint file_data_get_user_orientation(FileData *fd);
void file_data_set_user_orientation(FileData *fd, gint value);
options->mouse_button_8 = g_strdup("Back");
options->mouse_button_9 = g_strdup("Forward");
+ for (i = 0; i < FILE_FORMAT_CLASSES; i++)
+ {
+ options->class_filter[i] = TRUE;
+ }
return options;
}
gchar *mouse_button_8;
gchar *mouse_button_9;
+ /* class file filter */
+ gboolean class_filter[FILE_FORMAT_CLASSES];
+
gboolean read_metadata_in_idle;
GList *disabled_plugins;
N_("Metadata"),
N_("Video"),
N_("Collection"),
- N_("Document"),
- N_("HEIF")
+ N_("Document")
};
/* config memory values */
WRITE_NL(); WRITE_STRING("</marks_tooltips>");
}
+static void write_class_filter(GString *outstr, gint indent)
+{
+ gint i;
+
+ WRITE_NL(); WRITE_STRING("<class_filter>");
+ indent++;
+ for (i = 0; i < FILE_FORMAT_CLASSES; i++)
+ {
+ WRITE_NL(); WRITE_STRING("<filter_type ");
+ write_char_option(outstr, indent, "filter", format_class_list[i]);
+ write_bool_option(outstr, indent, "enabled", options->class_filter[i]);
+ WRITE_STRING("/>");
+ }
+ indent--;
+ WRITE_NL(); WRITE_STRING("</class_filter>");
+}
+
static void write_disabled_plugins(GString *outstr, gint indent)
{
GtkTreeIter iter;
WRITE_SEPARATOR();
write_disabled_plugins(outstr, indent);
+ WRITE_SEPARATOR();
+ write_class_filter(outstr, indent);
+
WRITE_SEPARATOR();
keyword_tree_write_config(outstr, indent);
indent--;
}
}
+static void class_filter_load_filter_type(const gchar **attribute_names, const gchar **attribute_values)
+{
+ gint i;
+ gint index;
+
+ while (*attribute_names)
+ {
+ const gchar *option = *attribute_names++;
+ const gchar *value = *attribute_values++;
+ if (g_strcmp0("filter", option) == 0)
+ {
+ for (i = 0; i < FILE_FORMAT_CLASSES; i++)
+ {
+ if (g_strcmp0(format_class_list[i], value) == 0)
+ {
+ index = i;
+ }
+ }
+ continue;
+ }
+
+ if (READ_BOOL_FULL("enabled", options->class_filter[index]))
+ {
+ continue;
+ }
+ log_printf("unknown attribute %s = %s\n", option, value);
+ }
+}
+
+static void options_parse_class_filter(GQParserData *parser_data, GMarkupParseContext *context, const gchar *element_name, const gchar **attribute_names, const gchar **attribute_values, gpointer data, GError **error)
+{
+ if (g_ascii_strcasecmp(element_name, "filter_type") == 0)
+ {
+ class_filter_load_filter_type(attribute_names, attribute_values);
+ options_parse_func_push(parser_data, options_parse_leaf, NULL, NULL);
+ }
+ else
+ {
+ log_printf("unexpected in <profile>: <%s>\n", element_name);
+ options_parse_func_push(parser_data, options_parse_leaf, NULL, NULL);
+ }
+}
+
static void options_parse_disabled_plugins(GQParserData *parser_data, GMarkupParseContext *context, const gchar *element_name, const gchar **attribute_names, const gchar **attribute_values, gpointer data, GError **error)
{
if (g_ascii_strcasecmp(element_name, "plugin") == 0)
options_load_marks_tooltips(parser_data, context, element_name, attribute_names, attribute_values, data, error);
options_parse_func_push(parser_data, options_parse_marks_tooltips, NULL, NULL);
}
+ else if (g_ascii_strcasecmp(element_name, "class_filter") == 0)
+ {
+ options_parse_func_push(parser_data, options_parse_class_filter, NULL, NULL);
+ }
else if (g_ascii_strcasecmp(element_name, "keyword_tree") == 0)
{
if (!keyword_tree) keyword_tree_new();
FILE_FORMAT_CLASSES
} FileFormatClass;
+/* defined in preferences.c */
extern gchar *format_class_list[];
typedef enum {
guint vf_marks_get_filter(ViewFile *vf);
void vf_mark_filter_toggle(ViewFile *vf, gint mark);
+guint vf_class_get_filter(ViewFile *vf);
+
GList *vf_selection_get_one(ViewFile *vf, FileData *fd);
GList *vf_pop_menu_file_list(ViewFile *vf);
GtkWidget *vf_pop_menu(ViewFile *vf);
vf_refresh(vf);
}
+static gboolean vf_file_filter_class_cb(GtkWidget *widget, gpointer data)
+{
+ ViewFile *vf = data;
+ gint i;
+
+ gboolean state = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));
+
+ for (i = 0; i < FILE_FORMAT_CLASSES; i++)
+ {
+ if (g_strcmp0(format_class_list[i], gtk_menu_item_get_label(GTK_MENU_ITEM(widget))) == 0)
+ {
+ options->class_filter[i] = state;
+ }
+ }
+ vf_refresh(vf);
+
+ return TRUE;
+}
+
+static gboolean vf_file_filter_class_set_all_cb(GtkWidget *widget, gpointer data)
+{
+ ViewFile *vf = data;
+ GtkWidget *parent;
+ GList *children;
+ GtkWidget *child;
+ gint i;
+ gboolean state;
+
+ if (g_strcmp0("Select all", gtk_menu_item_get_label(GTK_MENU_ITEM(widget))) == 0)
+ {
+ state == TRUE;
+ }
+ else
+ {
+ state = FALSE;
+ }
+
+ for (i = 0; i < FILE_FORMAT_CLASSES; i++)
+ {
+ options->class_filter[i] = state;
+ }
+
+ i = 0;
+ parent = gtk_widget_get_parent(widget);
+ children = gtk_container_get_children(GTK_CONTAINER(parent));
+ while (children)
+ {
+ child = children->data;
+ if (i < FILE_FORMAT_CLASSES)
+ {
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(child), state);
+ }
+ i++;
+ children = children->next;
+ }
+ g_list_free(children);
+ vf_refresh(vf);
+
+ return TRUE;
+}
+
+static GtkWidget *class_filter_menu (ViewFile *vf)
+{
+ GtkWidget *menu;
+ GtkWidget *menu_item;
+ int i;
+
+ menu = gtk_menu_new();
+
+ for (i = 0; i < FILE_FORMAT_CLASSES; i++)
+ {
+ menu_item = gtk_check_menu_item_new_with_label(format_class_list[i]);
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_item), options->class_filter[i]);
+ g_signal_connect(G_OBJECT(menu_item), "toggled", G_CALLBACK(vf_file_filter_class_cb), vf);
+ gtk_menu_shell_append(GTK_MENU_SHELL (menu), menu_item);
+ gtk_widget_show(menu_item);
+ }
+
+ menu_item = gtk_menu_item_new_with_label(_("Select all"));
+ gtk_menu_shell_append(GTK_MENU_SHELL (menu), menu_item);
+ gtk_widget_show(menu_item);
+ g_signal_connect(G_OBJECT(menu_item), "activate", G_CALLBACK(vf_file_filter_class_set_all_cb), vf);
+
+ menu_item = gtk_menu_item_new_with_label(_("Select none"));
+ gtk_menu_shell_append(GTK_MENU_SHELL (menu), menu_item);
+ gtk_widget_show(menu_item);
+ g_signal_connect(G_OBJECT(menu_item), "activate", G_CALLBACK(vf_file_filter_class_set_all_cb), vf);
+
+ return menu;
+}
+
static GtkWidget *vf_file_filter_init(ViewFile *vf)
{
GtkWidget *frame = gtk_frame_new(NULL);
GList *work;
gint n = 0;
GtkWidget *combo_entry;
+ GtkWidget *menubar;
+ GtkWidget *menuitem;
vf->file_filter.combo = gtk_combo_box_text_new_with_entry();
combo_entry = gtk_bin_get_child(GTK_BIN(vf->file_filter.combo));
gtk_container_add(GTK_CONTAINER(frame), hbox);
gtk_widget_show(hbox);
+ menubar = gtk_menu_bar_new();
+ gtk_widget_set_hexpand(menubar, TRUE);
+ gtk_box_pack_start(GTK_BOX(hbox), menubar, FALSE, TRUE, 0);
+ gtk_widget_show(menubar);
+
+ menuitem = gtk_menu_item_new_with_label(_("Class"));
+ gtk_widget_set_tooltip_text(GTK_WIDGET(menuitem), _("Select Class filter"));
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM (menuitem), class_filter_menu(vf));
+ gtk_menu_shell_append(GTK_MENU_SHELL (menubar), menuitem);
+ gtk_widget_show(menuitem);
+
+ gtk_widget_show(menuitem);
+
return frame;
}
return ret;
}
+guint vf_class_get_filter(ViewFile *vf)
+{
+ guint ret = 0;
+ gint i;
+
+ if (!gtk_widget_get_visible(vf->file_filter.combo))
+ {
+ return G_MAXUINT;
+ }
+
+ for ( i = 0; i < FILE_FORMAT_CLASSES; i++)
+ {
+ if (options->class_filter[i])
+ {
+ ret |= 1 << i;
+ }
+ }
+
+ return ret;
+}
+
void vf_set_layout(ViewFile *vf, LayoutWindow *layout)
{
vf->layout = layout;
new_filelist = file_data_filter_marks_list(new_filelist, vf_marks_get_filter(vf));
new_filelist = g_list_first(new_filelist);
new_filelist = file_data_filter_file_filter_list(new_filelist, vf_file_filter_get_filter(vf));
+
+ new_filelist = g_list_first(new_filelist);
+ new_filelist = file_data_filter_class_list(new_filelist, vf_class_get_filter(vf));
+
}
vf->list = filelist_sort(vf->list, vf->sort_method, vf->sort_ascend); /* the list might not be sorted if there were renames */
vf->list = file_data_filter_marks_list(vf->list, vf_marks_get_filter(vf));
vf->list = g_list_first(vf->list);
vf->list = file_data_filter_file_filter_list(vf->list, vf_file_filter_get_filter(vf));
+
+ vf->list = g_list_first(vf->list);
+ vf->list = file_data_filter_class_list(vf->list, vf_class_get_filter(vf));
+
file_data_register_notify_func(vf_notify_cb, vf, NOTIFY_PRIORITY_MEDIUM);
DEBUG_1("%s vflist_refresh: sort", get_exec_time());