Back to index

indicator-appmenu  12.10.0
hudresult.c
Go to the documentation of this file.
00001 /*
00002  * Copyright © 2012 Canonical Ltd.
00003  *
00004  * This program is free software: you can redistribute it and/or modify it
00005  * under the terms of the GNU General Public License version 3, as
00006  * published by the Free Software Foundation.
00007  *
00008  * This program is distributed in the hope that it will be useful, but
00009  * WITHOUT ANY WARRANTY; without even the implied warranties of
00010  * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
00011  * PURPOSE.  See the GNU General Public License for more details.
00012  *
00013  * You should have received a copy of the GNU General Public License along
00014  * with this program.  If not, see <http://www.gnu.org/licenses/>.
00015  *
00016  * Author: Ryan Lortie <desrt@desrt.ca>
00017  */
00018 
00019 #include "hudresult.h"
00020 
00021 #include <string.h>
00022 
00023 #include "hudsettings.h"
00024 #include "hudtoken.h"
00025 
00042 typedef GObjectClass HudResultClass;
00043 
00044 struct _HudResult
00045 {
00046   GObject parent_instance;
00047 
00048   HudItem *item;
00049 
00050   guint   distance;
00051   const gchar **matched;
00052   gchar  *description;
00053 };
00054 
00055 G_DEFINE_TYPE (HudResult, hud_result, G_TYPE_OBJECT)
00056 
00057 static void
00058 hud_result_finalize (GObject *object)
00059 {
00060   HudResult *result = HUD_RESULT (object);
00061 
00062   g_object_unref (result->item);
00063   g_free (result->matched);
00064   g_free (result->description);
00065 
00066   G_OBJECT_CLASS (hud_result_parent_class)
00067     ->finalize (object);
00068 }
00069 
00070 static void
00071 hud_result_init (HudResult *result)
00072 {
00073 }
00074 
00075 static void
00076 hud_result_class_init (HudResultClass *class)
00077 {
00078   class->finalize = hud_result_finalize;
00079 }
00080 
00101 HudResult *
00102 hud_result_get_if_matched (HudItem      *item,
00103                            HudTokenList *search_tokens,
00104                            guint         penalty)
00105 {
00106   if (!hud_item_get_enabled (item))
00107     return NULL;
00108 
00109   /* ignore the penalty in the max-distance calculation */
00110   if (hud_token_list_distance (hud_item_get_token_list (item), search_tokens, NULL) <= hud_settings.max_distance)
00111     return hud_result_new (item, search_tokens, penalty);
00112   else
00113     return NULL;
00114 }
00115 
00116 /* recurse so that we can avoid having to prepend the string */
00117 static void
00118 hud_result_format_tokens (GString       *string,
00119                           HudStringList *tokens)
00120 {
00121   HudStringList *tail;
00122   gchar *escaped;
00123 
00124   tail = hud_string_list_get_tail (tokens);
00125 
00126   if (tail)
00127     {
00128       hud_result_format_tokens (string, tail);
00129       g_string_append (string, " &gt; ");
00130     }
00131 
00132   escaped = g_markup_escape_text (hud_string_list_get_head (tokens), -1);
00133   g_string_append (string, escaped);
00134   g_free (escaped);
00135 }
00136 
00137 static void
00138 hud_result_format_description (HudResult *result)
00139 {
00140   GString *description;
00141   gint i;
00142 
00143   description = g_string_new (NULL);
00144   hud_result_format_tokens (description, hud_item_get_tokens (result->item));
00145 
00146   for (i = 0; result->matched[i]; i++)
00147     {
00148       gchar *escaped;
00149       gchar *match;
00150 
00151       escaped = g_markup_escape_text (result->matched[i], -1);
00152       match = strstr (description->str, escaped);
00153 
00154       if (match != NULL)
00155         {
00156           gsize start, end;
00157 
00158           start = match - description->str;
00159           end = start + strlen (escaped);
00160 
00161           /* modify the end first so that the modification to the start
00162            * doesn't change the offset of the end */
00163           g_string_insert (description, end, "</b>");
00164           g_string_insert (description, start, "<b>");
00165         }
00166 
00167       g_free (escaped);
00168     }
00169 
00170   result->description = g_string_free (description, FALSE);
00171 }
00172 
00187 HudResult *
00188 hud_result_new (HudItem      *item,
00189                 HudTokenList *search_tokens,
00190                 guint         penalty)
00191 {
00192   HudResult *result;
00193 
00194   g_return_val_if_fail (HUD_IS_ITEM (item), NULL);
00195   g_return_val_if_fail (search_tokens != NULL, NULL);
00196 
00197   result = g_object_new (HUD_TYPE_RESULT, NULL);
00198   result->item = g_object_ref (item);
00199   result->distance = hud_token_list_distance (hud_item_get_token_list (item), search_tokens, &result->matched);
00200   hud_result_format_description (result);
00201 
00202   result->distance += (result->distance * penalty) / 100;
00203 
00204   if (result->distance == 0 && penalty > 0)
00205     result->distance = 1;
00206 
00207   return result;
00208 }
00209 
00227 guint
00228 hud_result_get_distance (HudResult *result,
00229                          guint      max_usage)
00230 {
00231   guint distance;
00232 
00233   g_return_val_if_fail (HUD_IS_RESULT (result), G_MAXINT);
00234 
00235   distance = result->distance;
00236 
00237   if (max_usage != 0)
00238     {
00239       guint usage, inverse_usage;
00240 
00241       usage = hud_item_get_usage (result->item);
00242       inverse_usage = max_usage - usage;
00243       distance += (distance * inverse_usage) / max_usage;
00244     }
00245 
00246   return distance;
00247 }
00248 
00257 HudItem *
00258 hud_result_get_item (HudResult *result)
00259 {
00260   return result->item;
00261 }
00262 
00272 const gchar *
00273 hud_result_get_html_description (HudResult *result)
00274 {
00275   return result->description;
00276 }