diff options
Diffstat (limited to 'src/services')
| -rw-r--r-- | src/services/application-service.c | 211 | ||||
| -rw-r--r-- | src/services/application-service.h | 4 | ||||
| -rw-r--r-- | src/services/meson.build | 1 | ||||
| -rw-r--r-- | src/services/quick-answer-service.c | 317 | ||||
| -rw-r--r-- | src/services/quick-answer-service.h | 21 |
5 files changed, 451 insertions, 103 deletions
diff --git a/src/services/application-service.c b/src/services/application-service.c index 3885719..42835ac 100644 --- a/src/services/application-service.c +++ b/src/services/application-service.c @@ -1,4 +1,5 @@ #include "services/application-service.h" +#include "launcher-item.h" #include "utils.h" #include <gtk/gtk.h> #include <gio/gdesktopappinfo.h> @@ -21,29 +22,38 @@ struct _FoobarApplicationItem enum { APP_PROP_ID = 1, - APP_PROP_NAME, - APP_PROP_DESCRIPTION, APP_PROP_EXECUTABLE, APP_PROP_CATEGORIES, - APP_PROP_ICON, APP_PROP_FREQUENCY, + APP_PROP_TITLE, + APP_PROP_DESCRIPTION, + APP_PROP_ICON, N_APP_PROPS, }; static GParamSpec* app_props[N_APP_PROPS] = { 0 }; -static void foobar_application_item_class_init ( FoobarApplicationItemClass* klass ); -static void foobar_application_item_init ( FoobarApplicationItem* self ); -static void foobar_application_item_get_property( GObject* object, - guint prop_id, - GValue* value, - GParamSpec* pspec ); -static void foobar_application_item_finalize ( GObject* object ); -static FoobarApplicationItem* foobar_application_item_new ( FoobarApplicationService* service ); -static void foobar_application_item_set_info ( FoobarApplicationItem* self, - GAppInfo* value ); +static void foobar_application_item_class_init ( FoobarApplicationItemClass* klass ); +static void foobar_application_item_launcher_item_interface_init( FoobarLauncherItemInterface* iface ); +static void foobar_application_item_init ( FoobarApplicationItem* self ); +static void foobar_application_item_get_property ( GObject* object, + guint prop_id, + GValue* value, + GParamSpec* pspec ); +static void foobar_application_item_finalize ( GObject* object ); +static FoobarApplicationItem* foobar_application_item_new ( FoobarApplicationService* service ); +static gchar const* foobar_application_item_get_title ( FoobarLauncherItem* self ); +static gchar const* foobar_application_item_get_description ( FoobarLauncherItem* self ); +static GIcon* foobar_application_item_get_icon ( FoobarLauncherItem* self ); +static void foobar_application_item_activate ( FoobarLauncherItem* self ); +static void foobar_application_item_set_info ( FoobarApplicationItem* self, + GAppInfo* value ); -G_DEFINE_FINAL_TYPE( FoobarApplicationItem, foobar_application_item, G_TYPE_OBJECT ) +G_DEFINE_FINAL_TYPE_WITH_CODE( + FoobarApplicationItem, + foobar_application_item, + G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE( FOOBAR_TYPE_LAUNCHER_ITEM, foobar_application_item_launcher_item_interface_init ) ) // // FoobarApplicationService: @@ -124,24 +134,13 @@ void foobar_application_item_class_init( FoobarApplicationItemClass* klass ) object_klass->get_property = foobar_application_item_get_property; object_klass->finalize = foobar_application_item_finalize; + gpointer launcher_item_iface = g_type_default_interface_peek( FOOBAR_TYPE_LAUNCHER_ITEM ); app_props[APP_PROP_ID] = g_param_spec_string( "id", "ID", "Application identifier string.", NULL, G_PARAM_READABLE ); - app_props[APP_PROP_NAME] = g_param_spec_string( - "name", - "Name", - "Displayed name for the application.", - NULL, - G_PARAM_READABLE ); - app_props[APP_PROP_DESCRIPTION] = g_param_spec_string( - "description", - "Description", - "Brief description of the application.", - NULL, - G_PARAM_READABLE ); app_props[APP_PROP_EXECUTABLE] = g_param_spec_string( "executable", "Executable", @@ -154,12 +153,6 @@ void foobar_application_item_class_init( FoobarApplicationItemClass* klass ) "Semicolon-separated list of application categories.", NULL, G_PARAM_READABLE ); - app_props[APP_PROP_ICON] = g_param_spec_object( - "icon", - "Icon", - "Icon to show for the application.", - G_TYPE_ICON, - G_PARAM_READABLE ); app_props[APP_PROP_FREQUENCY] = g_param_spec_int64( "frequency", "Frequency", @@ -168,10 +161,30 @@ void foobar_application_item_class_init( FoobarApplicationItemClass* klass ) INT64_MAX, 0, G_PARAM_READABLE ); + app_props[APP_PROP_TITLE] = g_param_spec_override( + "title", + g_object_interface_find_property( launcher_item_iface, "title" ) ); + app_props[APP_PROP_DESCRIPTION] = g_param_spec_override( + "description", + g_object_interface_find_property( launcher_item_iface, "description" ) ); + app_props[APP_PROP_ICON] = g_param_spec_override( + "icon", + g_object_interface_find_property( launcher_item_iface, "icon" ) ); g_object_class_install_properties( object_klass, N_APP_PROPS, app_props ); } // +// Static initialization of the FoobarLauncherItem interface. +// +void foobar_application_item_launcher_item_interface_init( FoobarLauncherItemInterface* iface ) +{ + iface->get_title = foobar_application_item_get_title; + iface->get_description = foobar_application_item_get_description; + iface->get_icon = foobar_application_item_get_icon; + iface->activate = foobar_application_item_activate; +} + +// // Instance initialization for application items. // void foobar_application_item_init( FoobarApplicationItem* self ) @@ -195,24 +208,24 @@ void foobar_application_item_get_property( case APP_PROP_ID: g_value_set_string( value, foobar_application_item_get_id( self ) ); break; - case APP_PROP_NAME: - g_value_set_string( value, foobar_application_item_get_name( self ) ); - break; - case APP_PROP_DESCRIPTION: - g_value_set_string( value, foobar_application_item_get_description( self ) ); - break; case APP_PROP_EXECUTABLE: g_value_set_string( value, foobar_application_item_get_executable( self ) ); break; case APP_PROP_CATEGORIES: g_value_set_string( value, foobar_application_item_get_categories( self ) ); break; - case APP_PROP_ICON: - g_value_set_object( value, foobar_application_item_get_icon( self ) ); - break; case APP_PROP_FREQUENCY: g_value_set_int64( value, foobar_application_item_get_frequency( self ) ); break; + case APP_PROP_TITLE: + g_value_set_string( value, foobar_launcher_item_get_title( FOOBAR_LAUNCHER_ITEM ( self ) ) ); + break; + case APP_PROP_DESCRIPTION: + g_value_set_string( value, foobar_launcher_item_get_description( FOOBAR_LAUNCHER_ITEM( self ) ) ); + break; + case APP_PROP_ICON: + g_value_set_object( value, foobar_launcher_item_get_icon( FOOBAR_LAUNCHER_ITEM( self ) ) ); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID( object, prop_id, pspec ); break; @@ -251,62 +264,91 @@ gchar const* foobar_application_item_get_id( FoobarApplicationItem* self ) } // -// Get the application's human-readable name. +// Get the application's executable name. // -gchar const* foobar_application_item_get_name( FoobarApplicationItem* self ) +gchar const* foobar_application_item_get_executable( FoobarApplicationItem* self ) { g_return_val_if_fail( FOOBAR_IS_APPLICATION_ITEM( self ), NULL ); - return self->info ? g_app_info_get_display_name( self->info ) : NULL; + return self->info ? g_app_info_get_executable( self->info ) : NULL; } // -// Get an optional short description for the application. +// Get the semicolon-separated list of categories for this application. // -gchar const* foobar_application_item_get_description( FoobarApplicationItem* self ) +gchar const* foobar_application_item_get_categories( FoobarApplicationItem* self ) { g_return_val_if_fail( FOOBAR_IS_APPLICATION_ITEM( self ), NULL ); - return self->info ? g_app_info_get_description( self->info ) : NULL; + return G_IS_DESKTOP_APP_INFO( self->info ) + ? g_desktop_app_info_get_categories( G_DESKTOP_APP_INFO( self->info ) ) + : NULL; } // -// Get the application's executable name. +// Get the number of times this application was opened using the launcher. // -gchar const* foobar_application_item_get_executable( FoobarApplicationItem* self ) +gint64 foobar_application_item_get_frequency( FoobarApplicationItem* self ) { - g_return_val_if_fail( FOOBAR_IS_APPLICATION_ITEM( self ), NULL ); - return self->info ? g_app_info_get_executable( self->info ) : NULL; + g_return_val_if_fail( FOOBAR_IS_APPLICATION_ITEM( self ), 0 ); + + if ( !self->service ) { return 0; } + gpointer value = g_hash_table_lookup( self->service->frequencies, foobar_application_item_get_id( self ) ); + return GPOINTER_TO_SIZE( value ); } // -// Get the semicolon-separated list of categories for this application. +// Get the application's human-readable name. // -gchar const* foobar_application_item_get_categories( FoobarApplicationItem* self ) +gchar const* foobar_application_item_get_title( FoobarLauncherItem* item ) { - g_return_val_if_fail( FOOBAR_IS_APPLICATION_ITEM( self ), NULL ); - return G_IS_DESKTOP_APP_INFO( self->info ) - ? g_desktop_app_info_get_categories( G_DESKTOP_APP_INFO( self->info ) ) - : NULL; + FoobarApplicationItem* self = ( FoobarApplicationItem* )item; + return self->info ? g_app_info_get_display_name( self->info ) : NULL; +} + +// +// Get an optional short description for the application. +// +gchar const* foobar_application_item_get_description( FoobarLauncherItem* item ) +{ + FoobarApplicationItem* self = ( FoobarApplicationItem* )item; + return self->info ? g_app_info_get_description( self->info ) : NULL; } // // Get an icon representing the application. // -GIcon* foobar_application_item_get_icon( FoobarApplicationItem* self ) +GIcon* foobar_application_item_get_icon( FoobarLauncherItem* item ) { - g_return_val_if_fail( FOOBAR_IS_APPLICATION_ITEM( self ), NULL ); + FoobarApplicationItem* self = ( FoobarApplicationItem* )item; return self->info ? g_app_info_get_icon( self->info ) : NULL; } // -// Get the number of times this application was opened using the launcher. +// Launch the application, increasing its frequency by one. // -gint64 foobar_application_item_get_frequency( FoobarApplicationItem* self ) +void foobar_application_item_activate( FoobarLauncherItem* item ) { - g_return_val_if_fail( FOOBAR_IS_APPLICATION_ITEM( self ), 0 ); + FoobarApplicationItem* self = ( FoobarApplicationItem* )item; - if ( !self->service ) { return 0; } - gpointer value = g_hash_table_lookup( self->service->frequencies, foobar_application_item_get_id( self ) ); - return GPOINTER_TO_SIZE( value ); + if ( !self->info ) { return; } + + g_autoptr( GError ) error = NULL; + if ( !g_app_info_launch( self->info, NULL, NULL, &error ) ) + { + g_warning( "Unable to launch application: %s", error->message ); + } + + gchar const* id = foobar_application_item_get_id( self ); + if ( !self->service || !id ) { return; } + + gpointer value = g_hash_table_lookup( self->service->frequencies, id ); + value = GSIZE_TO_POINTER( GPOINTER_TO_SIZE( value ) + 1 ); + g_mutex_lock( &self->service->frequencies_mutex ); + g_hash_table_insert( self->service->frequencies, g_strdup( id ), value ); + g_mutex_unlock( &self->service->frequencies_mutex ); + + g_object_notify_by_pspec( G_OBJECT( self ), app_props[APP_PROP_FREQUENCY] ); + gtk_sorter_changed( gtk_sort_list_model_get_sorter( self->service->sorted_items ), GTK_SORTER_CHANGE_DIFFERENT ); + foobar_application_service_write_cache( self->service ); } // @@ -325,7 +367,7 @@ void foobar_application_item_set_info( if ( value ) { self->info = g_object_ref( value ); } g_object_notify_by_pspec( G_OBJECT( self ), app_props[APP_PROP_ID] ); - g_object_notify_by_pspec( G_OBJECT( self ), app_props[APP_PROP_NAME] ); + g_object_notify_by_pspec( G_OBJECT( self ), app_props[APP_PROP_TITLE] ); g_object_notify_by_pspec( G_OBJECT( self ), app_props[APP_PROP_DESCRIPTION] ); g_object_notify_by_pspec( G_OBJECT( self ), app_props[APP_PROP_EXECUTABLE] ); g_object_notify_by_pspec( G_OBJECT( self ), app_props[APP_PROP_ICON] ); @@ -346,8 +388,8 @@ gboolean foobar_application_item_match( for ( gchar const* const* it = terms; *it; ++it ) { gchar const* term = *it; - gchar const* name = foobar_application_item_get_name( self ); - gchar const* description = foobar_application_item_get_description( self ); + gchar const* name = foobar_launcher_item_get_title( FOOBAR_LAUNCHER_ITEM( self ) ); + gchar const* description = foobar_launcher_item_get_description( FOOBAR_LAUNCHER_ITEM( self ) ); gchar const* executable = foobar_application_item_get_executable( self ); gchar const* categories = foobar_application_item_get_categories( self ); gchar const* id = foobar_application_item_get_id( self ); @@ -363,35 +405,6 @@ gboolean foobar_application_item_match( return TRUE; } -// -// Launch the application, increasing its frequency by one. -// -void foobar_application_item_launch( FoobarApplicationItem* self ) -{ - g_return_if_fail( FOOBAR_IS_APPLICATION_ITEM( self ) ); - - if ( !self->info ) { return; } - - g_autoptr( GError ) error = NULL; - if ( !g_app_info_launch( self->info, NULL, NULL, &error ) ) - { - g_warning( "Unable to launch application: %s", error->message ); - } - - gchar const* id = foobar_application_item_get_id( self ); - if ( !self->service || !id ) { return; } - - gpointer value = g_hash_table_lookup( self->service->frequencies, id ); - value = GSIZE_TO_POINTER( GPOINTER_TO_SIZE( value ) + 1 ); - g_mutex_lock( &self->service->frequencies_mutex ); - g_hash_table_insert( self->service->frequencies, g_strdup( id ), value ); - g_mutex_unlock( &self->service->frequencies_mutex ); - - g_object_notify_by_pspec( G_OBJECT( self ), app_props[APP_PROP_FREQUENCY] ); - gtk_sorter_changed( gtk_sort_list_model_get_sorter( self->service->sorted_items ), GTK_SORTER_CHANGE_DIFFERENT ); - foobar_application_service_write_cache( self->service ); -} - // --------------------------------------------------------------------------------------------------------------------- // Service Implementation // --------------------------------------------------------------------------------------------------------------------- @@ -722,8 +735,8 @@ gint foobar_application_service_sort_func( if ( freq_a > freq_b ) { return -1; } if ( freq_a < freq_b ) { return 1; } - gchar const* name_a = foobar_application_item_get_name( app_a ); - gchar const* name_b = foobar_application_item_get_name( app_b ); + gchar const* name_a = foobar_launcher_item_get_title( FOOBAR_LAUNCHER_ITEM( app_a ) ); + gchar const* name_b = foobar_launcher_item_get_title( FOOBAR_LAUNCHER_ITEM( app_b ) ); gint name_res = g_strcmp0( name_a, name_b ); if ( name_res ) { return name_res; } diff --git a/src/services/application-service.h b/src/services/application-service.h index 3c2622a..dd043fc 100644 --- a/src/services/application-service.h +++ b/src/services/application-service.h @@ -11,15 +11,11 @@ G_BEGIN_DECLS G_DECLARE_FINAL_TYPE( FoobarApplicationItem, foobar_application_item, FOOBAR, APPLICATION_ITEM, GObject ) gchar const* foobar_application_item_get_id ( FoobarApplicationItem* self ); -gchar const* foobar_application_item_get_name ( FoobarApplicationItem* self ); -gchar const* foobar_application_item_get_description( FoobarApplicationItem* self ); gchar const* foobar_application_item_get_executable ( FoobarApplicationItem* self ); gchar const* foobar_application_item_get_categories ( FoobarApplicationItem* self ); -GIcon* foobar_application_item_get_icon ( FoobarApplicationItem* self ); gint64 foobar_application_item_get_frequency ( FoobarApplicationItem* self ); gboolean foobar_application_item_match ( FoobarApplicationItem* self, gchar const* const* terms ); -void foobar_application_item_launch ( FoobarApplicationItem* self ); G_DECLARE_FINAL_TYPE( FoobarApplicationService, foobar_application_service, FOOBAR, APPLICATION_SERVICE, GObject ) diff --git a/src/services/meson.build b/src/services/meson.build index 990102b..e4f151d 100644 --- a/src/services/meson.build +++ b/src/services/meson.build @@ -8,5 +8,6 @@ foobar_sources += files( 'network-service.c', 'bluetooth-service.c', 'application-service.c', + 'quick-answer-service.c', 'configuration-service.c', ) diff --git a/src/services/quick-answer-service.c b/src/services/quick-answer-service.c new file mode 100644 index 0000000..b564a16 --- /dev/null +++ b/src/services/quick-answer-service.c @@ -0,0 +1,317 @@ +#include "services/quick-answer-service.h" +#include "launcher-item.h" +#include <gdk/gdk.h> + +struct _FoobarQuickAnswer +{ + GObject parent_instance; + gchar* title; + gchar* value; + GIcon* icon; +}; + +enum +{ + ANSWER_PROP_VALUE = 1, + ANSWER_PROP_TITLE, + ANSWER_PROP_DESCRIPTION, + ANSWER_PROP_ICON, + N_ANSWER_PROPS, +}; + +static GParamSpec* answer_props[N_ANSWER_PROPS] = { 0 }; + +static void foobar_quick_answer_class_init ( FoobarQuickAnswerClass* klass ); +static void foobar_quick_answer_launcher_item_interface_init( FoobarLauncherItemInterface* iface ); +static void foobar_quick_answer_init ( FoobarQuickAnswer* self ); +static void foobar_quick_answer_get_property ( GObject* object, + guint prop_id, + GValue* value, + GParamSpec* pspec ); +static void foobar_quick_answer_finalize ( GObject* object ); +static FoobarQuickAnswer* foobar_quick_answer_new ( void ); +static gchar const* foobar_quick_answer_get_title ( FoobarLauncherItem* self ); +static gchar const* foobar_quick_answer_get_description ( FoobarLauncherItem* self ); +static GIcon* foobar_quick_answer_get_icon ( FoobarLauncherItem* self ); +static void foobar_quick_answer_activate ( FoobarLauncherItem* self ); +static void foobar_quick_answer_set_title ( FoobarQuickAnswer* self, + gchar const* value ); +static void foobar_quick_answer_set_value ( FoobarQuickAnswer* self, + gchar const* value ); +static void foobar_quick_answer_set_icon ( FoobarQuickAnswer* self, + GIcon* value ); + +G_DEFINE_FINAL_TYPE_WITH_CODE( + FoobarQuickAnswer, + foobar_quick_answer, + G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE( FOOBAR_TYPE_LAUNCHER_ITEM, foobar_quick_answer_launcher_item_interface_init ) ) + +struct _FoobarQuickAnswerService +{ + GObject parent_instance; +}; + +static void foobar_quick_answer_service_class_init( FoobarQuickAnswerServiceClass* klass ); +static void foobar_quick_answer_service_init ( FoobarQuickAnswerService* self ); + +G_DEFINE_FINAL_TYPE( FoobarQuickAnswerService, foobar_quick_answer_service, G_TYPE_OBJECT ) + +// --------------------------------------------------------------------------------------------------------------------- +// Quick Answers +// --------------------------------------------------------------------------------------------------------------------- + +// +// Static initialization for quick answers. +// +void foobar_quick_answer_class_init( FoobarQuickAnswerClass* klass ) +{ + GObjectClass* object_klass = G_OBJECT_CLASS( klass ); + object_klass->get_property = foobar_quick_answer_get_property; + object_klass->finalize = foobar_quick_answer_finalize; + + gpointer launcher_item_iface = g_type_default_interface_peek( FOOBAR_TYPE_LAUNCHER_ITEM ); + answer_props[ANSWER_PROP_VALUE] = g_param_spec_string( + "value", + "Value", + "The raw value of the quick answer.", + NULL, + G_PARAM_READABLE ); + answer_props[ANSWER_PROP_TITLE] = g_param_spec_override( + "title", + g_object_interface_find_property( launcher_item_iface, "title" ) ); + answer_props[ANSWER_PROP_DESCRIPTION] = g_param_spec_override( + "description", + g_object_interface_find_property( launcher_item_iface, "description" ) ); + answer_props[ANSWER_PROP_ICON] = g_param_spec_override( + "icon", + g_object_interface_find_property( launcher_item_iface, "icon" ) ); + g_object_class_install_properties( object_klass, N_ANSWER_PROPS, answer_props ); +} + +// +// Static initialization of the FoobarLauncherItem interface. +// +void foobar_quick_answer_launcher_item_interface_init( FoobarLauncherItemInterface* iface ) +{ + iface->get_title = foobar_quick_answer_get_title; + iface->get_description = foobar_quick_answer_get_description; + iface->get_icon = foobar_quick_answer_get_icon; + iface->activate = foobar_quick_answer_activate; +} + +// +// Instance initialization for quick answers. +// +void foobar_quick_answer_init( FoobarQuickAnswer* self ) +{ + (void)self; +} + +// +// Property getter implementation, mapping a property id to a method. +// +void foobar_quick_answer_get_property( + GObject* object, + guint prop_id, + GValue* value, + GParamSpec* pspec ) +{ + FoobarQuickAnswer* self = (FoobarQuickAnswer*)object; + + switch ( prop_id ) + { + case ANSWER_PROP_VALUE: + g_value_set_string( value, foobar_quick_answer_get_value( self ) ); + break; + case ANSWER_PROP_TITLE: + g_value_set_string( value, foobar_launcher_item_get_title( FOOBAR_LAUNCHER_ITEM ( self ) ) ); + break; + case ANSWER_PROP_DESCRIPTION: + g_value_set_string( value, foobar_launcher_item_get_description( FOOBAR_LAUNCHER_ITEM( self ) ) ); + break; + case ANSWER_PROP_ICON: + g_value_set_object( value, foobar_launcher_item_get_icon( FOOBAR_LAUNCHER_ITEM( self ) ) ); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID( object, prop_id, pspec ); + break; + } +} + +// +// Instance cleanup for quick answers. +// +void foobar_quick_answer_finalize( GObject* object ) +{ + FoobarQuickAnswer* self = (FoobarQuickAnswer*)object; + + g_clear_pointer( &self->title, g_free ); + g_clear_pointer( &self->value, g_free ); + g_clear_object( &self->icon ); + + G_OBJECT_CLASS( foobar_quick_answer_parent_class )->finalize( object ); +} + +// +// Create a new, default-initialized quick answer. +// +FoobarQuickAnswer* foobar_quick_answer_new( void ) +{ + return g_object_new( FOOBAR_TYPE_QUICK_ANSWER, NULL ); +} + +// +// Get the raw value of the quick answer. +// +gchar const* foobar_quick_answer_get_value( FoobarQuickAnswer* self ) +{ + g_return_val_if_fail( FOOBAR_IS_QUICK_ANSWER( self ), NULL ); + return self->value; +} + +// +// Get the title for the quick answer. +// +gchar const* foobar_quick_answer_get_title( FoobarLauncherItem* item ) +{ + FoobarQuickAnswer* self = ( FoobarQuickAnswer* )item; + return self->title; +} + +// +// Get the description shown below the title, always NULL for quick answers. +// +gchar const* foobar_quick_answer_get_description( FoobarLauncherItem* item ) +{ + (void)item; + return NULL; +} + +// +// Get an icon representing the quick answer. +// +GIcon* foobar_quick_answer_get_icon( FoobarLauncherItem* item ) +{ + FoobarQuickAnswer* self = ( FoobarQuickAnswer* )item; + return self->icon; +} + +// +// Copy the quick answer's value into the clipboard. +// +void foobar_quick_answer_activate( FoobarLauncherItem* item ) +{ + FoobarQuickAnswer* self = ( FoobarQuickAnswer* )item; + if ( self->value ) + { + GdkClipboard* clipboard = gdk_display_get_clipboard( gdk_display_get_default( ) ); + gdk_clipboard_set_text( clipboard, self->value ); + } +} + +// +// Update the raw value of the quick answer. +// +void foobar_quick_answer_set_value( + FoobarQuickAnswer* self, + gchar const* value ) +{ + g_return_if_fail( FOOBAR_IS_QUICK_ANSWER( self ) ); + + if ( g_strcmp0( self->value, value ) ) + { + g_clear_pointer( &self->value, g_free ); + self->value = g_strdup( value ); + g_object_notify_by_pspec( G_OBJECT( self ), answer_props[ANSWER_PROP_VALUE] ); + } +} + +// +// Update the title for the quick answer. +// +void foobar_quick_answer_set_title( + FoobarQuickAnswer* self, + gchar const* value ) +{ + g_return_if_fail( FOOBAR_IS_QUICK_ANSWER( self ) ); + + if ( g_strcmp0( self->title, value ) ) + { + g_clear_pointer( &self->title, g_free ); + self->title = g_strdup( value ); + g_object_notify_by_pspec( G_OBJECT( self ), answer_props[ANSWER_PROP_TITLE] ); + } +} + +// +// Update the icon representing the quick answer. +// +void foobar_quick_answer_set_icon( + FoobarQuickAnswer* self, + GIcon* value ) +{ + g_return_if_fail( FOOBAR_IS_QUICK_ANSWER( self ) ); + + if ( self->icon != value ) + { + g_clear_object( &self->icon ); + self->icon = value ? g_object_ref( value ) : NULL; + g_object_notify_by_pspec( G_OBJECT( self ), answer_props[ANSWER_PROP_ICON] ); + } +} + +// --------------------------------------------------------------------------------------------------------------------- +// Service Implementation +// --------------------------------------------------------------------------------------------------------------------- + +// +// Static initialization for the quick answer service. +// +void foobar_quick_answer_service_class_init( FoobarQuickAnswerServiceClass* klass ) +{ + (void)klass; +} + +// +// Instance initialization for the quick answer service. +// +void foobar_quick_answer_service_init( FoobarQuickAnswerService* self ) +{ + (void)self; +} + +// --------------------------------------------------------------------------------------------------------------------- +// Public API +// --------------------------------------------------------------------------------------------------------------------- + +// +// Create a new quick answer service instance. +// +FoobarQuickAnswerService* foobar_quick_answer_service_new( void ) +{ + return g_object_new( FOOBAR_TYPE_QUICK_ANSWER_SERVICE, NULL ); +} + +// +// Query the service for a quick answer. +// +FoobarQuickAnswer* foobar_quick_answer_service_query( + FoobarQuickAnswerService* self, + gchar const* query ) +{ + (void)self; + + if ( !g_strcmp0(query, "2+2") ) + { + g_autoptr(GIcon) icon = g_themed_icon_new("fluent-calculator-symbolic"); + + FoobarQuickAnswer* answer = foobar_quick_answer_new(); + foobar_quick_answer_set_value(answer, "4"); + foobar_quick_answer_set_title(answer, "= 4"); + foobar_quick_answer_set_icon(answer, icon); + return answer; + } + + return NULL; +} diff --git a/src/services/quick-answer-service.h b/src/services/quick-answer-service.h new file mode 100644 index 0000000..02a8e10 --- /dev/null +++ b/src/services/quick-answer-service.h @@ -0,0 +1,21 @@ +#pragma once + +#include <glib-object.h> +#include <gio/gio.h> + +G_BEGIN_DECLS + +#define FOOBAR_TYPE_QUICK_ANSWER foobar_quick_answer_get_type( ) +#define FOOBAR_TYPE_QUICK_ANSWER_SERVICE foobar_quick_answer_service_get_type( ) + +G_DECLARE_FINAL_TYPE( FoobarQuickAnswer, foobar_quick_answer, FOOBAR, QUICK_ANSWER, GObject ) + +gchar const* foobar_quick_answer_get_value( FoobarQuickAnswer* self ); + +G_DECLARE_FINAL_TYPE( FoobarQuickAnswerService, foobar_quick_answer_service, FOOBAR, QUICK_ANSWER_SERVICE, GObject ) + +FoobarQuickAnswerService* foobar_quick_answer_service_new ( void ); +FoobarQuickAnswer* foobar_quick_answer_service_query ( FoobarQuickAnswerService* self, + gchar const* query ); + +G_END_DECLS |
