Revision: 2266
http://gtkpod.svn.sourceforge.net/gtkpod/?rev=2266&view=rev
Author: jcsjcs
Date: 2009-02-28 13:49:10 +0000 (Sat, 28 Feb 2009)
Log Message:
-----------
* src/misc.h
src/display.h
src/sort_window.c
src/display_sorttabs.c
src/misc.c:
Optimation in the sort code -- thanks to javier Kohen for
the patches.
Modified Paths:
--------------
gtkpod/trunk/ChangeLog
gtkpod/trunk/src/display.h
gtkpod/trunk/src/display_sorttabs.c
gtkpod/trunk/src/misc.c
gtkpod/trunk/src/misc.h
gtkpod/trunk/src/sort_window.c
Modified: gtkpod/trunk/ChangeLog
===================================================================
--- gtkpod/trunk/ChangeLog 2009-02-28 13:19:48 UTC (rev 2265)
+++ gtkpod/trunk/ChangeLog 2009-02-28 13:49:10 UTC (rev 2266)
@@ -1,5 +1,15 @@
2009-02-28 Jorg Schuler <jcsjcs at users.sourceforge.net>
+ * src/misc.h
+ src/display.h
+ src/sort_window.c
+ src/display_sorttabs.c
+ src/misc.c:
+ Optimation in the sort code -- thanks to javier Kohen for
+ the patches.
+
+2009-02-28 Jorg Schuler <jcsjcs at users.sourceforge.net>
+
* src/display_coverart.c
src/display_tracks.c
src/display_sorttabs.c:
Modified: gtkpod/trunk/src/display.h
===================================================================
--- gtkpod/trunk/src/display.h 2009-02-28 13:19:48 UTC (rev 2265)
+++ gtkpod/trunk/src/display.h 2009-02-28 13:49:10 UTC (rev 2266)
@@ -90,6 +90,19 @@
/* struct for each entry in sort tab */
typedef struct {
gchar *name;
+
+ /* The sort key can be compared with other sort keys using strcmp
+ * and it will give the expected result, according to the user
+ * settings. Must be regenerated if the user settings change.
+ */
+ gchar *name_sortkey;
+
+ /* The fuzzy sortkey can be used to compare discarding some
+ * prefixes, such as "the", "el", "la", etc. If NULL, you should use
+ * name_sortkey instead.
+ */
+ gchar *name_fuzzy_sortkey;
+
gboolean master; /* set if this is the "All" entry */
gboolean compilation; /* set if this is the "Compilation" entry */
GList *members; /* GList with member tracks (pointer to "Track") */
@@ -128,7 +141,7 @@
TimeInfo ti_played; /* TimeInfo "played" (sp) */
GtkTooltipsData *sp_tooltips_data; /* ptr to tooltips in special st */
/* function used for string comparisons, set in on_st_switch_page */
- gint (*string_compare_func) (const gchar *str1, const gchar *str2);
+ gint (*entry_compare_func) (const TabEntry *a, const TabEntry *b);
} SortTab;
/* "Column numbers" in sort tab model */
@@ -333,7 +346,9 @@
void st_adopt_order_in_playlist (void);
TabEntry *st_get_selected_entry (gint inst);
void st_update_paned_position ();
+void st_rebuild_sortkeys ();
+
void cal_open_calendar (gint inst, T_item item);
void sp_go (guint32 inst);
void sp_conditions_changed (guint32 inst);
Modified: gtkpod/trunk/src/display_sorttabs.c
===================================================================
--- gtkpod/trunk/src/display_sorttabs.c 2009-02-28 13:19:48 UTC (rev 2265)
+++ gtkpod/trunk/src/display_sorttabs.c 2009-02-28 13:49:10 UTC (rev 2266)
@@ -263,7 +263,50 @@
return FALSE;
}
+static void
+st_build_sortkeys (TabEntry *entry)
+{
+ C_FREE (entry->name_sortkey);
+ C_FREE (entry->name_fuzzy_sortkey);
+ entry->name_sortkey = make_sortkey (entry->name);
+ if (entry->name != fuzzy_skip_prefix (entry->name))
+ {
+ entry->name_fuzzy_sortkey =
+ make_sortkey (fuzzy_skip_prefix (entry->name));
+ }
+}
+void
+st_rebuild_sortkeys ()
+{
+ gint inst;
+ for (inst = 0; inst < prefs_get_int("sort_tab_num"); inst++)
+ {
+ SortTab *st = sorttab[inst];
+ GList *entries;
+
+ for (entries = st->entries; entries; entries = g_list_next (entries))
+ {
+ TabEntry *entry = (TabEntry *)entries->data;
+ st_build_sortkeys (entry);
+ }
+ }
+}
+
+gint compare_entry (const TabEntry *a, const TabEntry *b)
+{
+ return strcmp (a->name_sortkey, b->name_sortkey);
+}
+
+gint compare_entry_fuzzy (const TabEntry *a, const TabEntry *b)
+{
+ const gchar *ka, *kb;
+ ka = a->name_fuzzy_sortkey ? a->name_fuzzy_sortkey : a->name_sortkey;
+ kb = b->name_fuzzy_sortkey ? b->name_fuzzy_sortkey : b->name_sortkey;
+ return strcmp (ka, kb);
+}
+
+
/* set string compare function according to whether the ignore field
is set or not */
static void st_set_string_compare_func (guint inst, guint page_num)
@@ -273,9 +316,9 @@
{
buf = g_strdup_printf ("sort_ign_field_%d", ST_to_T (page_num));
if (prefs_get_int (buf))
- sorttab[inst]->string_compare_func = compare_string_fuzzy;
+ sorttab[inst]->entry_compare_func = compare_entry_fuzzy;
else
- sorttab[inst]->string_compare_func = compare_string;
+ sorttab[inst]->entry_compare_func = compare_entry;
g_free (buf);
}
}
@@ -1087,7 +1130,9 @@
}
gtk_list_store_set (GTK_LIST_STORE (model), &iter,
ST_COLUMN_ENTRY, entry, -1);
- st->entries = g_list_append (st->entries, entry);
+ /* Prepend entry to the list, but always add after the master. */
+ st->entries = g_list_insert (st->entries, entry, 1);
+
if (!entry->master && !entry->compilation)
{
if (!st->entry_hash)
@@ -1145,6 +1190,8 @@
g_hash_table_remove (st->entry_hash, entry->name);
}
g_free (entry->name);
+ g_free (entry->name_sortkey);
+ g_free (entry->name_fuzzy_sortkey);
g_free (entry);
}
}
@@ -1573,6 +1620,7 @@
{ /* doesn't exist yet -- let's create it */
master_entry = g_malloc0 (sizeof (TabEntry));
master_entry->name = g_strdup (_("All"));
+ st_build_sortkeys (master_entry);
master_entry->master = TRUE;
master_entry->compilation = FALSE;
st_add_entry (master_entry, inst);
@@ -1604,6 +1652,7 @@
{
entry->name = g_strdup (entryname);
}
+ st_build_sortkeys (entry);
entry->compilation = group_track;
entry->master = FALSE;
st_add_entry (entry, inst);
@@ -2230,18 +2279,18 @@
if (hash_entry == entry)
g_hash_table_remove (st->entry_hash, entry->name);
/* replace entry name */
+ g_free (entry->name);
if (sorttab[inst]->current_category == ST_CAT_YEAR)
{ /* make sure the entry->name is identical to
atoi(new_text) */
- g_free (entry->name);
entry->name = g_strdup_printf ("%d", atoi (new_text));
g_object_set (G_OBJECT (renderer), "text", entry->name, NULL);
}
else
{
- g_free (entry->name);
entry->name = g_strdup (new_text);
}
+ st_build_sortkeys (entry);
/* re-insert into hash table if the same name doesn't
already exist */
@@ -2408,7 +2457,7 @@
st = sorttab[inst];
- return st->string_compare_func (entry1->name, entry2->name);
+ return st->entry_compare_func (entry1, entry2);
}
/* Stop editing. If @cancel is TRUE, the edited value will be
Modified: gtkpod/trunk/src/misc.c
===================================================================
--- gtkpod/trunk/src/misc.c 2009-02-28 13:19:48 UTC (rev 2265)
+++ gtkpod/trunk/src/misc.c 2009-02-28 13:49:10 UTC (rev 2266)
@@ -336,10 +336,15 @@
* depending on prefs settings */
gint compare_string (const gchar *str1, const gchar *str2)
{
- if (prefs_get_int("case_sensitive"))
- return strcmp (str1, str2);
- else
- return compare_string_case_insensitive (str1, str2);
+ gint result;
+ gchar *sortkey1 = make_sortkey (str1);
+ gchar *sortkey2 = make_sortkey (str2);
+
+ result = strcmp (sortkey1, sortkey2);
+
+ g_free (sortkey1);
+ g_free (sortkey2);
+ return result;
}
struct csfk
@@ -351,6 +356,30 @@
static GList *csfk_list = NULL;
+/* Returns the sortkey for an entry name.
+ *
+ * The sort key can be compared with other sort keys using strcmp and
+ * it will give the expected result, according to the user
+ * settings. Must be regenerated if the user settings change.
+ *
+ * The caller is responsible of freeing the returned key with g_free.
+ */
+gchar *
+make_sortkey (const gchar *name)
+{
+ if (prefs_get_int("case_sensitive"))
+ {
+ return g_utf8_collate_key (name, -1);
+ }
+ else
+ {
+ gchar *casefolded = g_utf8_casefold (name, -1);
+ gchar *key = g_utf8_collate_key (casefolded, -1);
+ g_free (casefolded);
+ return key;
+ }
+}
+
/* needs to be called everytime the sort_ign_strings in the prefs were
changed */
void compare_string_fuzzy_generate_keys (void)
@@ -387,87 +416,63 @@
csfk->key = g_utf8_collate_key (tempStr, -1 );
g_free (tempStr);
- csfk_list = g_list_append (csfk_list, csfk);
+ csfk_list = g_list_prepend (csfk_list, csfk);
}
prefs_free_list(sort_ign_strings);
}
-
-/* compare @str1 and @str2 case-sensitively or case-insensitively
- * depending on prefs settings, and ignoring certain initial articles
- * ("the", "le"/"la", etc) */
-gint compare_string_fuzzy (const gchar *str1, const gchar *str2)
+/* Returns a pointer inside the name, possibly skiping a prefix from
+ * the list generated by compare_string_fuzzy_generate_keys.
+ */
+const gchar *
+fuzzy_skip_prefix (const gchar *name)
{
- gchar *tempStr;
- gint result;
-
- gchar *cleanStr1 = g_utf8_casefold (str1, -1);
- gchar *cleanStr2 = g_utf8_casefold (str2, -1);
+ const gchar *result = name;
+ const GList *gl;
+ gchar *cleanStr;
- const gchar *pstr1 = str1;
- const gchar *pstr2 = str2;
- gchar *pcleanStr1 = cleanStr1;
- gchar *pcleanStr2 = cleanStr2;
-
- GList *gl;
-
/* If the article collations keys have not been generated,
* do that first
*/
if (!csfk_list)
compare_string_fuzzy_generate_keys ();
- if (!csfk_list)
- return compare_string (str1, str2);
+ cleanStr = g_utf8_casefold (name, -1);
- /* Check the beginnings of both strings for any of the
- * articles we should ignore
- */
- for (gl=csfk_list; gl; gl=gl->next)
+ for (gl=csfk_list; gl; gl=g_list_next(gl))
{
struct csfk *csfk = gl->data;
+ gchar *tempStr;
+
g_return_val_if_fail (csfk, 0);
- tempStr = g_utf8_collate_key (cleanStr1, csfk->length);
+
+ tempStr = g_utf8_collate_key (cleanStr, csfk->length);
if (strcmp (tempStr, csfk->key) == 0)
{
/* Found article, bump pointers ahead appropriate distance
*/
- pstr1 += csfk->length;
- pcleanStr1 = g_utf8_offset_to_pointer (cleanStr1, csfk->length);
+ result += csfk->length;
g_free (tempStr);
break;
}
g_free (tempStr);
}
- for (gl=csfk_list; gl; gl=gl->next)
- {
- struct csfk *csfk = gl->data;
- g_return_val_if_fail (csfk, 0);
- tempStr = g_utf8_collate_key (cleanStr2, csfk->length);
- if (strcmp (tempStr, csfk->key) == 0)
- {
- /* Found article, bump pointers ahead apropriate distance
- */
- pstr2 += csfk->length;
- pcleanStr2 = g_utf8_offset_to_pointer (cleanStr2, csfk->length);
- g_free (tempStr);
- break;
- }
- g_free (tempStr);
- }
- if (prefs_get_int("case_sensitive"))
- result = strcmp(pstr1, pstr2);
- else
- result = g_utf8_collate(pcleanStr1, pcleanStr2);
+ g_free (cleanStr);
- g_free (cleanStr1);
- g_free (cleanStr2);
return result;
}
/* compare @str1 and @str2 case-sensitively or case-insensitively
- * depending on prefs settings */
+ * depending on prefs settings, and ignoring certain initial articles
+ * ("the", "le"/"la", etc) */
+gint compare_string_fuzzy (const gchar *str1, const gchar *str2)
+{
+ return compare_string (fuzzy_skip_prefix (str1),
+ fuzzy_skip_prefix (str2));
+}
+
+/* compare @str1 and @str2 case-insensitively */
gint compare_string_case_insensitive (const gchar *str1, const gchar *str2)
{
gchar *string1 = g_utf8_casefold (str1, -1);
Modified: gtkpod/trunk/src/misc.h
===================================================================
--- gtkpod/trunk/src/misc.h 2009-02-28 13:19:48 UTC (rev 2265)
+++ gtkpod/trunk/src/misc.h 2009-02-28 13:49:10 UTC (rev 2266)
@@ -143,9 +143,11 @@
gchar *get_filesize_as_string (double size);
+gchar *make_sortkey (const gchar *name);
gint compare_string (const gchar *str1, const gchar *str2);
void compare_string_fuzzy_generate_keys (void);
gint compare_string_fuzzy (const gchar *str1, const gchar *str2);
+const gchar *fuzzy_skip_prefix (const gchar *sortkey);
gint compare_string_case_insensitive (const gchar *str1,
const gchar *str2);
gint compare_string_start_case_insensitive (const gchar *haystack,
Modified: gtkpod/trunk/src/sort_window.c
===================================================================
--- gtkpod/trunk/src/sort_window.c 2009-02-28 13:19:48 UTC (rev 2265)
+++ gtkpod/trunk/src/sort_window.c 2009-02-28 13:49:10 UTC (rev 2266)
@@ -487,6 +487,12 @@
/* update compare string keys */
compare_string_fuzzy_generate_keys ();
+ /* if case sensitive has changed, rebuild sortkeys */
+ if (temp_prefs_get_int_value(sort_temp_prefs, "case_sensitive", &val))
+ {
+ st_rebuild_sortkeys ();
+ temp_prefs_remove_key (sort_temp_prefs, "case_sensitive");
+ }
/* if sort type has changed, initialize display */
if (temp_prefs_get_int_value(sort_temp_prefs, "pm_sort", &val))
{
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA
-OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise
-Strategies to boost innovation and cut costs with open source participation
-Receive a $600 discount off the registration fee with the source code: SFAD
http://p.sf.net/sfu/XcvMzF8H
_______________________________________________
gtkpod-cvs2 mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/gtkpod-cvs2