[gnome-control-center/wip/applications] first stab at formatting content types
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center/wip/applications] first stab at formatting content types
- Date: Thu, 29 Nov 2018 07:08:59 +0000 (UTC)
commit a7de3e7c4e8ee04148a8b6eb138b31477c165303
Author: Matthias Clasen <mclasen redhat com>
Date: Thu Nov 29 02:08:28 2018 -0500
first stab at formatting content types
panels/applications/cc-applications-panel.c | 497 +++++++++++++++++++++++++--
panels/applications/cc-applications-panel.ui | 57 ++-
2 files changed, 529 insertions(+), 25 deletions(-)
---
diff --git a/panels/applications/cc-applications-panel.c b/panels/applications/cc-applications-panel.c
index 8054263f8..ec60a1f3b 100644
--- a/panels/applications/cc-applications-panel.c
+++ b/panels/applications/cc-applications-panel.c
@@ -62,6 +62,8 @@ struct _CcApplicationsPanel
char *current_app_id;
+ GHashTable *globs;
+
GDBusProxy *perm_store;
GSettings *notification_settings;
GSettings *location_settings;
@@ -86,8 +88,19 @@ struct _CcApplicationsPanel
GtkWidget *device_section;
GtkWidget *device_list;
- GtkWidget *handler_section;
- GtkWidget *handler_list;
+ GtkWidget *file_type_section;
+ GtkWidget *file_type_list;
+ GtkWidget *hypertext;
+ GtkWidget *text;
+ GtkWidget *images;
+ GtkWidget *fonts;
+ GtkWidget *archives;
+ GtkWidget *packages;
+ GtkWidget *audio;
+ GtkWidget *video;
+ GtkWidget *other;
+ GtkWidget *link_type_section;
+ GtkWidget *link_type_list;
GtkWidget *storage_section;
GtkWidget *storage_list;
GtkWidget *app;
@@ -120,6 +133,7 @@ cc_applications_panel_finalize (GObject *object)
g_clear_object (&self->cancellable);
g_free (self->current_app_id);
+ g_hash_table_unref (self->globs);
G_OBJECT_CLASS (cc_applications_panel_parent_class)->finalize (object);
}
@@ -665,38 +679,441 @@ update_device_section (CcApplicationsPanel *self,
}
static void
-add_handler_row (CcApplicationsPanel *self,
- GAppInfo *info,
- const char *type)
+add_link_type_row (CcApplicationsPanel *self,
+ const char *type)
+{
+ CcActionRow *row = NULL;
+
+ if (g_str_has_suffix (type, "http"))
+ {
+ row = cc_action_row_new ();
+ cc_action_row_set_title (row, _("Web Links"));
+ cc_action_row_set_subtitle (row, "http://, https://");
+ cc_action_row_set_action (row, _("Unset"), FALSE);
+ }
+ else if (g_str_has_suffix (type, "https"))
+ {
+ return; /* assume anything that handles https also handles http */
+ }
+ else if (g_str_has_suffix (type, "git"))
+ {
+ row = cc_action_row_new ();
+ cc_action_row_set_title (row, _("Git Links"));
+ cc_action_row_set_subtitle (row, "git://");
+ cc_action_row_set_action (row, _("Unset"), FALSE);
+ }
+ else
+ {
+ char *scheme = strrchr (type, '/') + 1;
+ g_autofree char *title = g_strdup_printf (_("%s Links"), scheme);
+ g_autofree char *subtitle = g_strdup_printf ("%s://", scheme);
+
+ row = cc_action_row_new ();
+ cc_action_row_set_title (row, title);
+ cc_action_row_set_subtitle (row, subtitle);
+ cc_action_row_set_action (row, _("Unset"), FALSE);
+ }
+
+ gtk_list_box_insert (GTK_LIST_BOX (self->link_type_list), GTK_WIDGET (row), -1);
+ gtk_widget_show (self->link_type_section);
+}
+
+static void
+add_file_type (CcApplicationsPanel *self,
+ GtkListBoxRow *after,
+ const char *type)
{
- g_autofree char *desc = NULL;
CcActionRow *row;
+ const char *desc;
+ int pos;
+ const char *glob;
+
+ glob = g_hash_table_lookup (self->globs, type);
desc = g_content_type_get_description (type);
row = cc_action_row_new ();
cc_action_row_set_title (row, desc);
+ cc_action_row_set_subtitle (row, glob ? glob : "");
cc_action_row_set_action (row, _("Remove"), FALSE);
- gtk_list_box_insert (GTK_LIST_BOX (self->handler_list), GTK_WIDGET (row), -1);
+ if (after)
+ {
+ pos = gtk_list_box_row_get_index (after) + 1;
+ g_object_bind_property (after, "expanded",
+ row, "visible",
+ G_BINDING_SYNC_CREATE);
+ }
+ else
+ pos = -1;
+ gtk_list_box_insert (GTK_LIST_BOX (self->file_type_list), GTK_WIDGET (row), pos);
+}
+
+static gboolean
+is_hypertext_type (const char *type)
+{
+ const char *types[] = {
+ "text/html",
+ "text/htmlh",
+ "text/xml",
+ "application/xhtml+xml",
+ "application/vnd.mozilla.xul+xml",
+ "text/mml",
+ NULL
+ };
+ return g_strv_contains (types, type);
}
static void
-update_handler_section (CcApplicationsPanel *self,
- GAppInfo *info)
+add_hypertext_type (CcApplicationsPanel *self,
+ const char *type)
+{
+ g_autofree char *types = NULL;
+ g_autofree char *ntypes = NULL;
+
+ if (!self->hypertext)
+ {
+ CcInfoRow *row = CC_INFO_ROW (g_object_new (CC_TYPE_INFO_ROW,
+ "title", _("Hypertext Files"),
+ "has-expander", TRUE,
+ NULL));
+ gtk_list_box_insert (GTK_LIST_BOX (self->file_type_list), GTK_WIDGET (row), -1);
+ self->hypertext = GTK_WIDGET (row);
+ }
+ add_file_type (self, self->hypertext, type);
+}
+
+static gboolean
+is_text_type (const char *type)
+{
+ return g_content_type_is_a (type, "text/*");
+}
+
+static void
+add_text_type (CcApplicationsPanel *self,
+ const char *type)
+{
+ g_autofree char *types = NULL;
+ g_autofree char *ntypes = NULL;
+
+ if (!self->text)
+ {
+ CcInfoRow *row = CC_INFO_ROW (g_object_new (CC_TYPE_INFO_ROW,
+ "title", _("Text Files"),
+ "has-expander", TRUE,
+ NULL));
+ gtk_list_box_insert (GTK_LIST_BOX (self->file_type_list), GTK_WIDGET (row), -1);
+ self->text = GTK_WIDGET (row);
+ }
+ add_file_type (self, self->text, type);
+}
+
+static gboolean
+is_image_type (const char *type)
+{
+ return g_content_type_is_a (type, "image/*");
+}
+
+static void
+add_image_type (CcApplicationsPanel *self,
+ const char *type)
+{
+ g_autofree char *types = NULL;
+ g_autofree char *ntypes = NULL;
+
+ if (!self->images)
+ {
+ CcInfoRow *row = CC_INFO_ROW (g_object_new (CC_TYPE_INFO_ROW,
+ "title", _("Image Files"),
+ "has-expander", TRUE,
+ NULL));
+ gtk_list_box_insert (GTK_LIST_BOX (self->file_type_list), GTK_WIDGET (row), -1);
+ self->images = GTK_WIDGET (row);
+ }
+ add_file_type (self, self->images, type);
+}
+
+static gboolean
+is_font_type (const char *type)
+{
+ return g_content_type_is_a (type, "font/*") ||
+ g_str_equal (type, "application/x-font-pcf") ||
+ g_str_equal (type, "application/x-font-type1");
+}
+
+static void
+add_font_type (CcApplicationsPanel *self,
+ const char *type)
+{
+ g_autofree char *types = NULL;
+ g_autofree char *ntypes = NULL;
+
+ if (!self->fonts)
+ {
+ CcInfoRow *row = CC_INFO_ROW (g_object_new (CC_TYPE_INFO_ROW,
+ "title", _("Font Files"),
+ "has-expander", TRUE,
+ NULL));
+ gtk_list_box_insert (GTK_LIST_BOX (self->file_type_list), GTK_WIDGET (row), -1);
+ self->fonts = GTK_WIDGET (row);
+ }
+ add_file_type (self, self->fonts, type);
+}
+
+static gboolean
+is_archive_type (const char *type)
+{
+ const char *types[] = {
+ "application/bzip2",
+ "application/zip",
+ "application/x-xz-compressed-tar",
+ "application/x-xz",
+ "application/x-xar",
+ "application/x-tarz",
+ "application/x-tar",
+ "application/x-lzma-compressed-tar",
+ "application/x-lzma",
+ "application/x-lzip-compressed-tar",
+ "application/x-lzip",
+ "application/x-lha",
+ "application/gzip",
+ "application/x-cpio",
+ "application/x-compressed-tar",
+ "application/x-compress",
+ "application/x-bzip-compressed-tar",
+ "application/x-bzip",
+ "application/x-7z-compressed-tar",
+ "application/x-7z-compressed",
+ "application/x-zoo",
+ "application/x-war",
+ "application/x-stuffit",
+ "application/x-rzip-compressed-tar",
+ "application/x-rzip",
+ "application/vnd.rar",
+ "application/x-lzop-compressed-tar",
+ "application/x-lzop",
+ "application/x-lz4-compressed-tar",
+ "application/x-lz4",
+ "application/x-lrzip-compressed-tar",
+ "application/x-lrzip",
+ "application/x-lhz",
+ "application/x-java-archive",
+ "application/x-ear",
+ "application/x-cabinet",
+ "application/x-bzip1-compressed-tar",
+ "application/x-bzip1",
+ "application/x-arj",
+ "application/x-archive",
+ "application/x-ar",
+ "application/x-alz",
+ "application/x-ace",
+ "application/vnd.ms-cab-compressed",
+ NULL
+ };
+ return g_strv_contains (types, type);
+}
+
+static void
+add_archive_type (CcApplicationsPanel *self,
+ const char *type)
+{
+ g_autofree char *types = NULL;
+ g_autofree char *ntypes = NULL;
+
+ if (!self->archives)
+ {
+ CcInfoRow *row = CC_INFO_ROW (g_object_new (CC_TYPE_INFO_ROW,
+ "title", _("Archive Files"),
+ "has-expander", TRUE,
+ NULL));
+ gtk_list_box_insert (GTK_LIST_BOX (self->file_type_list), GTK_WIDGET (row), -1);
+ self->archives = GTK_WIDGET (row);
+ }
+ add_file_type (self, self->archives, type);
+}
+
+static gboolean
+is_package_type (const char *type)
+{
+ const char *types[] = {
+ "application/x-source-rpm",
+ "application/x-rpm",
+ "application/vnd.debian.binary-package",
+ NULL
+ };
+ return g_strv_contains (types, type);
+}
+
+static void
+add_package_type (CcApplicationsPanel *self,
+ const char *type)
+{
+ g_autofree char *types = NULL;
+ g_autofree char *ntypes = NULL;
+
+ if (!self->packages)
+ {
+ CcInfoRow *row = CC_INFO_ROW (g_object_new (CC_TYPE_INFO_ROW,
+ "title", _("Software packages"),
+ "has-expander", TRUE,
+ NULL));
+ gtk_list_box_insert (GTK_LIST_BOX (self->file_type_list), GTK_WIDGET (row), -1);
+ self->packages = GTK_WIDGET (row);
+ }
+ add_file_type (self, self->packages, type);
+}
+
+static gboolean
+is_audio_type (const char *type)
+{
+ return g_content_type_is_a (type, "audio/*") ||
+ g_str_equal (type, "application/ogg") ||
+ g_str_equal (type, "application/x-shorten") ||
+ g_str_equal (type, "application/x-matroska") ||
+ g_str_equal (type, "application/x-flac") ||
+ g_str_equal (type, "application/x-extension-mp4") ||
+ g_str_equal (type, "application/x-extension-m4a") ||
+ g_str_equal (type, "application/vnd.rn-realmedia") ||
+ g_str_equal (type, "application/ram") ||
+ g_str_equal (type, "application/vnd.ms-wpl");
+}
+
+static void
+add_audio_type (CcApplicationsPanel *self,
+ const char *type)
+{
+ g_autofree char *types = NULL;
+ g_autofree char *ntypes = NULL;
+
+ if (!self->audio)
+ {
+ CcInfoRow *row = CC_INFO_ROW (g_object_new (CC_TYPE_INFO_ROW,
+ "title", _("Audio Files"),
+ "has-expander", TRUE,
+ NULL));
+ gtk_list_box_insert (GTK_LIST_BOX (self->file_type_list), GTK_WIDGET (row), -1);
+ self->audio = GTK_WIDGET (row);
+ }
+ add_file_type (self, self->audio, type);
+}
+
+static gboolean
+is_video_type (const char *type)
+{
+ return g_content_type_is_a (type, "video/*") ||
+ g_str_equal (type, "application/x-smil") ||
+ g_str_equal (type, "application/vnd.ms-asf") ||
+ g_str_equal (type, "application/mxf");
+}
+
+static void
+add_video_type (CcApplicationsPanel *self,
+ const char *type)
+{
+ g_autofree char *types = NULL;
+ g_autofree char *ntypes = NULL;
+
+ if (!self->video)
+ {
+ CcInfoRow *row = CC_INFO_ROW (g_object_new (CC_TYPE_INFO_ROW,
+ "title", _("Video Files"),
+ "has-expander", TRUE,
+ NULL));
+ gtk_list_box_insert (GTK_LIST_BOX (self->file_type_list), GTK_WIDGET (row), -1);
+ self->video = GTK_WIDGET (row);
+ }
+ add_file_type (self, self->video, type);
+}
+
+static void
+add_other_type (CcApplicationsPanel *self,
+ const char *type)
+{
+ g_autofree char *types = NULL;
+ g_autofree char *ntypes = NULL;
+
+ if (!self->other)
+ {
+ CcInfoRow *row = CC_INFO_ROW (g_object_new (CC_TYPE_INFO_ROW,
+ "title", _("Other Files"),
+ "has-expander", TRUE,
+ NULL));
+ gtk_list_box_insert (GTK_LIST_BOX (self->file_type_list), GTK_WIDGET (row), -1);
+ self->other = GTK_WIDGET (row);
+ }
+ add_file_type (self, self->other, type);
+}
+
+static void
+add_file_type_row (CcApplicationsPanel *self,
+ const char *type)
+{
+ gtk_widget_show (self->file_type_section);
+
+ if (is_hypertext_type (type))
+ add_hypertext_type (self, type);
+ else if (is_font_type (type))
+ add_font_type (self, type);
+ else if (is_package_type (type))
+ add_package_type (self, type);
+ else if (is_audio_type (type))
+ add_audio_type (self, type);
+ else if (is_video_type (type))
+ add_video_type (self, type);
+ else if (is_archive_type (type))
+ add_archive_type (self, type);
+ else if (is_text_type (type))
+ add_text_type (self, type);
+ else if (is_image_type (type))
+ add_image_type (self, type);
+ else
+ add_other_type (self, type);
+}
+
+static void
+file_type_row_activated_cb (GtkListBox *list,
+ GtkListBoxRow *list_row,
+ CcApplicationsPanel *self)
+{
+ GtkWidget *row = GTK_WIDGET (list_row);
+
+ if (row == self->hypertext ||
+ row == self->text ||
+ row == self->images ||
+ row == self->fonts ||
+ row == self->archives ||
+ row == self->packages ||
+ row == self->audio ||
+ row == self->video ||
+ row == self->other)
+ cc_info_row_set_expanded (CC_INFO_ROW (row),
+ !cc_info_row_get_expanded (CC_INFO_ROW (row)));
+}
+static void
+update_handler_sections (CcApplicationsPanel *self,
+ GAppInfo *info)
{
const char **types;
int i;
g_autoptr(GHashTable) hash = NULL;
- container_remove_all (GTK_CONTAINER (self->handler_list));
+ container_remove_all (GTK_CONTAINER (self->file_type_list));
+ container_remove_all (GTK_CONTAINER (self->link_type_list));
+
+ self->hypertext = NULL;
+ self->text = NULL;
+ self->images = NULL;
+ self->fonts = NULL;
+ self->archives = NULL;
+ self->packages = NULL;
+ self->audio = NULL;
+ self->video = NULL;
+ self->other = NULL;
+
+ gtk_widget_hide (self->file_type_section);
+ gtk_widget_hide (self->link_type_section);
types = g_app_info_get_supported_types (info);
if (types == NULL || types[0] == NULL)
- {
- gtk_widget_hide (self->handler_section);
- return;
- }
-
- gtk_widget_show (self->handler_section);
+ return;
hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
@@ -709,7 +1126,10 @@ update_handler_section (CcApplicationsPanel *self,
continue;
}
g_hash_table_add (hash, ctype);
- add_handler_row (self, info, ctype);
+ if (g_content_type_is_a (ctype, "x-scheme-handler/*"))
+ add_link_type_row (self, ctype);
+ else
+ add_file_type_row (self, ctype);
}
}
@@ -761,7 +1181,7 @@ update_panel (CcApplicationsPanel *self)
update_permission_section (self, info);
update_information_section (self, info);
update_device_section (self, info);
- update_handler_section (self, info);
+ update_handler_sections (self, info);
update_storage_section (self, info);
self->current_app_id = get_app_id (info);
@@ -802,7 +1222,11 @@ prepare_content (CcApplicationsPanel *self)
cc_list_box_update_header_func,
NULL, NULL);
- gtk_list_box_set_header_func (GTK_LIST_BOX (self->handler_list),
+ gtk_list_box_set_header_func (GTK_LIST_BOX (self->file_type_list),
+ cc_list_box_update_header_func,
+ NULL, NULL);
+
+ gtk_list_box_set_header_func (GTK_LIST_BOX (self->link_type_list),
cc_list_box_update_header_func,
NULL, NULL);
@@ -931,6 +1355,32 @@ cc_applications_panel_set_property (GObject *object,
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
+static void
+parse_globs (CcApplicationsPanel *self)
+{
+ g_autofree char *contents = NULL;
+
+ self->globs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+
+ if (g_file_get_contents ("/usr/share/mime/globs", &contents, NULL, NULL))
+ {
+ g_auto(GStrv) strv = NULL;
+ int i;
+
+ strv = g_strsplit (contents, "\n", 0);
+ for (i = 0; strv[i]; i++)
+ {
+ g_auto(GStrv) parts = NULL;
+
+ if (strv[i][0] == '#' || strv[i][0] == '\0')
+ continue;
+
+ parts = g_strsplit (strv[i], ":", 2);
+ g_hash_table_insert (self->globs, g_strdup (parts[0]), g_strdup (parts[1]));
+ }
+ }
+}
+
static void
cc_applications_panel_class_init (CcApplicationsPanelClass *klass)
{
@@ -969,8 +1419,10 @@ cc_applications_panel_class_init (CcApplicationsPanelClass *klass)
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, builtin);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, device_section);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, device_list);
- gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, handler_section);
- gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, handler_list);
+ gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, file_type_section);
+ gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, file_type_list);
+ gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, link_type_section);
+ gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, link_type_list);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, storage_section);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, storage_list);
gtk_widget_class_bind_template_child (widget_class, CcApplicationsPanel, app);
@@ -984,6 +1436,7 @@ cc_applications_panel_class_init (CcApplicationsPanelClass *klass)
gtk_widget_class_bind_template_callback (widget_class, privacy_link_cb);
gtk_widget_class_bind_template_callback (widget_class, sound_cb);
gtk_widget_class_bind_template_callback (widget_class, permission_row_activated_cb);
+ gtk_widget_class_bind_template_callback (widget_class, file_type_row_activated_cb);
gtk_widget_class_bind_template_callback (widget_class, clear_cb);
gtk_widget_class_bind_template_callback (widget_class, uninstall_cb);
}
@@ -1029,4 +1482,6 @@ cc_applications_panel_init (CcApplicationsPanel *self)
self->cancellable,
on_perm_store_ready,
self);
+
+ parse_globs (self);
}
diff --git a/panels/applications/cc-applications-panel.ui b/panels/applications/cc-applications-panel.ui
index 71f9f8f52..c566053b9 100644
--- a/panels/applications/cc-applications-panel.ui
+++ b/panels/applications/cc-applications-panel.ui
@@ -246,7 +246,7 @@
</object>
</child>
<child>
- <object class="GtkBox" id="handler_section">
+ <object class="GtkBox" id="file_type_section">
<property name="visible">1</property>
<property name="orientation">vertical</property>
<property name="spacing">12</property>
@@ -262,7 +262,7 @@
<object class="GtkLabel">
<property name="visible">1</property>
<property name="xalign">0</property>
- <property name="label" translatable="yes">Default Handler</property>
+ <property name="label" translatable="yes">File Associations</property>
<style>
<class name="section-title"/>
</style>
@@ -272,7 +272,7 @@
<object class="GtkLabel">
<property name="visible">1</property>
<property name="xalign">0</property>
- <property name="label" translatable="yes">Links and Files that are opened by
this application</property>
+ <property name="label" translatable="yes">The types of files that this
application opens.</property>
<style>
<class name="section-subtitle"/>
</style>
@@ -281,9 +281,10 @@
</object>
</child>
<child>
- <object class="GtkListBox" id="handler_list">
+ <object class="GtkListBox" id="file_type_list">
<property name="visible">1</property>
<property name="selection-mode">none</property>
+ <signal name="row-activated" handler="file_type_row_activated_cb"/>
<style>
<class name="view"/>
<class name="frame"/>
@@ -292,6 +293,54 @@
</child>
</object>
</child>
+ <child>
+ <object class="GtkBox" id="link_type_section">
+ <property name="visible">1</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <style>
+ <class name="section"/>
+ </style>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">1</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">1</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Link Associations</property>
+ <style>
+ <class name="section-title"/>
+ </style>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">1</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">The types of links that this
application opens.</property>
+ <style>
+ <class name="section-subtitle"/>
+ </style>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkListBox" id="link_type_list">
+ <property name="visible">1</property>
+ <property name="selection-mode">none</property>
+ <style>
+ <class name="view"/>
+ <class name="frame"/>
+ </style>
+ </object>
+ </child>
+ </object>
+ </child>
+FOO
<child>
<object class="GtkBox" id="storage_section">
<property name="visible">1</property>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]