Index: src/trackerd/tracker-dbus-search.c =================================================================== --- src/trackerd/tracker-dbus-search.c (revision 527) +++ src/trackerd/tracker-dbus-search.c (working copy) @@ -781,3 +781,179 @@ tracker_db_free_result (res); } + +/* int levenshtein () + * Original license: GNU Lesser Public License + * from the Dixit project, (http://dixit.sourceforge.net/) + * Author: Octavian Procopiuc + * Created: July 25, 2004 + * Copied into tracker, by Edward Duffy + */ + +static int +levenshtein(char *source, char *target, int maxdist) +{ + + char n, m; + uint l; + l = strlen (source); + if (l > 50) + return -1; + n = l; + + l = strlen (target); + if (l > 50) + return -1; + m = l; + + if (maxdist == 0) + maxdist = MAX(m, n); + if (n == 0) + return MIN(m, maxdist); + if (m == 0) + return MIN(n, maxdist); + + // Store the min. value on each column, so that, if it reaches + // maxdist, we break early. + char mincolval; + + char matrix[51][51]; + + char j; + char i; + char cell; + + for (j = 0; j <= m; j++) + matrix[0][(int)j] = j; + + for (i = 1; i <= n; i++) { + + mincolval = MAX(m, i); + matrix[(int)i][0] = i; + + char s_i = source[i-1]; + + for (j = 1; j <= m; j++) { + + char t_j = target[j-1]; + + char cost = (s_i == t_j ? 0 : 1); + + char above = matrix[i-1][(int)j]; + char left = matrix[(int)i][j-1]; + char diag = matrix[i-1][j-1]; + cell = MIN(above + 1, MIN(left + 1, diag + cost)); + + // Cover transposition, in addition to deletion, + // insertion and substitution. This step is taken from: + // Berghel, Hal ; Roach, David : "An Extension of Ukkonen's + // Enhanced Dynamic Programming ASM Algorithm" + // (http://www.acm.org/~hlb/publications/asm/asm.html) + + if (i > 2 && j > 2) { + char trans = matrix[i-2][j-2] + 1; + if (source[i-2] != t_j) + trans++; + if (s_i != target[j-2]) + trans++; + if (cell > trans) + cell = trans; + } + + mincolval = MIN(mincolval, cell); + matrix[(int)i][(int)j] = cell; + } + + if (mincolval >= maxdist) + break; + + } + + if (i == n + 1) + return (int) matrix[(int)n][(int)m]; + else + return maxdist; +} + +void +tracker_dbus_method_search_suggest (DBusRec *rec) +{ + DBusError dbus_error; + DBusMessage *reply; + gchar *term, *str; + gint maxdist; + gint dist, tsiz; + gchar *winner_str; + gint winner_dist; + char *tmp; + int hits; + + /* + + + + + + */ + + dbus_error_init (&dbus_error); + if (!dbus_message_get_args (rec->message, NULL, + DBUS_TYPE_STRING, &term, + DBUS_TYPE_INT32, &maxdist, + DBUS_TYPE_INVALID)) { + tracker_set_error (rec, "DBusError: %s;%s", dbus_error.name, dbus_error.message); + dbus_error_free (&dbus_error); + return; + } + + winner_str = NULL; + + criterinit (tracker->file_indexer->word_index); + + str = criternext (tracker->file_indexer->word_index, NULL); + while (str != NULL) { + dist = levenshtein (term, str, 0); + if (dist != -1 && dist < maxdist) { + hits = 0; + if ((tmp = crget (tracker->file_indexer->word_index, str, -1, 0, -1, &tsiz)) != NULL) { + hits = tsiz / sizeof (WordDetails); + free (tmp); + } + if (hits > 0) { + if (winner_str == NULL) { + winner_str = strdup (str); + winner_dist = dist; + } + else if (dist < winner_dist) { + free (winner_str); + winner_str = strdup (str); + winner_dist = dist; + } + } + else { + tracker_log ("No hits for %s!", str); + } + } + free (str); + str = criternext (tracker->file_indexer->word_index, NULL); + } + + if (winner_str == NULL) { + winner_str = strdup (term); + } + + tracker_log ("Suggested spelling for %s is %s.", term, winner_str); + + reply = dbus_message_new_method_return (rec->message); + + dbus_message_append_args (reply, + DBUS_TYPE_STRING, &winner_str, + DBUS_TYPE_INVALID); + free (winner_str); + + dbus_connection_send (rec->connection, reply, NULL); + + dbus_message_unref (reply); + +} + Index: src/trackerd/trackerd.c =================================================================== --- src/trackerd/trackerd.c (revision 527) +++ src/trackerd/trackerd.c (working copy) @@ -1548,7 +1548,14 @@ break; + case DBUS_ACTION_SEARCH_SUGGEST: + tracker_dbus_method_search_suggest (rec); + + break; + + + case DBUS_ACTION_FILES_EXISTS: tracker_dbus_method_files_exists (rec); Index: src/trackerd/tracker-dbus.c =================================================================== --- src/trackerd/tracker-dbus.c (revision 527) +++ src/trackerd/tracker-dbus.c (working copy) @@ -36,7 +36,6 @@ NULL }; - DBusConnection * tracker_dbus_init (void) { @@ -291,7 +290,14 @@ + } else if (dbus_message_is_method_call (message, TRACKER_INTERFACE_SEARCH, TRACKER_METHOD_SEARCH_SUGGEST)) { + dbus_message_ref (message); + rec->action = DBUS_ACTION_SEARCH_SUGGEST; + + + + } else if (dbus_message_is_method_call (message, TRACKER_INTERFACE_FILES, TRACKER_METHOD_FILES_EXISTS)) { dbus_message_ref (message); Index: src/trackerd/tracker-dbus.h =================================================================== --- src/trackerd/tracker-dbus.h (revision 527) +++ src/trackerd/tracker-dbus.h (working copy) @@ -71,6 +71,7 @@ #define TRACKER_METHOD_SEARCH_METADATA "Metadata" #define TRACKER_METHOD_SEARCH_MATCHING_FIELDS "MatchingFields" #define TRACKER_METHOD_SEARCH_QUERY "Query" +#define TRACKER_METHOD_SEARCH_SUGGEST "Suggest" /* File Interface */ #define TRACKER_METHOD_FILES_EXISTS "Exists" @@ -136,6 +137,7 @@ DBUS_ACTION_SEARCH_METADATA, DBUS_ACTION_SEARCH_MATCHING_FIELDS, DBUS_ACTION_SEARCH_QUERY, + DBUS_ACTION_SEARCH_SUGGEST, DBUS_ACTION_FILES_EXISTS, DBUS_ACTION_FILES_CREATE, Index: src/libtracker/tracker.h =================================================================== --- src/libtracker/tracker.h (revision 527) +++ src/libtracker/tracker.h (working copy) @@ -129,6 +129,7 @@ char * tracker_search_get_snippet (TrackerClient *client, ServiceType service, const char *uri, const char *search_text, GError **error); char ** tracker_search_metadata (TrackerClient *client, ServiceType service, const char *field, const char* search_text, int offset, int max_hits, GError **error); GPtrArray * tracker_search_query (TrackerClient *client, int live_query_id, ServiceType service, char **fields, const char *search_text, const char *keywords, const char *query, int offset, int max_hits, gboolean sort_by_service, GError **error); +gchar * tracker_search_suggest (TrackerClient *client, const char *search_text, int maxdist, GError **error); void tracker_files_create (TrackerClient *client, const char *uri, gboolean is_directory, const char *mime, int size, int mtime, GError **error); @@ -180,8 +181,8 @@ void tracker_search_get_snippet_async (TrackerClient *client, ServiceType service, const char *uri, const char *search_text, TrackerStringReply callback, gpointer user_data); void tracker_search_metadata_async (TrackerClient *client, ServiceType service, const char *field, const char* search_text, int offset, int max_hits, TrackerArrayReply callback, gpointer user_data); void tracker_search_query_async (TrackerClient *client, int live_query_id, ServiceType service, char **fields, const char *search_text, const char *keywords, const char *query, int offset, int max_hits, gboolean sort_by_service, TrackerGPtrArrayReply callback, gpointer user_data); +void tracker_search_suggest_async (TrackerClient *client, const char *search_text, int maxdist, TrackerStringReply callback, gpointer user_data); - void tracker_files_create_async (TrackerClient *client, const char *uri, gboolean is_directory, const char *mime, int size, int mtime, TrackerVoidReply callback, gpointer user_data); void tracker_files_delete_async (TrackerClient *client, const char *uri, TrackerVoidReply callback, gpointer user_data); void tracker_files_get_text_contents_async (TrackerClient *client, const char *uri, int offset, int max_length, TrackerStringReply callback, gpointer user_data); Index: src/libtracker/tracker.c =================================================================== --- src/libtracker/tracker.c (revision 527) +++ src/libtracker/tracker.c (working copy) @@ -611,6 +611,15 @@ return table; } +char * +tracker_search_suggest (TrackerClient *client, const char *search_term, int maxdist, GError **error) +{ + gchar *result; + if (org_freedesktop_Tracker_Search_suggest (client->proxy_search, search_term, maxdist, &result, &*error)) { + return result; + } + return NULL; +} @@ -1147,8 +1156,21 @@ } +void +tracker_search_suggest_async (TrackerClient *client, const char *search_text, int maxdist, TrackerStringReply callback, gpointer user_data) +{ + StringCallBackStruct *callback_struct; + callback_struct = g_new (StringCallBackStruct, 1); + callback_struct->callback = callback; + callback_struct->data = user_data; + + client->last_pending_call = org_freedesktop_Tracker_Search_suggest_async (client->proxy_search, search_text, maxdist, tracker_string_reply, callback_struct); + +} + + void tracker_files_create_async (TrackerClient *client, const char *uri, gboolean is_directory, const char *mime, int size, int mtime, TrackerVoidReply callback, gpointer user_data) { Index: src/libtracker/tracker-client.h =================================================================== --- src/libtracker/tracker-client.h (revision 527) +++ src/libtracker/tracker-client.h (working copy) @@ -25,7 +25,7 @@ static void org_freedesktop_Tracker_get_version_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - DBusGAsyncData *data = user_data; + DBusGAsyncData *data = (DBusGAsyncData*) user_data; GError *error = NULL; gint OUT_version; dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INT, &OUT_version, G_TYPE_INVALID); @@ -63,7 +63,7 @@ static void org_freedesktop_Tracker_get_services_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - DBusGAsyncData *data = user_data; + DBusGAsyncData *data = (DBusGAsyncData*) user_data; GError *error = NULL; GHashTable* OUT_result; dbus_g_proxy_end_call (proxy, call, &error, dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), &OUT_result, G_TYPE_INVALID); @@ -101,7 +101,7 @@ static void org_freedesktop_Tracker_get_stats_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - DBusGAsyncData *data = user_data; + DBusGAsyncData *data = (DBusGAsyncData*) user_data; GError *error = NULL; GPtrArray* OUT_service_stats; dbus_g_proxy_end_call (proxy, call, &error, dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRV), &OUT_service_stats, G_TYPE_INVALID); @@ -144,7 +144,7 @@ static void org_freedesktop_Tracker_Metadata_get_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - DBusGAsyncData *data = user_data; + DBusGAsyncData *data = (DBusGAsyncData*) user_data; GError *error = NULL; char ** OUT_values; dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_STRV, &OUT_values, G_TYPE_INVALID); @@ -182,7 +182,7 @@ static void org_freedesktop_Tracker_Metadata_set_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - DBusGAsyncData *data = user_data; + DBusGAsyncData *data = (DBusGAsyncData*) user_data; GError *error = NULL; dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); (*(org_freedesktop_Tracker_Metadata_set_reply)data->cb) (proxy, error, data->userdata); @@ -219,7 +219,7 @@ static void org_freedesktop_Tracker_Metadata_register_type_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - DBusGAsyncData *data = user_data; + DBusGAsyncData *data = (DBusGAsyncData*) user_data; GError *error = NULL; dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); (*(org_freedesktop_Tracker_Metadata_register_type_reply)data->cb) (proxy, error, data->userdata); @@ -256,7 +256,7 @@ static void org_freedesktop_Tracker_Metadata_get_type_details_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - DBusGAsyncData *data = user_data; + DBusGAsyncData *data = (DBusGAsyncData*) user_data; GError *error = NULL; char * OUT_data_type; gboolean OUT_is_embedded; @@ -296,7 +296,7 @@ static void org_freedesktop_Tracker_Metadata_get_registered_types_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - DBusGAsyncData *data = user_data; + DBusGAsyncData *data = (DBusGAsyncData*) user_data; GError *error = NULL; char ** OUT_result; dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_STRV, &OUT_result, G_TYPE_INVALID); @@ -334,7 +334,7 @@ static void org_freedesktop_Tracker_Metadata_get_writeable_types_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - DBusGAsyncData *data = user_data; + DBusGAsyncData *data = (DBusGAsyncData*) user_data; GError *error = NULL; char ** OUT_result; dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_STRV, &OUT_result, G_TYPE_INVALID); @@ -372,7 +372,7 @@ static void org_freedesktop_Tracker_Metadata_get_registered_classes_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - DBusGAsyncData *data = user_data; + DBusGAsyncData *data = (DBusGAsyncData*) user_data; GError *error = NULL; char ** OUT_result; dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_STRV, &OUT_result, G_TYPE_INVALID); @@ -415,7 +415,7 @@ static void org_freedesktop_Tracker_Keywords_get_list_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - DBusGAsyncData *data = user_data; + DBusGAsyncData *data = (DBusGAsyncData*) user_data; GError *error = NULL; GPtrArray* OUT_value; dbus_g_proxy_end_call (proxy, call, &error, dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRV), &OUT_value, G_TYPE_INVALID); @@ -453,7 +453,7 @@ static void org_freedesktop_Tracker_Keywords_get_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - DBusGAsyncData *data = user_data; + DBusGAsyncData *data = (DBusGAsyncData*) user_data; GError *error = NULL; char ** OUT_value; dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_STRV, &OUT_value, G_TYPE_INVALID); @@ -491,7 +491,7 @@ static void org_freedesktop_Tracker_Keywords_add_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - DBusGAsyncData *data = user_data; + DBusGAsyncData *data = (DBusGAsyncData*) user_data; GError *error = NULL; dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); (*(org_freedesktop_Tracker_Keywords_add_reply)data->cb) (proxy, error, data->userdata); @@ -528,7 +528,7 @@ static void org_freedesktop_Tracker_Keywords_remove_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - DBusGAsyncData *data = user_data; + DBusGAsyncData *data = (DBusGAsyncData*) user_data; GError *error = NULL; dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); (*(org_freedesktop_Tracker_Keywords_remove_reply)data->cb) (proxy, error, data->userdata); @@ -565,7 +565,7 @@ static void org_freedesktop_Tracker_Keywords_remove_all_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - DBusGAsyncData *data = user_data; + DBusGAsyncData *data = (DBusGAsyncData*) user_data; GError *error = NULL; dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); (*(org_freedesktop_Tracker_Keywords_remove_all_reply)data->cb) (proxy, error, data->userdata); @@ -602,7 +602,7 @@ static void org_freedesktop_Tracker_Keywords_search_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - DBusGAsyncData *data = user_data; + DBusGAsyncData *data = (DBusGAsyncData*) user_data; GError *error = NULL; char ** OUT_result; dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_STRV, &OUT_result, G_TYPE_INVALID); @@ -645,7 +645,7 @@ static void org_freedesktop_Tracker_Search_get_hit_count_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - DBusGAsyncData *data = user_data; + DBusGAsyncData *data = (DBusGAsyncData*) user_data; GError *error = NULL; gint OUT_result; dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INT, &OUT_result, G_TYPE_INVALID); @@ -683,7 +683,7 @@ static void org_freedesktop_Tracker_Search_get_hit_count_all_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - DBusGAsyncData *data = user_data; + DBusGAsyncData *data = (DBusGAsyncData*) user_data; GError *error = NULL; GPtrArray* OUT_result; dbus_g_proxy_end_call (proxy, call, &error, dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRV), &OUT_result, G_TYPE_INVALID); @@ -721,7 +721,7 @@ static void org_freedesktop_Tracker_Search_text_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - DBusGAsyncData *data = user_data; + DBusGAsyncData *data = (DBusGAsyncData*) user_data; GError *error = NULL; char ** OUT_result; dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_STRV, &OUT_result, G_TYPE_INVALID); @@ -759,7 +759,7 @@ static void org_freedesktop_Tracker_Search_text_detailed_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - DBusGAsyncData *data = user_data; + DBusGAsyncData *data = (DBusGAsyncData*) user_data; GError *error = NULL; GPtrArray* OUT_result; dbus_g_proxy_end_call (proxy, call, &error, dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRV), &OUT_result, G_TYPE_INVALID); @@ -797,7 +797,7 @@ static void org_freedesktop_Tracker_Search_get_snippet_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - DBusGAsyncData *data = user_data; + DBusGAsyncData *data = (DBusGAsyncData*) user_data; GError *error = NULL; char * OUT_result; dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_STRING, &OUT_result, G_TYPE_INVALID); @@ -835,7 +835,7 @@ static void org_freedesktop_Tracker_Search_metadata_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - DBusGAsyncData *data = user_data; + DBusGAsyncData *data = (DBusGAsyncData*) user_data; GError *error = NULL; char ** OUT_result; dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_STRV, &OUT_result, G_TYPE_INVALID); @@ -873,7 +873,7 @@ static void org_freedesktop_Tracker_Search_query_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - DBusGAsyncData *data = user_data; + DBusGAsyncData *data = (DBusGAsyncData*) user_data; GError *error = NULL; GPtrArray* OUT_result; dbus_g_proxy_end_call (proxy, call, &error, dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRV), &OUT_result, G_TYPE_INVALID); @@ -895,6 +895,44 @@ stuff->userdata = userdata; return dbus_g_proxy_begin_call (proxy, "Query", org_freedesktop_Tracker_Search_query_async_callback, stuff, g_free, G_TYPE_INT, IN_live_query_id, G_TYPE_STRING, IN_service, G_TYPE_STRV, IN_fields, G_TYPE_STRING, IN_search_text, G_TYPE_STRING, IN_keyword, G_TYPE_STRING, IN_query_condition, G_TYPE_BOOLEAN, IN_sort_by_service, G_TYPE_INT, IN_offset, G_TYPE_INT, IN_max_hits, G_TYPE_INVALID); } +static +#ifdef G_HAVE_INLINE +inline +#endif +gboolean +org_freedesktop_Tracker_Search_suggest (DBusGProxy *proxy, const char * IN_search_text, const gint IN_maxdist, char ** OUT_result, GError **error) + +{ + return dbus_g_proxy_call (proxy, "Suggest", error, G_TYPE_STRING, IN_search_text, G_TYPE_INT, IN_maxdist, G_TYPE_INVALID, G_TYPE_STRING, OUT_result, G_TYPE_INVALID); +} + +typedef void (*org_freedesktop_Tracker_Search_suggest_reply) (DBusGProxy *proxy, char * OUT_result, GError *error, gpointer userdata); + +static void +org_freedesktop_Tracker_Search_suggest_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) +{ + DBusGAsyncData *data = (DBusGAsyncData*) user_data; + GError *error = NULL; + char * OUT_result; + dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_STRING, &OUT_result, G_TYPE_INVALID); + (*(org_freedesktop_Tracker_Search_suggest_reply)data->cb) (proxy, OUT_result, error, data->userdata); + return; +} + +static +#ifdef G_HAVE_INLINE +inline +#endif +DBusGProxyCall* +org_freedesktop_Tracker_Search_suggest_async (DBusGProxy *proxy, const char * IN_search_text, const gint IN_maxdist, org_freedesktop_Tracker_Search_suggest_reply callback, gpointer userdata) + +{ + DBusGAsyncData *stuff; + stuff = g_new (DBusGAsyncData, 1); + stuff->cb = G_CALLBACK (callback); + stuff->userdata = userdata; + return dbus_g_proxy_begin_call (proxy, "Suggest", org_freedesktop_Tracker_Search_suggest_async_callback, stuff, g_free, G_TYPE_STRING, IN_search_text, G_TYPE_INT, IN_maxdist, G_TYPE_INVALID); +} #endif /* defined DBUS_GLIB_CLIENT_WRAPPERS_org_freedesktop_Tracker_Search */ #ifndef DBUS_GLIB_CLIENT_WRAPPERS_org_freedesktop_Tracker_Files @@ -916,7 +954,7 @@ static void org_freedesktop_Tracker_Files_exists_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - DBusGAsyncData *data = user_data; + DBusGAsyncData *data = (DBusGAsyncData*) user_data; GError *error = NULL; gboolean OUT_result; dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_BOOLEAN, &OUT_result, G_TYPE_INVALID); @@ -954,7 +992,7 @@ static void org_freedesktop_Tracker_Files_create_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - DBusGAsyncData *data = user_data; + DBusGAsyncData *data = (DBusGAsyncData*) user_data; GError *error = NULL; dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); (*(org_freedesktop_Tracker_Files_create_reply)data->cb) (proxy, error, data->userdata); @@ -991,7 +1029,7 @@ static void org_freedesktop_Tracker_Files_delete_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - DBusGAsyncData *data = user_data; + DBusGAsyncData *data = (DBusGAsyncData*) user_data; GError *error = NULL; dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); (*(org_freedesktop_Tracker_Files_delete_reply)data->cb) (proxy, error, data->userdata); @@ -1028,7 +1066,7 @@ static void org_freedesktop_Tracker_Files_get_service_type_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - DBusGAsyncData *data = user_data; + DBusGAsyncData *data = (DBusGAsyncData*) user_data; GError *error = NULL; char * OUT_result; dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_STRING, &OUT_result, G_TYPE_INVALID); @@ -1066,7 +1104,7 @@ static void org_freedesktop_Tracker_Files_get_text_contents_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - DBusGAsyncData *data = user_data; + DBusGAsyncData *data = (DBusGAsyncData*) user_data; GError *error = NULL; char * OUT_result; dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_STRING, &OUT_result, G_TYPE_INVALID); @@ -1104,7 +1142,7 @@ static void org_freedesktop_Tracker_Files_search_text_contents_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - DBusGAsyncData *data = user_data; + DBusGAsyncData *data = (DBusGAsyncData*) user_data; GError *error = NULL; char * OUT_result; dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_STRING, &OUT_result, G_TYPE_INVALID); @@ -1142,7 +1180,7 @@ static void org_freedesktop_Tracker_Files_get_by_service_type_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - DBusGAsyncData *data = user_data; + DBusGAsyncData *data = (DBusGAsyncData*) user_data; GError *error = NULL; char ** OUT_result; dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_STRV, &OUT_result, G_TYPE_INVALID); @@ -1180,7 +1218,7 @@ static void org_freedesktop_Tracker_Files_get_by_mime_type_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - DBusGAsyncData *data = user_data; + DBusGAsyncData *data = (DBusGAsyncData*) user_data; GError *error = NULL; char ** OUT_result; dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_STRV, &OUT_result, G_TYPE_INVALID); @@ -1218,7 +1256,7 @@ static void org_freedesktop_Tracker_Files_get_by_mime_type_vfs_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - DBusGAsyncData *data = user_data; + DBusGAsyncData *data = (DBusGAsyncData*) user_data; GError *error = NULL; char ** OUT_result; dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_STRV, &OUT_result, G_TYPE_INVALID); @@ -1256,7 +1294,7 @@ static void org_freedesktop_Tracker_Files_refresh_metadata_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - DBusGAsyncData *data = user_data; + DBusGAsyncData *data = (DBusGAsyncData*) user_data; GError *error = NULL; dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); (*(org_freedesktop_Tracker_Files_refresh_metadata_reply)data->cb) (proxy, error, data->userdata); @@ -1293,7 +1331,7 @@ static void org_freedesktop_Tracker_Files_get_mtime_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - DBusGAsyncData *data = user_data; + DBusGAsyncData *data = (DBusGAsyncData*) user_data; GError *error = NULL; gint OUT_result; dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INT, &OUT_result, G_TYPE_INVALID); @@ -1331,7 +1369,7 @@ static void org_freedesktop_Tracker_Files_get_metadata_for_files_in_folder_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - DBusGAsyncData *data = user_data; + DBusGAsyncData *data = (DBusGAsyncData*) user_data; GError *error = NULL; GPtrArray* OUT_values; dbus_g_proxy_end_call (proxy, call, &error, dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRV), &OUT_values, G_TYPE_INVALID); @@ -1369,7 +1407,7 @@ static void org_freedesktop_Tracker_Files_search_by_text_and_mime_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - DBusGAsyncData *data = user_data; + DBusGAsyncData *data = (DBusGAsyncData*) user_data; GError *error = NULL; char ** OUT_result; dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_STRV, &OUT_result, G_TYPE_INVALID); @@ -1407,7 +1445,7 @@ static void org_freedesktop_Tracker_Files_search_by_text_and_mime_and_location_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - DBusGAsyncData *data = user_data; + DBusGAsyncData *data = (DBusGAsyncData*) user_data; GError *error = NULL; char ** OUT_result; dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_STRV, &OUT_result, G_TYPE_INVALID); @@ -1445,7 +1483,7 @@ static void org_freedesktop_Tracker_Files_search_by_text_and_location_async_callback (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data) { - DBusGAsyncData *data = user_data; + DBusGAsyncData *data = (DBusGAsyncData*) user_data; GError *error = NULL; char ** OUT_result; dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_STRV, &OUT_result, G_TYPE_INVALID); Index: src/tracker-search-tool/tracker-search-tool.h =================================================================== --- src/tracker-search-tool/tracker-search-tool.h (revision 527) +++ src/tracker-search-tool/tracker-search-tool.h (working copy) @@ -121,7 +121,7 @@ int type; service_info_t *current_service; GtkWidget *metatile; - GtkWidget *no_results_label; + GtkWidget *no_results; GtkWidget *initial_label; GtkWidget *count_label; GtkWidget *message_box; Index: src/tracker-search-tool/tracker-search-tool-callbacks.c =================================================================== --- src/tracker-search-tool/tracker-search-tool-callbacks.c (revision 527) +++ src/tracker-search-tool/tracker-search-tool-callbacks.c (working copy) @@ -1795,3 +1795,18 @@ } return FALSE; } + +void +suggest_search_cb (GtkWidget *widget, + gpointer data) +{ + GSearchWindow *gsearch = data; + gchar *suggest; + + suggest = g_object_get_data (G_OBJECT (widget), "suggestion"); + + gtk_entry_set_text (GTK_ENTRY (gsearch->search_entry), suggest); + gtk_button_clicked (GTK_BUTTON (gsearch->find_button)); + +} + Index: src/tracker-search-tool/tracker-search-tool.c =================================================================== --- src/tracker-search-tool/tracker-search-tool.c (revision 527) +++ src/tracker-search-tool/tracker-search-tool.c (working copy) @@ -261,9 +261,15 @@ /* } */ +static gboolean +cancel_last_call (gpointer user_data) +{ + g_print ("tracker_cancel_last_call ();\n"); + tracker_cancel_last_call (tracker_client); + return FALSE; +} - static void display_dialog_character_set_conversion_error (GtkWidget * window, gchar * string, @@ -776,13 +782,74 @@ } static void +set_suggestion (gchar *suggestion, GError *error, gpointer *user_data) +{ + gchar *str; + + GtkWidget *label; + GtkWidget *box1, *box2; + GtkWidget *button; + + GSearchWindow *gsearch = user_data[0]; + gint timeout_id = GPOINTER_TO_INT (user_data[1]); + + gchar *search_term = (gchar *) gtk_entry_get_text (GTK_ENTRY (gsearch->search_entry)); + + g_source_remove (timeout_id); + g_free (user_data); + + if (strcmp (search_term, suggestion) == 0) { + return; + } + + box1 = gtk_hbox_new (FALSE, 0); + box2 = gtk_hbox_new (FALSE, 0); + label = gtk_label_new (_("Did you mean")); + gtk_box_pack_start (GTK_BOX (box2), label, FALSE, TRUE, 0); + + str = g_strconcat ("", suggestion, "?", NULL); + button = gtk_button_new (); + gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE); + label = gtk_label_new (NULL); + gtk_label_set_markup (label, str); + g_free (str); + gtk_container_add (GTK_CONTAINER (button), label); + gtk_box_pack_start (GTK_BOX (box2), button, FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (gsearch->no_results), box1, FALSE, FALSE, 12); + gtk_widget_show_all (box1); + + + g_object_set_data (G_OBJECT (button), "suggestion", suggestion); + g_signal_connect (G_OBJECT (button), "clicked", + G_CALLBACK (suggest_search_cb), gsearch); + +} + +static void add_no_files_found_message (GSearchWindow * gsearch) { - if (!gsearch->no_results_label) { + GtkWidget *label; + gchar *search_term = (gchar *) gtk_entry_get_text (GTK_ENTRY (gsearch->search_entry)); + gint id; + gpointer *args; - gsearch->no_results_label = gtk_label_new (_("Your search returned no results.")); - gtk_widget_show (gsearch->no_results_label); - gtk_box_pack_start (GTK_BOX (gsearch->message_box), gsearch->no_results_label, TRUE, TRUE, 12); + if (!gsearch->no_results) { + + gsearch->no_results = gtk_vbox_new (FALSE, 0); + label = gtk_label_new (_("Your search returned no results.")); + gtk_box_pack_start (GTK_BOX (gsearch->no_results), label, FALSE, FALSE, 12); + + gtk_box_pack_start (GTK_BOX (gsearch->message_box), gsearch->no_results, TRUE, TRUE, 12); + gtk_widget_show_all (gsearch->no_results); + + id = g_timeout_add (1000, cancel_last_call, NULL); + + args = g_new0 (gpointer, 2); + args[0] = gsearch; + args[1] = GINT_TO_POINTER (id); + + tracker_search_suggest_async (tracker_client, search_term, 4, set_suggestion, args); } @@ -2250,9 +2317,9 @@ gsearch->initial_label = NULL; } - if (gsearch->no_results_label) { - gtk_widget_destroy (gsearch->no_results_label); - gsearch->no_results_label = NULL; + if (gsearch->no_results) { + gtk_widget_destroy (gsearch->no_results); + gsearch->no_results = NULL; } @@ -2624,7 +2691,7 @@ gtk_box_pack_start (GTK_BOX (vbox), gsearch->initial_label, TRUE, TRUE, 12); - gsearch->no_results_label = NULL; + gsearch->no_results = NULL; gtk_widget_show (gsearch->initial_label); Index: src/tracker-search-tool/tracker-search-tool-callbacks.h =================================================================== --- src/tracker-search-tool/tracker-search-tool-callbacks.h (revision 527) +++ src/tracker-search-tool/tracker-search-tool-callbacks.h (working copy) @@ -177,6 +177,10 @@ GdkEventWindowState * event, gpointer data); +void +suggest_search_cb (GtkWidget *widget, + gpointer data); + #ifdef __cplusplus } #endif Index: data/tracker-introspect.xml =================================================================== --- data/tracker-introspect.xml (revision 527) +++ data/tracker-introspect.xml (working copy) @@ -323,7 +323,15 @@ + + + + + + +