Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Librem5
pureos-store
Commits
8e83ad51
Commit
8e83ad51
authored
Sep 02, 2013
by
Richard Hughes
Browse files
Use the AppStream data to populate the category tree
parent
e62a17be
Changes
8
Hide whitespace changes
Inline
Side-by-side
src/gs-plugin-loader.c
View file @
8e83ad51
...
...
@@ -359,6 +359,7 @@ typedef struct {
GSimpleAsyncResult
*
res
;
GsPluginLoader
*
plugin_loader
;
gchar
*
value
;
GsCategory
*
category
;
}
GsPluginLoaderAsyncState
;
/******************************************************************************/
...
...
@@ -1155,7 +1156,7 @@ cd_plugin_loader_get_category_apps_thread_cb (GSimpleAsyncResult *res,
GsPluginLoaderAsyncState
*
state
=
(
GsPluginLoaderAsyncState
*
)
g_object_get_data
(
G_OBJECT
(
cancellable
),
"state"
);
GsPluginLoader
*
plugin_loader
=
GS_PLUGIN_LOADER
(
object
);
GsPlugin
*
plugin
;
GsPlugin
Search
Func
plugin_func
=
NULL
;
GsPlugin
Category
Func
plugin_func
=
NULL
;
guint
i
;
/* run each plugin */
...
...
@@ -1178,7 +1179,7 @@ cd_plugin_loader_get_category_apps_thread_cb (GSimpleAsyncResult *res,
g_debug
(
"run %s on %s"
,
function_name
,
g_module_name
(
plugin
->
module
));
g_timer_start
(
plugin
->
timer
);
ret
=
plugin_func
(
plugin
,
state
->
value
,
&
state
->
list
,
cancellable
,
&
error
);
ret
=
plugin_func
(
plugin
,
state
->
category
,
&
state
->
list
,
cancellable
,
&
error
);
if
(
!
ret
)
{
cd_plugin_loader_get_all_state_finish
(
state
,
error
);
g_error_free
(
error
);
...
...
@@ -1220,6 +1221,7 @@ cd_plugin_loader_get_category_apps_thread_cb (GSimpleAsyncResult *res,
/* success */
state
->
ret
=
TRUE
;
g_object_unref
(
state
->
category
);
cd_plugin_loader_get_all_state_finish
(
state
,
NULL
);
out:
return
;
...
...
@@ -1248,7 +1250,7 @@ gs_plugin_loader_get_category_apps_async (GsPluginLoader *plugin_loader,
user_data
,
gs_plugin_loader_get_category_apps_async
);
state
->
plugin_loader
=
g_object_ref
(
plugin_loader
);
state
->
value
=
g_strdup
(
gs_category_get_id
(
category
)
)
;
state
->
category
=
g_object_ref
(
category
);
if
(
cancellable
!=
NULL
)
state
->
cancellable
=
g_object_ref
(
cancellable
);
...
...
src/gs-plugin.h
View file @
8e83ad51
...
...
@@ -81,6 +81,11 @@ typedef gboolean (*GsPluginSearchFunc) (GsPlugin *plugin,
GList
**
list
,
GCancellable
*
cancellable
,
GError
**
error
);
typedef
gboolean
(
*
GsPluginCategoryFunc
)
(
GsPlugin
*
plugin
,
GsCategory
*
category
,
GList
**
list
,
GCancellable
*
cancellable
,
GError
**
error
);
typedef
gboolean
(
*
GsPluginResultsFunc
)
(
GsPlugin
*
plugin
,
GList
**
list
,
GCancellable
*
cancellable
,
...
...
@@ -122,7 +127,7 @@ gboolean gs_plugin_add_categories (GsPlugin *plugin,
GCancellable
*
cancellable
,
GError
**
error
);
gboolean
gs_plugin_add_category_apps
(
GsPlugin
*
plugin
,
const
gchar
*
id
,
GsCategory
*
category
,
GList
**
list
,
GCancellable
*
cancellable
,
GError
**
error
);
...
...
src/gs-shell-category.c
View file @
8e83ad51
...
...
@@ -28,7 +28,9 @@
#include
"gs-shell-category.h"
struct
GsShellCategoryPrivate
{
GsPluginLoader
*
plugin_loader
;
GtkBuilder
*
builder
;
GCancellable
*
cancellable
;
GsShell
*
shell
;
GsCategory
*
category
;
};
...
...
@@ -46,7 +48,7 @@ gs_shell_category_refresh (GsShellCategory *shell)
gtk_widget_show
(
widget
);
widget
=
GTK_WIDGET
(
gtk_builder_get_object
(
priv
->
builder
,
"application_details_header"
));
gtk_widget_show
(
widget
);
category
=
priv
->
category
;
category
=
g_object_ref
(
priv
->
category
)
;
if
(
gs_category_get_parent
(
category
))
category
=
gs_category_get_parent
(
category
);
gtk_label_set_label
(
GTK_LABEL
(
widget
),
gs_category_get_name
(
category
));
...
...
@@ -104,14 +106,54 @@ create_app_tile (GsShellCategory *shell, GsApp *app)
return
button
;
}
/**
* gs_shell_category_get_apps_cb:
**/
static
void
gs_shell_category_get_apps_cb
(
GObject
*
source_object
,
GAsyncResult
*
res
,
gpointer
user_data
)
{
GError
*
error
=
NULL
;
gint
i
=
0
;
GList
*
l
;
GList
*
list
;
GsApp
*
app
;
GtkWidget
*
grid
;
GtkWidget
*
tile
;
GsShellCategory
*
shell
=
GS_SHELL_CATEGORY
(
user_data
);
GsShellCategoryPrivate
*
priv
=
shell
->
priv
;
GsPluginLoader
*
plugin_loader
=
GS_PLUGIN_LOADER
(
source_object
);
list
=
gs_plugin_loader_get_category_apps_finish
(
plugin_loader
,
res
,
&
error
);
if
(
list
==
NULL
)
{
g_warning
(
"failed to get apps for category apps: %s"
,
error
->
message
);
g_error_free
(
error
);
goto
out
;
}
grid
=
GTK_WIDGET
(
gtk_builder_get_object
(
priv
->
builder
,
"category_detail_grid"
));
for
(
l
=
list
;
l
!=
NULL
;
l
=
l
->
next
)
{
app
=
GS_APP
(
l
->
data
);
tile
=
create_app_tile
(
shell
,
app
);
if
(
gs_category_get_parent
(
priv
->
category
)
!=
NULL
)
gtk_grid_attach
(
GTK_GRID
(
grid
),
tile
,
1
+
(
i
%
2
),
i
/
2
,
1
,
1
);
else
gtk_grid_attach
(
GTK_GRID
(
grid
),
tile
,
i
%
3
,
i
/
3
,
1
,
1
);
i
++
;
}
out:
g_list_free
(
list
);
}
static
void
gs_shell_category_populate_filtered
(
GsShellCategory
*
shell
,
GsCategory
*
category
)
{
GsShellCategoryPrivate
*
priv
=
shell
->
priv
;
gint
i
;
GtkWidget
*
tile
;
GsApp
*
app
;
GtkWidget
*
grid
;
GsCategory
*
parent
;
grid
=
GTK_WIDGET
(
gtk_builder_get_object
(
priv
->
builder
,
"category_detail_grid"
));
gtk_grid_remove_column
(
GTK_GRID
(
grid
),
2
);
...
...
@@ -119,24 +161,20 @@ gs_shell_category_populate_filtered (GsShellCategory *shell, GsCategory *categor
if
(
!
category
)
gtk_grid_remove_column
(
GTK_GRID
(
grid
),
0
);
/* FIXME load apps for this category and filter */
app
=
gs_app_new
(
"gnome-boxes"
);
gs_app_set_name
(
app
,
"Boxes"
);
gs_app_set_summary
(
app
,
"View and use virtual machines"
);
gs_app_set_url
(
app
,
"http://www.box.org"
);
gs_app_set_kind
(
app
,
GS_APP_KIND_NORMAL
);
gs_app_set_state
(
app
,
GS_APP_STATE_AVAILABLE
);
gs_app_set_pixbuf
(
app
,
gdk_pixbuf_new_from_file
(
"/usr/share/icons/hicolor/48x48/apps/gnome-boxes.png"
,
NULL
));
for
(
i
=
0
;
i
<
30
;
i
++
)
{
tile
=
create_app_tile
(
shell
,
app
);
if
(
category
)
gtk_grid_attach
(
GTK_GRID
(
grid
),
tile
,
1
+
(
i
%
2
),
i
/
2
,
1
,
1
);
else
gtk_grid_attach
(
GTK_GRID
(
grid
),
tile
,
i
%
3
,
i
/
3
,
1
,
1
);
parent
=
gs_category_get_parent
(
category
);
if
(
parent
==
NULL
)
{
g_debug
(
"search using %s"
,
gs_category_get_id
(
category
));
}
else
{
g_debug
(
"search using %s/%s"
,
gs_category_get_id
(
parent
),
gs_category_get_id
(
category
));
}
g_object_unref
(
app
);
gs_plugin_loader_get_category_apps_async
(
priv
->
plugin_loader
,
category
,
priv
->
cancellable
,
gs_shell_category_get_apps_cb
,
shell
);
}
static
void
...
...
@@ -211,32 +249,37 @@ gs_shell_category_create_filter_list (GsShellCategory *shell, GsCategory *catego
void
gs_shell_category_set_category
(
GsShellCategory
*
shell
,
GsCategory
*
category
)
{
GsShellCategoryPrivate
*
priv
=
shell
->
priv
;
GsCategory
*
parent
,
*
sub
;
GsShellCategoryPrivate
*
priv
=
shell
->
priv
;
GsCategory
*
sub
;
GsCategory
*
selected
=
NULL
;
GList
*
list
;
GList
*
l
;
if
(
gs_category_get_parent
(
category
))
{
parent
=
gs_category_get_parent
(
category
)
;
sub
=
category
;
}
else
{
parent
=
category
;
sub
=
NULL
;
list
=
gs_category_get_subcategories
(
category
);
if
(
list
)
{
s
ub
=
GS_CATEGORY
(
list
->
data
)
;
g_list_free
(
list
)
;
/* this means we've come from the app-view -> back */
if
(
gs_category_get_parent
(
category
)
!=
NULL
)
return
;
/* select favourites by default */
list
=
gs_category_get_subcategories
(
category
)
;
for
(
l
=
list
;
l
!=
NULL
;
l
=
l
->
next
)
{
sub
=
GS_CATEGORY
(
l
->
data
);
if
(
g_strcmp0
(
gs_category_get_id
(
sub
),
"favourites"
)
==
0
)
{
s
elected
=
sub
;
break
;
}
}
/* okay, no favourites, so just select the first entry */
if
(
selected
==
NULL
&&
list
!=
NULL
)
selected
=
GS_CATEGORY
(
list
->
data
);
/* save this */
g_clear_object
(
&
priv
->
category
);
if
(
sub
)
priv
->
category
=
g_object_ref
(
sub
);
else
priv
->
category
=
g_object_ref
(
parent
);
priv
->
category
=
g_object_ref
(
selected
);
gs_shell_category_create_filter_list
(
shell
,
parent
,
sub
);
gs_shell_category_populate_filtered
(
shell
,
sub
);
/* find apps in this group */
gs_shell_category_create_filter_list
(
shell
,
category
,
selected
);
g_list_free
(
list
);
}
GsCategory
*
...
...
@@ -259,6 +302,8 @@ gs_shell_category_finalize (GObject *object)
g_clear_object
(
&
priv
->
builder
);
g_clear_object
(
&
priv
->
category
);
g_clear_object
(
&
priv
->
plugin_loader
);
g_clear_object
(
&
priv
->
cancellable
);
G_OBJECT_CLASS
(
gs_shell_category_parent_class
)
->
finalize
(
object
);
}
...
...
@@ -274,11 +319,17 @@ gs_shell_category_class_init (GsShellCategoryClass *klass)
}
void
gs_shell_category_setup
(
GsShellCategory
*
shell_category
,
GsShell
*
shell
,
GtkBuilder
*
builder
)
gs_shell_category_setup
(
GsShellCategory
*
shell_category
,
GsShell
*
shell
,
GsPluginLoader
*
plugin_loader
,
GtkBuilder
*
builder
,
GCancellable
*
cancellable
)
{
GsShellCategoryPrivate
*
priv
=
shell_category
->
priv
;
priv
->
plugin_loader
=
g_object_ref
(
plugin_loader
);
priv
->
builder
=
g_object_ref
(
builder
);
priv
->
cancellable
=
g_object_ref
(
cancellable
);
priv
->
shell
=
shell
;
}
...
...
src/gs-shell-category.h
View file @
8e83ad51
...
...
@@ -60,6 +60,8 @@ GsCategory *gs_shell_category_get_category (GsShellCategory *shell_category
void
gs_shell_category_refresh
(
GsShellCategory
*
shell_category
);
void
gs_shell_category_setup
(
GsShellCategory
*
shell_category
,
GsShell
*
shell
,
GtkBuilder
*
builder
);
GsPluginLoader
*
plugin_loader
,
GtkBuilder
*
builder
,
GCancellable
*
cancellable
);
#endif
/* __GS_SHELL_CATEGORY_H */
src/gs-shell-overview.c
View file @
8e83ad51
...
...
@@ -312,9 +312,9 @@ gs_shell_overview_get_categories_cb (GObject *source_object,
GtkWidget
*
grid
;
GtkWidget
*
tile
;
list
=
gs_plugin_loader_get_
featured
_finish
(
plugin_loader
,
res
,
&
error
);
list
=
gs_plugin_loader_get_
categories
_finish
(
plugin_loader
,
res
,
&
error
);
if
(
list
==
NULL
)
{
g_warning
(
"failed to get categories: %s"
,
error
->
message
);
g_error_free
(
error
);
...
...
src/gs-shell.c
View file @
8e83ad51
...
...
@@ -431,7 +431,9 @@ gs_shell_setup (GsShell *shell, GsPluginLoader *plugin_loader, GCancellable *can
priv
->
cancellable
);
gs_shell_category_setup
(
priv
->
shell_category
,
shell
,
priv
->
builder
);
priv
->
plugin_loader
,
priv
->
builder
,
priv
->
cancellable
);
/* set up search */
widget
=
GTK_WIDGET
(
gtk_builder_get_object
(
priv
->
builder
,
"entry_search"
));
...
...
src/plugins/gs-plugin-appstream.c
View file @
8e83ad51
...
...
@@ -45,6 +45,7 @@ typedef struct {
gchar
*
name
;
gchar
*
summary
;
gchar
*
icon
;
GPtrArray
*
appcategories
;
}
GsAppstreamItem
;
struct
GsPluginPrivate
{
...
...
@@ -69,6 +70,7 @@ gs_appstream_item_free (gpointer data)
g_free
(
item
->
name
);
g_free
(
item
->
summary
);
g_free
(
item
->
icon
);
g_ptr_array_unref
(
item
->
appcategories
);
g_free
(
item
);
}
...
...
@@ -241,6 +243,7 @@ gs_appstream_start_element_cb (GMarkupParseContext *context,
return
;
}
plugin
->
priv
->
item_temp
=
g_new0
(
GsAppstreamItem
,
1
);
plugin
->
priv
->
item_temp
->
appcategories
=
g_ptr_array_new_with_free_func
(
g_free
);
break
;
case
GS_APPSTREAM_XML_SECTION_ID
:
case
GS_APPSTREAM_XML_SECTION_PKGNAME
:
...
...
@@ -328,9 +331,19 @@ gs_appstream_text_cb (GMarkupParseContext *context,
case
GS_APPSTREAM_XML_SECTION_APPLICATIONS
:
case
GS_APPSTREAM_XML_SECTION_APPLICATION
:
case
GS_APPSTREAM_XML_SECTION_APPCATEGORIES
:
case
GS_APPSTREAM_XML_SECTION_APPCATEGORY
:
/* ignore */
break
;
case
GS_APPSTREAM_XML_SECTION_APPCATEGORY
:
if
(
plugin
->
priv
->
item_temp
==
NULL
)
{
g_set_error_literal
(
error
,
GS_PLUGIN_ERROR
,
GS_PLUGIN_ERROR_FAILED
,
"item_temp category invalid"
);
return
;
}
g_ptr_array_add
(
plugin
->
priv
->
item_temp
->
appcategories
,
g_strndup
(
text
,
text_len
));
break
;
case
GS_APPSTREAM_XML_SECTION_ID
:
if
(
plugin
->
priv
->
item_temp
==
NULL
||
plugin
->
priv
->
item_temp
->
id
!=
NULL
)
{
...
...
@@ -505,7 +518,6 @@ gs_plugin_destroy (GsPlugin *plugin)
g_hash_table_unref
(
plugin
->
priv
->
hash_pkgname
);
}
/**
* gs_plugin_startup:
*/
...
...
@@ -692,3 +704,62 @@ gs_plugin_refine (GsPlugin *plugin,
out:
return
ret
;
}
static
gboolean
in_array
(
GPtrArray
*
array
,
const
gchar
*
search
)
{
const
gchar
*
tmp
;
guint
i
;
for
(
i
=
0
;
i
<
array
->
len
;
i
++
)
{
tmp
=
g_ptr_array_index
(
array
,
i
);
if
(
g_strcmp0
(
tmp
,
search
)
==
0
)
return
TRUE
;
}
return
FALSE
;
}
/**
* gs_plugin_add_category_apps:
*/
gboolean
gs_plugin_add_category_apps
(
GsPlugin
*
plugin
,
GsCategory
*
category
,
GList
**
list
,
GCancellable
*
cancellable
,
GError
**
error
)
{
const
gchar
*
search_id1
;
const
gchar
*
search_id2
=
NULL
;
gboolean
ret
=
TRUE
;
GsApp
*
app
;
GsAppstreamItem
*
item
;
GsCategory
*
parent
;
guint
i
;
/* get the two search terms */
search_id1
=
gs_category_get_id
(
category
);
parent
=
gs_category_get_parent
(
category
);
if
(
parent
!=
NULL
)
search_id2
=
gs_category_get_id
(
parent
);
/* just look at each app in turn */
for
(
i
=
0
;
i
<
plugin
->
priv
->
array
->
len
;
i
++
)
{
item
=
g_ptr_array_index
(
plugin
->
priv
->
array
,
i
);
if
(
item
->
id
==
NULL
)
continue
;
if
(
!
in_array
(
item
->
appcategories
,
search_id1
))
continue
;
if
(
search_id2
!=
NULL
&&
!
in_array
(
item
->
appcategories
,
search_id2
))
continue
;
/* got a search match, so add all the data we can */
app
=
gs_app_new
(
item
->
id
);
ret
=
gs_plugin_refine_item
(
plugin
,
app
,
item
,
error
);
if
(
!
ret
)
goto
out
;
gs_plugin_add_app
(
list
,
app
);
}
out:
return
ret
;
}
src/plugins/gs-plugin-dummy.c
View file @
8e83ad51
...
...
@@ -184,3 +184,25 @@ gs_plugin_refine (GsPlugin *plugin,
}
return
TRUE
;
}
/**
* gs_plugin_add_category_apps:
*/
gboolean
gs_plugin_add_category_apps
(
GsPlugin
*
plugin
,
GsCategory
*
category
,
GList
**
list
,
GCancellable
*
cancellable
,
GError
**
error
)
{
GsApp
*
app
;
app
=
gs_app_new
(
"gnome-boxes"
);
gs_app_set_name
(
app
,
"Boxes"
);
gs_app_set_summary
(
app
,
"View and use virtual machines"
);
gs_app_set_url
(
app
,
"http://www.box.org"
);
gs_app_set_kind
(
app
,
GS_APP_KIND_NORMAL
);
gs_app_set_state
(
app
,
GS_APP_STATE_AVAILABLE
);
gs_app_set_pixbuf
(
app
,
gdk_pixbuf_new_from_file
(
"/usr/share/icons/hicolor/48x48/apps/gnome-boxes.png"
,
NULL
));
gs_plugin_add_app
(
list
,
app
);
return
TRUE
;
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment