This is an automated email from the git hooks/post-receive script.

nomad pushed a commit to branch master
in repository apps/xfdashboard.

commit 96c42fa2d0095b82a988c99e94fdc4dbd6d80128
Author: Stephan Haller <no...@froevel.de>
Date:   Wed Jan 20 15:37:21 2016 +0100

    Count how often an application was launched by xfdashboard. It can be used 
to calculate the relevance of an application in a search.
    
    This is a preparation work for issue GH #106
---
 xfdashboard/applications-search-provider.c |  362 +++++++++++++++++++++++++++-
 1 file changed, 361 insertions(+), 1 deletion(-)

diff --git a/xfdashboard/applications-search-provider.c 
b/xfdashboard/applications-search-provider.c
index 55aed2b..ed2208d 100644
--- a/xfdashboard/applications-search-provider.c
+++ b/xfdashboard/applications-search-provider.c
@@ -30,11 +30,13 @@
 
 #include <glib/gi18n-lib.h>
 #include <gtk/gtk.h>
+#include <errno.h>
 
 #include "application-database.h"
 #include "application-button.h"
 #include "application.h"
 #include "drag-action.h"
+#include "utils.h"
 
 /* Define this class in GObject system */
 G_DEFINE_TYPE(XfdashboardApplicationsSearchProvider,
@@ -56,7 +58,357 @@ struct _XfdashboardApplicationsSearchProviderPrivate
 };
 
 /* IMPLEMENTATION: Private variables and methods */
-#define DEFAULT_DELIMITERS                     "\t\n\r "
+#define DEFAULT_DELIMITERS                                                     
                                                        "\t\n\r "
+
+#define XFDASHBOARD_APPLICATIONS_SEARCH_PROVIDER_APPDATA_STATE_FILE            
                "app-datas-state"
+#define XFDASHBOARD_APPLICATIONS_SEARCH_PROVIDER_APPDATA_LAUNCH_COUNT_GROUP    
        "Launch Counts"
+
+G_LOCK_DEFINE_STATIC(_xfdashboard_applications_search_provider_app_datas_lock);
+static GHashTable*             
_xfdashboard_applications_search_provider_app_datas=NULL;
+static gchar*                  
_xfdashboard_applications_search_provider_app_datas_filename=NULL;
+static guint                   
_xfdashboard_applications_search_provider_app_datas_shutdownSignalID=0;
+static guint                   
_xfdashboard_applications_search_provider_app_datas_applicationLaunchedSignalID=0;
+
+typedef struct _XfdashboardApplicationsSearchProviderAppData           
XfdashboardApplicationsSearchProviderAppData;
+struct _XfdashboardApplicationsSearchProviderAppData
+{
+       gint                                                            
refCount;
+
+       guint                                                           
launchCounter;
+};
+
+/* Create, destroy, ref and unref tag data for a tag */
+static XfdashboardApplicationsSearchProviderAppData* 
_xfdashboard_applications_search_provider_app_data_new(void)
+{
+       XfdashboardApplicationsSearchProviderAppData    *data;
+
+       /* Create data for app-data */
+       data=g_new0(XfdashboardApplicationsSearchProviderAppData, 1);
+       if(!data) return(NULL);
+
+       /* Set up app-data */
+       data->refCount=1;
+
+       return(data);
+}
+
+static void 
_xfdashboard_applications_search_provider_app_data_free(XfdashboardApplicationsSearchProviderAppData
 *inData)
+{
+       g_return_if_fail(inData);
+
+       /* Release common allocated resources */
+       g_free(inData);
+}
+
+static XfdashboardApplicationsSearchProviderAppData* 
_xfdashboard_applications_search_provider_app_data_ref(XfdashboardApplicationsSearchProviderAppData
 *inData)
+{
+       g_return_val_if_fail(inData, NULL);
+
+       inData->refCount++;
+       return(inData);
+}
+
+static void 
_xfdashboard_applications_search_provider_app_data_unref(XfdashboardApplicationsSearchProviderAppData
 *inData)
+{
+       g_return_if_fail(inData);
+
+       inData->refCount--;
+       if(inData->refCount==0) 
_xfdashboard_applications_search_provider_app_data_free(inData);
+}
+
+/* An application was launched successfully */
+static void 
_xfdashboard_applications_search_provider_on_application_launched(XfdashboardApplication
 *inApplication,
+                                                                               
                                                                                
GAppInfo *inAppInfo,
+                                                                               
                                                                                
gpointer inUserData)
+{
+       const gchar                                                             
                *appID;
+       XfdashboardApplicationsSearchProviderAppData    *appData;
+
+       g_return_if_fail(G_IS_APP_INFO(inAppInfo));
+
+       /* Lock for thread-safety */
+       G_LOCK(_xfdashboard_applications_search_provider_app_datas_lock);
+
+       /* Get application ID which is used to lookup and store app-datas */
+       appID=g_app_info_get_id(inAppInfo);
+
+       /* Create new app-data if application is new, otherwise take an extra
+        * reference on app-data to keep it alive as it will be removed and
+        * re-added when updating and the removal may decrease the reference
+        * counter to zero which destroys the app-data.
+        */
+       
if(!g_hash_table_lookup_extended(_xfdashboard_applications_search_provider_app_datas,
 appID, NULL, (gpointer*)&appData))
+       {
+               
appData=_xfdashboard_applications_search_provider_app_data_new();
+       }
+               else
+               {
+                       
_xfdashboard_applications_search_provider_app_data_ref(appData);
+               }
+
+       /* Increase launch counter */
+       appData->launchCounter++;
+
+       /* Store updated app-data */
+       
g_hash_table_insert(_xfdashboard_applications_search_provider_app_datas, 
g_strdup(appID), 
_xfdashboard_applications_search_provider_app_data_ref(appData));
+
+       /* Release extra reference we took to keep this app-data alive */
+       _xfdashboard_applications_search_provider_app_data_unref(appData);
+
+       /* Unlock for thread-safety */
+       G_UNLOCK(_xfdashboard_applications_search_provider_app_datas_lock);
+}
+
+/* Destroy app-datas for this search provider */
+static void _xfdashboard_applications_search_provider_destroy_app_datas(void)
+{
+       XfdashboardApplication                                                  
        *application;
+
+       /* Only existing app-datas can be destroyed */
+       if(!_xfdashboard_applications_search_provider_app_datas) return;
+
+       /* Lock for thread-safety */
+       G_LOCK(_xfdashboard_applications_search_provider_app_datas_lock);
+
+       /* Get application instance */
+       application=xfdashboard_application_get_default();
+
+       /* Disconnect application "shutdown" signal handler */
+       g_signal_handler_disconnect(application, 
_xfdashboard_applications_search_provider_app_datas_shutdownSignalID);
+       _xfdashboard_applications_search_provider_app_datas_shutdownSignalID=0;
+
+       /* Disconnect application "application-launched" signal handler */
+       g_signal_handler_disconnect(application, 
_xfdashboard_applications_search_provider_app_datas_applicationLaunchedSignalID);
+       
_xfdashboard_applications_search_provider_app_datas_applicationLaunchedSignalID=0;
+
+       /* Save app-datas to state file */
+       if(_xfdashboard_applications_search_provider_app_datas_filename)
+       {
+               GKeyFile                                                        
                        *keyFile;
+               gchar                                                           
                        *keyFileData;
+               gsize                                                           
                        keyFileLength;
+               GHashTableIter                                                  
                iter;
+               gchar                                                           
                        *appID;
+               XfdashboardApplicationsSearchProviderAppData    *appData;
+               GError                                                          
                        *error;
+               gchar                                                           
                        *fileFolder;
+
+               /* Create parent folders for key file if not available */
+               
fileFolder=g_path_get_dirname(_xfdashboard_applications_search_provider_app_datas_filename);
+
+               if(g_mkdir_with_parents(fileFolder, 0700)<0)
+               {
+                       int                                                     
                                errno_save;
+
+                       /* Get error code */
+                       errno_save=errno;
+
+                       /* Show error message */
+                       g_critical(_("Could not create folders to store 
app-datas of applications search provider to %s: %s"),
+                                               
_xfdashboard_applications_search_provider_app_datas_filename,
+                                               g_strerror(errno_save));
+               }
+
+               /* Create and set up key file for app-datas */
+               keyFile=g_key_file_new();
+
+               g_hash_table_iter_init(&iter, 
_xfdashboard_applications_search_provider_app_datas);
+               while(g_hash_table_iter_next(&iter, (gpointer*)&appID, 
(gpointer*)&appData))
+               {
+                       g_key_file_set_uint64(keyFile,
+                                                                       
XFDASHBOARD_APPLICATIONS_SEARCH_PROVIDER_APPDATA_LAUNCH_COUNT_GROUP,
+                                                                       appID,
+                                                                       
appData->launchCounter);
+               }
+
+               /* Store key file for app-datas */
+               error=NULL;
+
+               keyFileData=g_key_file_to_data(keyFile, &keyFileLength, NULL);
+               
if(!g_file_set_contents(_xfdashboard_applications_search_provider_app_datas_filename,
 keyFileData, keyFileLength, &error))
+               {
+                       g_critical(_("Failed to save app-datas of applications 
search provider to %s: %s"),
+                                               
_xfdashboard_applications_search_provider_app_datas_filename,
+                                               error ? error->message : 
_("Unknown error"));
+                       if(error) g_error_free(error);
+               }
+
+               /* Release allocated resources */
+               if(fileFolder) g_free(fileFolder);
+               if(keyFileData) g_free(keyFileData);
+               if(keyFile) g_key_file_free(keyFile);
+       }
+
+       /* Destroy app-datas */
+       g_debug("Destroying app-datas of applications search provider");
+       
g_hash_table_destroy(_xfdashboard_applications_search_provider_app_datas);
+       _xfdashboard_applications_search_provider_app_datas=NULL;
+
+       /* Destroy filename for app-datas */
+       if(_xfdashboard_applications_search_provider_app_datas_filename)
+       {
+               
g_free(_xfdashboard_applications_search_provider_app_datas_filename);
+               
_xfdashboard_applications_search_provider_app_datas_filename=NULL;
+       }
+
+       /* Unlock for thread-safety */
+       G_UNLOCK(_xfdashboard_applications_search_provider_app_datas_lock);
+}
+
+/* Create and load app-datas for this search provider if not done already */
+static void 
_xfdashboard_applications_search_provider_create_app_datas(XfdashboardApplicationsSearchProvider
 *self)
+{
+       XfdashboardApplication                                                  
                *application;
+
+       g_return_if_fail(XFDASHBOARD_IS_APPLICATIONS_SEARCH_PROVIDER(self));
+
+       /* App-datas were already set up */
+       if(_xfdashboard_applications_search_provider_app_datas) return;
+
+       
g_assert(!_xfdashboard_applications_search_provider_app_datas_shutdownSignalID);
+       
g_assert(!_xfdashboard_applications_search_provider_app_datas_applicationLaunchedSignalID);
+
+       /* Lock for thread-safety */
+       G_LOCK(_xfdashboard_applications_search_provider_app_datas_lock);
+
+       /* Load app-datas from state file */
+       
_xfdashboard_applications_search_provider_app_datas_filename=xfdashboard_get_data_path(self,
 XFDASHBOARD_APPLICATIONS_SEARCH_PROVIDER_APPDATA_STATE_FILE);
+       if(!_xfdashboard_applications_search_provider_app_datas_filename)
+       {
+               /* Show error message */
+               g_critical(_("Could not get file name for app-datas of 
applications search provider"));
+
+               /* Unlock for thread-safety */
+               
G_UNLOCK(_xfdashboard_applications_search_provider_app_datas_lock);
+
+               return;
+       }
+
+       /* Create hash-table for app-datas */
+       _xfdashboard_applications_search_provider_app_datas=
+               g_hash_table_new_full(g_str_hash,
+                                                               g_str_equal,
+                                                               g_free,
+                                                               
(GDestroyNotify)_xfdashboard_applications_search_provider_app_data_unref);
+       g_debug("Created app-datas of applications search provider");
+
+       /* Load app-datas and store into hash-table */
+       
if(g_file_test(_xfdashboard_applications_search_provider_app_datas_filename, 
G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
+       {
+               GKeyFile                                                        
                                *keyFile;
+               GError                                                          
                                *error;
+               gchar                                                           
                                *startGroup;
+               gchar                                                           
                                **keys;
+
+               error=NULL;
+               startGroup=NULL;
+               keys=NULL;
+
+               /* Load app-datas state file */
+               keyFile=g_key_file_new();
+               if(!g_key_file_load_from_file(keyFile, 
_xfdashboard_applications_search_provider_app_datas_filename, G_KEY_FILE_NONE, 
&error))
+               {
+                       /* Show error message and release error */
+                       g_critical(_("Could not load app-datas state file of 
applications search provider at %s: %s"),
+                                               
_xfdashboard_applications_search_provider_app_datas_filename,
+                                               error ? error->message : 
_("Unknown error"));
+                       if(error)
+                       {
+                               g_error_free(error);
+                               error=NULL;
+                       }
+
+                       /* Release key file to stop further processing */
+                       g_key_file_free(keyFile);
+                       keyFile=NULL;
+               }
+
+               /* Get keys to lookup in app-datas state file */
+               if(keyFile)
+               {
+                       startGroup=g_key_file_get_start_group(keyFile);
+                       if(!startGroup)
+                       {
+                               g_critical(_("Could get list of app-datas from 
state file of applications search provider at %s"),
+                                                       
_xfdashboard_applications_search_provider_app_datas_filename);
+
+                               /* Release key file to stop further processing 
*/
+                               g_key_file_free(keyFile);
+                               keyFile=NULL;
+                       }
+               }
+
+               if(keyFile)
+               {
+                       keys=g_key_file_get_keys(keyFile, startGroup, NULL, 
&error);
+                       if(!keys)
+                       {
+                               g_critical(_("Could get list of app-datas from 
state file of applications search provider at %s"),
+                                                       
_xfdashboard_applications_search_provider_app_datas_filename);
+
+                               /* Release key file to stop further processing 
*/
+                               g_key_file_free(keyFile);
+                               keyFile=NULL;
+                       }
+               }
+
+               /* Read app-datas from state file */
+               if(keyFile)
+               {
+                       gchar                                                   
                                **iter;
+                       gchar                                                   
                                *appID;
+                       XfdashboardApplicationsSearchProviderAppData    
*appData;
+
+                       for(iter=keys; *iter; iter++)
+                       {
+                               /* Get application ID */
+                               appID=*iter;
+
+                               /* Set up application data for application ID */
+                               
appData=_xfdashboard_applications_search_provider_app_data_new();
+                               
appData->launchCounter=g_key_file_get_uint64(keyFile,
+                                                                               
                                                
XFDASHBOARD_APPLICATIONS_SEARCH_PROVIDER_APPDATA_LAUNCH_COUNT_GROUP,
+                                                                               
                                                appID,
+                                                                               
                                                NULL);
+
+                               /* Store application data into hash-table */
+                               
g_hash_table_insert(_xfdashboard_applications_search_provider_app_datas, 
g_strdup(appID), 
_xfdashboard_applications_search_provider_app_data_ref(appData));
+
+                               /* Release application data */
+                               
_xfdashboard_applications_search_provider_app_data_unref(appData);
+                       }
+
+                       g_debug("Loaded %d app-data entries from '%s' at 
applications search provider",
+                                               
g_hash_table_size(_xfdashboard_applications_search_provider_app_datas),
+                                               
_xfdashboard_applications_search_provider_app_datas_filename);
+               }
+
+               /* Release allocated resources */
+               if(keys) g_strfreev(keys);
+               if(startGroup) g_free(startGroup);
+               if(keyFile) g_key_file_free(keyFile);
+       }
+
+       /* Get application instance */
+       application=xfdashboard_application_get_default();
+
+       /* Connect to "shutdown" signal of application to clean up app-datas */
+       _xfdashboard_applications_search_provider_app_datas_shutdownSignalID=
+               g_signal_connect(application,
+                                                       "shutdown-final",
+                                                       
G_CALLBACK(_xfdashboard_applications_search_provider_destroy_app_datas),
+                                                       NULL);
+
+       /* Connect to "application-launched" signal of application to track app 
launches */
+       
_xfdashboard_applications_search_provider_app_datas_applicationLaunchedSignalID=
+               g_signal_connect(application,
+                                                       "application-launched",
+                                                       
G_CALLBACK(_xfdashboard_applications_search_provider_on_application_launched),
+                                                       NULL);
+
+       /* Unlock for thread-safety */
+       G_UNLOCK(_xfdashboard_applications_search_provider_app_datas_lock);
+}
 
 /* An application was added to database */
 static void 
_xfdashboard_applications_search_provider_on_application_added(XfdashboardApplicationsSearchProvider
 *self,
@@ -302,6 +654,13 @@ static gint 
_xfdashboard_applications_search_provider_sort_result_set(GVariant *
 }
 
 /* IMPLEMENTATION: XfdashboardSearchProvider */
+static void 
_xfdashboard_applications_search_provider_initialize(XfdashboardSearchProvider 
*inProvider)
+{
+       
g_return_if_fail(XFDASHBOARD_IS_APPLICATIONS_SEARCH_PROVIDER(inProvider));
+
+       /* Create and load app-data hash-table (will only be done once) */
+       
_xfdashboard_applications_search_provider_create_app_datas(XFDASHBOARD_APPLICATIONS_SEARCH_PROVIDER(inProvider));
+}
 
 /* Get display name for this search provider */
 static const gchar* 
_xfdashboard_applications_search_provider_get_name(XfdashboardSearchProvider 
*inProvider)
@@ -535,6 +894,7 @@ static void 
xfdashboard_applications_search_provider_class_init(XfdashboardAppli
        /* Override functions */
        gobjectClass->dispose=_xfdashboard_applications_search_provider_dispose;
 
+       
providerClass->initialize=_xfdashboard_applications_search_provider_initialize;
        
providerClass->get_name=_xfdashboard_applications_search_provider_get_name;
        
providerClass->get_icon=_xfdashboard_applications_search_provider_get_icon;
        
providerClass->get_result_set=_xfdashboard_applications_search_provider_get_result_set;

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.
_______________________________________________
Xfce4-commits mailing list
Xfce4-commits@xfce.org
https://mail.xfce.org/mailman/listinfo/xfce4-commits

Reply via email to