aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/scan.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/scan.c')
-rw-r--r--[-rwxr-xr-x]src/scan.c547
1 files changed, 348 insertions, 199 deletions
diff --git a/src/scan.c b/src/scan.c
index ce080a0..a16adf9 100755..100644
--- a/src/scan.c
+++ b/src/scan.c
@@ -234,7 +234,9 @@ void Scan_Free_File_Fill_Tag_List (GList *list);
void Scan_Rename_Directory_Generate_Preview (void);
gchar **Scan_Return_File_Tag_Field_From_Mask_Code (File_Tag *FileTag, gchar code);
-void Scan_Process_Fields_Functions (gchar *string);
+void Scan_Process_Fields_Functions (gchar **string);
+
+gint Scan_Word_Is_Roman_Numeral (gchar *text);
void Process_Fields_Check_Button_Toggled (GtkObject *object, GList *list);
void Process_Fields_Convert_Check_Button_Toggled (GtkObject *object);
@@ -242,16 +244,17 @@ void Select_Fields_Invert_Selection (void);
void Select_Fields_Select_Unselect_All (void);
void Select_Fields_Set_Sensitive (void);
-void Mask_Editor_List_Row_Selected (GtkTreeSelection* selection, gpointer data);
-void Mask_Editor_List_New (void);
-void Mask_Editor_List_Duplicate (void);
-void Mask_Editor_List_Add (void);
-void Mask_Editor_List_Remove (void);
-void Mask_Editor_List_Move_Up (void);
-void Mask_Editor_List_Move_Down (void);
-void Mask_Editor_List_Save_Button (void);
-void Mask_Editor_Entry_Changed (void);
-gboolean Mask_Editor_List_Key_Press (GtkWidget *widget, GdkEvent *event);
+void Mask_Editor_List_Row_Selected (GtkTreeSelection* selection, gpointer data);
+void Mask_Editor_List_Set_Row_Visible (GtkTreeModel *treeModel, GtkTreeIter *rowIter);
+void Mask_Editor_List_New (void);
+void Mask_Editor_List_Duplicate (void);
+void Mask_Editor_List_Add (void);
+void Mask_Editor_List_Remove (void);
+void Mask_Editor_List_Move_Up (void);
+void Mask_Editor_List_Move_Down (void);
+void Mask_Editor_List_Save_Button (void);
+void Mask_Editor_Entry_Changed (void);
+gboolean Mask_Editor_List_Key_Press (GtkWidget *widget, GdkEvent *event);
void Mask_Editor_Clean_Up_Masks_List (void);
@@ -1067,18 +1070,14 @@ void Scan_Process_Fields (ET_File *ETFile)
File_Name *st_filename;
File_Tag *st_filetag;
gchar *filename_utf8;
- //GString *string2process;
- guint string_length;
- gchar *string;
- gchar *temp;
+ gchar *string;
if (!ScannerWindow || !ETFile) return;
- st_filename = (File_Name *)ETFile->FileNameNew->data;
- st_filetag = (File_Tag *)ETFile->FileTag->data;
- //string2process = g_string_sized_new(512);
-
+ st_filename = (File_Name *)ETFile->FileNameNew->data;
+ st_filetag = (File_Tag *)ETFile->FileTag->data;
+
/* Process the filename */
if (st_filename != NULL)
{
@@ -1092,17 +1091,11 @@ void Scan_Process_Fields (ET_File *ETFile)
if (!FileName)
FileName = ET_File_Name_Item_New();
- // FIX ME : we suppose that it will not grow more than 2 times its size...
- temp = g_path_get_basename(filename_utf8);
- string_length = 2 * g_utf8_strlen(temp,-1);
- string = g_malloc(string_length+1);
- strncpy(string,temp,string_length);
- g_free(temp);
- string[string_length]='\0';
+ string = g_path_get_basename(filename_utf8);
// Remove the extension to set it to lower case (to avoid problem with undo)
if ((pos=strrchr(string,'.'))!=NULL) *pos = 0;
- Scan_Process_Fields_Functions(string);
+ Scan_Process_Fields_Functions(&string);
string_utf8 = ET_File_Name_Generate(ETFile,string);
ET_Set_Filename_File_Name_Item(FileName,string_utf8,NULL);
@@ -1123,13 +1116,9 @@ void Scan_Process_Fields (ET_File *ETFile)
ET_Copy_File_Tag_Item(ETFile,FileTag);
}
- // FIX ME : we suppose that it will not grow more than 2 times its size...
- string_length = 2 * strlen(st_filetag->title);
- string = g_malloc(string_length+1);
- strncpy(string,st_filetag->title,string_length);
- string[string_length]='\0';
+ string = g_strdup(st_filetag->title);
- Scan_Process_Fields_Functions(string);
+ Scan_Process_Fields_Functions(&string);
ET_Set_Field_File_Tag_Item(&FileTag->title,string);
@@ -1145,13 +1134,9 @@ void Scan_Process_Fields (ET_File *ETFile)
ET_Copy_File_Tag_Item(ETFile,FileTag);
}
- // FIX ME : we suppose that it will not grow more than 2 times its size...
- string_length = 2 * strlen(st_filetag->artist);
- string = g_malloc(string_length+1);
- strncpy(string,st_filetag->artist,string_length);
- string[string_length]='\0';
-
- Scan_Process_Fields_Functions(string);
+ string = g_strdup(st_filetag->artist);
+
+ Scan_Process_Fields_Functions(&string);
ET_Set_Field_File_Tag_Item(&FileTag->artist,string);
@@ -1167,13 +1152,9 @@ void Scan_Process_Fields (ET_File *ETFile)
ET_Copy_File_Tag_Item(ETFile,FileTag);
}
- // FIX ME : we suppose that it will not grow more than 2 times its size...
- string_length = 2 * strlen(st_filetag->album);
- string = g_malloc(string_length+1);
- strncpy(string,st_filetag->album,string_length);
- string[string_length]='\0';
-
- Scan_Process_Fields_Functions(string);
+ string = g_strdup(st_filetag->album);
+
+ Scan_Process_Fields_Functions(&string);
ET_Set_Field_File_Tag_Item(&FileTag->album,string);
@@ -1189,13 +1170,9 @@ void Scan_Process_Fields (ET_File *ETFile)
ET_Copy_File_Tag_Item(ETFile,FileTag);
}
- // FIX ME : we suppose that it will not grow more than 2 times its size...
- string_length = 2 * strlen(st_filetag->genre);
- string = g_malloc(string_length+1);
- strncpy(string,st_filetag->genre,string_length);
- string[string_length]='\0';
-
- Scan_Process_Fields_Functions(string);
+ string = g_strdup(st_filetag->genre);
+
+ Scan_Process_Fields_Functions(&string);
ET_Set_Field_File_Tag_Item(&FileTag->genre,string);
@@ -1211,13 +1188,9 @@ void Scan_Process_Fields (ET_File *ETFile)
ET_Copy_File_Tag_Item(ETFile,FileTag);
}
- // FIX ME : we suppose that it will not grow more than 2 times its size...
- string_length = 2 * strlen(st_filetag->comment);
- string = g_malloc(string_length+1);
- strncpy(string,st_filetag->comment,string_length);
- string[string_length]='\0';
-
- Scan_Process_Fields_Functions(string);
+ string = g_strdup(st_filetag->comment);
+
+ Scan_Process_Fields_Functions(&string);
ET_Set_Field_File_Tag_Item(&FileTag->comment,string);
@@ -1233,13 +1206,9 @@ void Scan_Process_Fields (ET_File *ETFile)
ET_Copy_File_Tag_Item(ETFile,FileTag);
}
- // FIX ME : we suppose that it will not grow more than 2 times its size...
- string_length = 2 * strlen(st_filetag->composer);
- string = g_malloc(string_length+1);
- strncpy(string,st_filetag->composer,string_length);
- string[string_length]='\0';
-
- Scan_Process_Fields_Functions(string);
+ string = g_strdup(st_filetag->composer);
+
+ Scan_Process_Fields_Functions(&string);
ET_Set_Field_File_Tag_Item(&FileTag->composer,string);
@@ -1255,13 +1224,9 @@ void Scan_Process_Fields (ET_File *ETFile)
ET_Copy_File_Tag_Item(ETFile,FileTag);
}
- // FIX ME : we suppose that it will not grow more than 2 times its size...
- string_length = 2 * strlen(st_filetag->orig_artist);
- string = g_malloc(string_length+1);
- strncpy(string,st_filetag->orig_artist,string_length);
- string[string_length]='\0';
-
- Scan_Process_Fields_Functions(string);
+ string = g_strdup(st_filetag->orig_artist);
+
+ Scan_Process_Fields_Functions(&string);
ET_Set_Field_File_Tag_Item(&FileTag->orig_artist,string);
@@ -1277,13 +1242,9 @@ void Scan_Process_Fields (ET_File *ETFile)
ET_Copy_File_Tag_Item(ETFile,FileTag);
}
- // FIX ME : we suppose that it will not grow more than 2 times its size...
- string_length = 2 * strlen(st_filetag->copyright);
- string = g_malloc(string_length+1);
- strncpy(string,st_filetag->copyright,string_length);
- string[string_length]='\0';
-
- Scan_Process_Fields_Functions(string);
+ string = g_strdup(st_filetag->copyright);
+
+ Scan_Process_Fields_Functions(&string);
ET_Set_Field_File_Tag_Item(&FileTag->copyright,string);
@@ -1299,13 +1260,9 @@ void Scan_Process_Fields (ET_File *ETFile)
ET_Copy_File_Tag_Item(ETFile,FileTag);
}
- // FIX ME : we suppose that it will not grow more than 2 times its size...
- string_length = 2 * strlen(st_filetag->url);
- string = g_malloc(string_length+1);
- strncpy(string,st_filetag->url,string_length);
- string[string_length]='\0';
-
- Scan_Process_Fields_Functions(string);
+ string = g_strdup(st_filetag->url);
+
+ Scan_Process_Fields_Functions(&string);
ET_Set_Field_File_Tag_Item(&FileTag->url,string);
@@ -1321,13 +1278,9 @@ void Scan_Process_Fields (ET_File *ETFile)
ET_Copy_File_Tag_Item(ETFile,FileTag);
}
- // FIX ME : we suppose that it will not grow more than 2 times its size...
- string_length = 2 * strlen(st_filetag->encoded_by);
- string = g_malloc(string_length+1);
- strncpy(string,st_filetag->encoded_by,string_length);
- string[string_length]='\0';
-
- Scan_Process_Fields_Functions(string);
+ string = g_strdup(st_filetag->encoded_by);
+
+ Scan_Process_Fields_Functions(&string);
ET_Set_Field_File_Tag_Item(&FileTag->encoded_by,string);
@@ -1346,51 +1299,50 @@ void Scan_Process_Fields (ET_File *ETFile)
}
-void Scan_Process_Fields_Functions (gchar *string)
+void Scan_Process_Fields_Functions (gchar **string)
{
-
if (GTK_TOGGLE_BUTTON(ProcessFieldsConvertIntoSpace)->active)
{
- Scan_Convert_Underscore_Into_Space(string);
- Scan_Convert_P20_Into_Space(string);
+ Scan_Convert_Underscore_Into_Space(*string);
+ Scan_Convert_P20_Into_Space(*string);
}
if (GTK_TOGGLE_BUTTON(ProcessFieldsConvertSpace)->active)
- Scan_Convert_Space_Into_Undescore(string);
+ Scan_Convert_Space_Into_Undescore(*string);
if (GTK_TOGGLE_BUTTON(ProcessFieldsInsertSpace)->active)
Scan_Process_Fields_Insert_Space(string);
if (GTK_TOGGLE_BUTTON(ProcessFieldsOnlyOneSpace)->active)
- Scan_Process_Fields_Keep_One_Space(string);
+ Scan_Process_Fields_Keep_One_Space(*string);
if (GTK_TOGGLE_BUTTON(ProcessFieldsConvert)->active)
- Scan_Convert(string);
+ Scan_Convert_Character(string);
if (GTK_TOGGLE_BUTTON(ProcessFieldsAllUppercase)->active)
- Scan_Process_Fields_All_Uppercase(string);
+ Scan_Process_Fields_All_Uppercase(*string);
if (GTK_TOGGLE_BUTTON(ProcessFieldsAllDowncase)->active)
- Scan_Process_Fields_All_Downcase(string);
+ Scan_Process_Fields_All_Downcase(*string);
if (GTK_TOGGLE_BUTTON(ProcessFieldsFirstLetterUppercase)->active)
- Scan_Process_Fields_Letter_Uppercase(string);
+ Scan_Process_Fields_Letter_Uppercase(*string);
if (GTK_TOGGLE_BUTTON(ProcessFieldsFirstLettersUppercase)->active)
- Scan_Process_Fields_First_Letters_Uppercase(string);
+ Scan_Process_Fields_First_Letters_Uppercase(*string);
if (GTK_TOGGLE_BUTTON(ProcessFieldsRemoveSpace)->active)
- Scan_Process_Fields_Remove_Space(string);
+ Scan_Process_Fields_Remove_Space(*string);
}
-void Scan_Process_Fields_All_Uppercase (gchar *text)
+void Scan_Process_Fields_All_Uppercase (gchar *string)
{
gchar *temp;
gchar temp2[6]; // Must have at least 6 bytes of space
gunichar c;
- for (temp = text; *temp; temp = g_utf8_next_char(temp))
+ for (temp = string; *temp; temp = g_utf8_next_char(temp))
{
c = g_utf8_get_char(temp);
if (g_unichar_islower(c))
@@ -1398,13 +1350,13 @@ void Scan_Process_Fields_All_Uppercase (gchar *text)
}
}
-void Scan_Process_Fields_All_Downcase (gchar *text)
+void Scan_Process_Fields_All_Downcase (gchar *string)
{
gchar *temp;
gchar temp2[6];
gunichar c;
- for (temp = text; *temp; temp = g_utf8_next_char(temp))
+ for (temp = string; *temp; temp = g_utf8_next_char(temp))
{
c = g_utf8_get_char(temp);
if (g_unichar_isupper(c))
@@ -1412,7 +1364,7 @@ void Scan_Process_Fields_All_Downcase (gchar *text)
}
}
-void Scan_Process_Fields_Letter_Uppercase (gchar *text)
+void Scan_Process_Fields_Letter_Uppercase (gchar *string)
{
gchar *temp;
gchar temp2[6];
@@ -1421,7 +1373,7 @@ void Scan_Process_Fields_Letter_Uppercase (gchar *text)
gchar utf8_character[6];
gchar *word, *word1, *word2;
- for (temp = text; *temp; temp = g_utf8_next_char(temp))
+ for (temp = string; *temp; temp = g_utf8_next_char(temp))
{
c = g_utf8_get_char(temp);
if (set_to_upper_case && g_unichar_islower(c))
@@ -1431,11 +1383,12 @@ void Scan_Process_Fields_Letter_Uppercase (gchar *text)
set_to_upper_case = FALSE; // After the first time, all will be down case
}
- temp = text;
+ temp = string;
// Uppercase again the word 'I' in english
while ( temp )
{
+ word = temp; // Needed if there is only one word
word1 = g_utf8_strchr(temp,-1,' ');
word2 = g_utf8_strchr(temp,-1,'_');
@@ -1447,6 +1400,7 @@ void Scan_Process_Fields_Letter_Uppercase (gchar *text)
else if (word2)
word = word2;
else
+ // Last word of the string
break;
// Go to first character of the word (char. after ' ' or '_')
@@ -1463,7 +1417,11 @@ void Scan_Process_Fields_Letter_Uppercase (gchar *text)
}
}
-void Scan_Process_Fields_First_Letters_Uppercase (gchar *text)
+/*
+ * Function to set the first letter of each word to uppercase, according the "Chicago Manual of Style"
+ * No needed to reallocate
+ */
+void Scan_Process_Fields_First_Letters_Uppercase (gchar *string)
{
/**** DANIEL TEST *****
gchar *iter;
@@ -1487,31 +1445,35 @@ void Scan_Process_Fields_First_Letters_Uppercase (gchar *text)
****/
/**** Barış Çiçek version ****/
gchar *word, *word1, *word2, *temp;
- gint i;
+ gint i, len;
gchar utf8_character[6];
gunichar c;
gboolean set_to_upper_case, set_to_upper_case_tmp;
// There have to be space at the end of words to seperate them from prefix
+ // Chicago Manual of Style "Heading caps" Capitalization Rules (CMS 1993, 282) (http://www.docstyles.com/cmscrib.htm#Note2)
gchar *exempt[] =
{
"a ", "a_",
+ "against ", "against_",
"an ", "an_",
"and ", "and_",
"at ", "at_",
+ "between ", "between_",
"but ", "but_",
- "feat. ", "feat._",
+ //"feat. ", "feat._", // Removed by Slash Bunny
"for ", "for_",
"in ", "in_",
"nor ", "nor_",
"of ", "of_",
- "off ", "off_",
+ //"off ", "off_", // Removed by Slash Bunny
"on ", "on_",
"or ", "or_",
- "over ", "over_",
+ //"over ", "over_", // Removed by Slash Bunny
"so ", "so_",
"the ", "the_",
"to ", "to_",
"with ", "with_",
+ "yet ", "yet_",
NULL
};
@@ -1519,25 +1481,33 @@ void Scan_Process_Fields_First_Letters_Uppercase (gchar *text)
{
exempt[0] = NULL;
}
- Scan_Process_Fields_All_Downcase(text);
+ Scan_Process_Fields_All_Downcase(string);
- if (!g_utf8_validate(text,-1,NULL))
+ if (!g_utf8_validate(string,-1,NULL))
{
Log_Print("Scan_Process_Fields_First_Letters_Uppercase: Not a valid utf8! quiting");
return;
}
// Removes trailing whitespace
- text = g_strchomp(text);
+ string = g_strchomp(string);
- temp = text;
+ temp = string;
- // Set first character to uppercase
- c = g_utf8_get_char(temp);
- strncpy(text, utf8_character, g_unichar_to_utf8(g_unichar_toupper(c), utf8_character));
+ // If the word is a roman numeral, capitalize all of it
+ if ((len = Scan_Word_Is_Roman_Numeral(temp)))
+ {
+ strncpy(string, g_utf8_strup(temp, len), len);
+ } else
+ {
+ // Set first character to uppercase
+ c = g_utf8_get_char(temp);
+ strncpy(string, utf8_character, g_unichar_to_utf8(g_unichar_toupper(c), utf8_character));
+ }
// Uppercase first character of each word, except for 'exempt[]' words lists
while ( temp )
{
+ word = temp; // Needed if there is only one word
word1 = g_utf8_strchr(temp,-1,' ');
word2 = g_utf8_strchr(temp,-1,'_');
@@ -1549,23 +1519,37 @@ void Scan_Process_Fields_First_Letters_Uppercase (gchar *text)
else if (word2)
word = word2;
else
+ {
+ // Last word of the string: the first letter is always uppercase,
+ // even if it's in the exempt list. This is a Chicago Manual of Style rule.
+ // Last Word In String - Should Capitalize Regardless of Word (Chicago Manual of Style)
+ c = g_utf8_get_char(word);
+ strncpy(word, utf8_character, g_unichar_to_utf8(g_unichar_toupper(c), utf8_character));
break;
+ }
// Go to first character of the word (char. after ' ' or '_')
word = word+1;
- // Set uppercase the first character of this word
- c = g_utf8_get_char(word);
- strncpy(word, utf8_character, g_unichar_to_utf8(g_unichar_toupper(c), utf8_character));
-
- // Set lowercase the first character of this word if found in the exempt words list
- for (i=0; exempt[i]!=NULL; i++)
+ // If the word is a roman numeral, capitalize all of it
+ if ((len = Scan_Word_Is_Roman_Numeral(word)))
+ {
+ strncpy(word, g_utf8_strup(word, len), len);
+ } else
{
- if (g_ascii_strncasecmp(exempt[i], word, strlen(exempt[i])) == 0)
+ // Set uppercase the first character of this word
+ c = g_utf8_get_char(word);
+ strncpy(word, utf8_character, g_unichar_to_utf8(g_unichar_toupper(c), utf8_character));
+
+ // Set lowercase the first character of this word if found in the exempt words list
+ for (i=0; exempt[i]!=NULL; i++)
{
- c = g_utf8_get_char(word);
- strncpy(word, utf8_character, g_unichar_to_utf8(g_unichar_tolower(c), utf8_character));
- break;
+ if (g_ascii_strncasecmp(exempt[i], word, strlen(exempt[i])) == 0)
+ {
+ c = g_utf8_get_char(word);
+ strncpy(word, utf8_character, g_unichar_to_utf8(g_unichar_tolower(c), utf8_character));
+ break;
+ }
}
}
@@ -1574,13 +1558,17 @@ void Scan_Process_Fields_First_Letters_Uppercase (gchar *text)
// Uppercase letter placed after some characters like '(', '[', '{'
set_to_upper_case = FALSE;
- for (temp = text; *temp; temp = g_utf8_next_char(temp))
+ for (temp = string; *temp; temp = g_utf8_next_char(temp))
{
c = g_utf8_get_char(temp);
set_to_upper_case_tmp = ( c == (gunichar)'('
|| c == (gunichar)'['
|| c == (gunichar)'{'
|| c == (gunichar)'"'
+ || c == (gunichar)':'
+ || c == (gunichar)'.'
+ || c == (gunichar)'`'
+ || c == (gunichar)'-'
) ? TRUE : FALSE;
if (set_to_upper_case && g_unichar_islower(c))
@@ -1591,11 +1579,12 @@ void Scan_Process_Fields_First_Letters_Uppercase (gchar *text)
}
-void Scan_Process_Fields_Remove_Space (gchar *text)
+void Scan_Process_Fields_Remove_Space (gchar *string)
{
gchar *tmp, *tmp1;
+
+ tmp = tmp1 = string;
- tmp = tmp1 = text;
while (*tmp)
{
while (*tmp == ' ')
@@ -1606,14 +1595,28 @@ void Scan_Process_Fields_Remove_Space (gchar *text)
*tmp1 = '\0';
}
-void Scan_Process_Fields_Insert_Space (gchar *text)
+/*
+ * The function inserts a space before an uppercase letter
+ * It is needed to realloc the memory!
+ */
+void Scan_Process_Fields_Insert_Space (gchar **string)
{
gchar *iter;
gunichar c;
gint j;
-
- // FIXME: try to use realloc
- for (iter = g_utf8_next_char(text); *iter; iter = g_utf8_next_char(iter)) // i=1 to not consider first "uppercase" letter
+ guint string_length;
+ gchar *string1;
+
+ // FIX ME : we suppose that it will not grow more than 2 times its size...
+ string_length = 2 * strlen(*string);
+ //string1 = g_realloc(*string, string_length+1);
+ string1 = g_malloc(string_length+1);
+ strncpy(string1,*string,string_length);
+ string1[string_length]='\0';
+ g_free(*string);
+ *string = string1;
+
+ for (iter = g_utf8_next_char(*string); *iter; iter = g_utf8_next_char(iter)) // At start : g_utf8_next_char to not consider first "uppercase" letter
{
c = g_utf8_get_char(iter);
@@ -1626,10 +1629,16 @@ void Scan_Process_Fields_Insert_Space (gchar *text)
}
}
}
-void Scan_Process_Fields_Keep_One_Space (gchar *text)
+
+/*
+ * The function removes the duplicated spaces
+ * No needed to reallocate
+ */
+void Scan_Process_Fields_Keep_One_Space (gchar *string)
{
gchar *tmp, *tmp1;
- tmp = tmp1 = text;
+
+ tmp = tmp1 = string;
// Remove multiple consecutive underscores and spaces.
while (*tmp1)
@@ -1647,6 +1656,7 @@ void Scan_Process_Fields_Keep_One_Space (gchar *text)
/*
* Function to replace underscore '_' by a space
+ * No needed to reallocate
*/
void Scan_Convert_Underscore_Into_Space (gchar *string)
{
@@ -1658,6 +1668,7 @@ void Scan_Convert_Underscore_Into_Space (gchar *string)
/*
* Function to replace %20 by a space
+ * No needed to reallocate
*/
void Scan_Convert_P20_Into_Space (gchar *string)
{
@@ -1675,6 +1686,7 @@ void Scan_Convert_P20_Into_Space (gchar *string)
/*
* Function to replace space by '_'
+ * No needed to reallocate
*/
void Scan_Convert_Space_Into_Undescore (gchar *string)
{
@@ -1688,17 +1700,113 @@ void Scan_Convert_Space_Into_Undescore (gchar *string)
* Replace something with something else ;)
* Currently this only works with one character for each
*/
-void Scan_Convert (gchar *string)
+void Scan_Convert_Character (gchar **string)
{
- gchar *tmp;
gchar *from = gtk_editable_get_chars(GTK_EDITABLE(ProcessFieldsConvertFrom),0,-1 );
gchar *to = gtk_editable_get_chars(GTK_EDITABLE(ProcessFieldsConvertTo),0,-1 );
-
- if ( from && to && strlen(from)>0 && strlen(to)>0 )
- while ((tmp=strchr(string,*from))!=NULL)
- *tmp = *to;
+ const gchar *s;
+ const gchar *current;
+ GSList *tokens_list, *list;
+ gchar *token;
+ gint n_tokens;
+ gchar **result;
+
+
+ tokens_list = NULL;
+ n_tokens = 0;
+ s = current = *string;
+
+ // Find tokens
+ if (strlen(from) > 0)
+ {
+ while (s
+ && *s != '\0'
+ && (s = g_strstr_len(current,strlen(current),from)) )
+ {
+ token = g_strndup(current, s - current);
+ tokens_list = g_slist_prepend(tokens_list, token);
+ n_tokens++;
+ current = s + strlen(from);
+ }
+ // For the last token
+ if (s == NULL)
+ {
+ token = g_strndup(current,strlen(current));
+ tokens_list = g_slist_prepend(tokens_list, token);
+ n_tokens++;
+ }
+ }else
+ {
+ // We search an empty string... we suppose it exists between each UTF-8 character
+ while (s
+ && *s != '\0'
+ && (s = g_utf8_find_next_char(current,NULL)) )
+ {
+ token = g_strndup(current, s - current);
+ tokens_list = g_slist_prepend(tokens_list, token);
+ n_tokens++;
+ current = s;
+ }
+ }
+
+ // Load the tokens list in an array for g_strjoinv
+ result = g_new (gchar *, n_tokens + 1);
+ result[n_tokens] = NULL;
+ for (list = tokens_list; list != NULL; list = list->next)
+ result[--n_tokens] = list->data;
+ g_slist_free(tokens_list);
+
+ g_free(*string);
+
+ // Join all the tokens with the 'to' separator
+ *string = g_strjoinv(to,result);
+
+ g_strfreev(result);
}
+/*
+ * Quick roman numeral check (non-roman numerals may also return true)
+ * Patch from Slash Bunny (2007.08.12)
+ * (http://home.hiwaay.net/~lkseitz/math/roman/numerals.shtml)
+ * I = 1 (one)
+ * V = 5 (five)
+ * X = 10 (ten)
+ * L = 50 (fifty)
+ * C = 100 (one hundred)
+ * D = 500 (five hundred)
+ * M = 1000 (one thousand)
+ */
+gint Scan_Word_Is_Roman_Numeral (gchar *text)
+{
+ gchar *tmp;
+ gint len;
+
+ tmp = text;
+ len = 0;
+
+ while (*tmp)
+ {
+ if (*tmp == (gunichar)'i' ||
+ *tmp == (gunichar)'v' ||
+ *tmp == (gunichar)'x' ||
+ *tmp == (gunichar)'l' ||
+ *tmp == (gunichar)'c' ||
+ *tmp == (gunichar)'d' ||
+ *tmp == (gunichar)'m')
+ {
+ tmp++;
+ len++;
+ } else if (*tmp == ' ' || *tmp == '_')
+ {
+ return len;
+ } else
+ {
+ return 0;
+ }
+ }
+
+ return len;
+}
/*
@@ -1830,13 +1938,16 @@ void Open_ScannerWindow (gint scanner_type)
gtk_widget_set_size_request(ScannerOptionCombo, 160, -1);
/* Option for Tag */
- gtk_combo_box_append_text(GTK_COMBO_BOX(ScannerOptionCombo), _(Scanner_Option_Menu_Items[SCANNER_FILL_TAG]));
+ gtk_combo_box_append_text(GTK_COMBO_BOX(ScannerOptionCombo),
+ _(Scanner_Option_Menu_Items[SCANNER_FILL_TAG]));
/* Option for FileName */
- gtk_combo_box_append_text(GTK_COMBO_BOX(ScannerOptionCombo), _(Scanner_Option_Menu_Items[SCANNER_RENAME_FILE]));
+ gtk_combo_box_append_text(GTK_COMBO_BOX(ScannerOptionCombo),
+ _(Scanner_Option_Menu_Items[SCANNER_RENAME_FILE]));
/* Option for ProcessFields */
- gtk_combo_box_append_text(GTK_COMBO_BOX(ScannerOptionCombo), _(Scanner_Option_Menu_Items[SCANNER_PROCESS_FIELDS]));
+ gtk_combo_box_append_text(GTK_COMBO_BOX(ScannerOptionCombo),
+ _(Scanner_Option_Menu_Items[SCANNER_PROCESS_FIELDS]));
// Selection of the item made at the end of the function
gtk_tooltips_set_tip(Tips, EventBox, _("Select the type of scanner to use"), NULL);
@@ -2135,19 +2246,23 @@ void Open_ScannerWindow (gint scanner_type)
gtk_box_pack_start(GTK_BOX(VBox),ProcessFieldsConvertIntoSpace,FALSE,FALSE,0);
gtk_box_pack_start(GTK_BOX(VBox),ProcessFieldsConvertSpace, FALSE,FALSE,0);
hbox = gtk_hbox_new(FALSE,2);
+ gtk_box_pack_start(GTK_BOX(VBox),hbox,FALSE,FALSE,0);
ProcessFieldsConvert = gtk_check_button_new_with_label(_("Convert:")); // Patch from Ben Hearsum, Oct. 3, 2003
ProcessFieldsConvertTo = gtk_entry_new();
ProcessFieldsConvertLabelTo = gtk_label_new(_("to: ")); // A "space" at the end to allow an other traduction for "to :" (needed in French!)
ProcessFieldsConvertFrom = gtk_entry_new();
- gtk_entry_set_max_length(GTK_ENTRY(ProcessFieldsConvertTo), 1);
- gtk_entry_set_max_length(GTK_ENTRY(ProcessFieldsConvertFrom), 1);
- gtk_widget_set_size_request(ProcessFieldsConvertTo,40,-1);
- gtk_widget_set_size_request(ProcessFieldsConvertFrom,40,-1);
+ //gtk_entry_set_max_length(GTK_ENTRY(ProcessFieldsConvertTo), 1); // Now, it isn't limited to one character
+ //gtk_entry_set_max_length(GTK_ENTRY(ProcessFieldsConvertFrom), 1);
+ gtk_widget_set_size_request(ProcessFieldsConvertTo,120,-1);
+ gtk_widget_set_size_request(ProcessFieldsConvertFrom,120,-1);
gtk_box_pack_start(GTK_BOX(hbox),ProcessFieldsConvert, FALSE,FALSE,0);
gtk_box_pack_start(GTK_BOX(hbox),ProcessFieldsConvertFrom, FALSE,FALSE,0);
- gtk_box_pack_start(GTK_BOX(hbox),ProcessFieldsConvertLabelTo,FALSE,FALSE,4);
+ gtk_box_pack_start(GTK_BOX(hbox),ProcessFieldsConvertLabelTo,FALSE,FALSE,0);
gtk_box_pack_start(GTK_BOX(hbox),ProcessFieldsConvertTo, FALSE,FALSE,0);
- gtk_box_pack_start(GTK_BOX(VBox),hbox,FALSE,FALSE,0);
+ if (PROCESS_FIELDS_CONVERT_FROM)
+ gtk_entry_set_text(GTK_ENTRY(ProcessFieldsConvertFrom),PROCESS_FIELDS_CONVERT_FROM);
+ if (PROCESS_FIELDS_CONVERT_TO)
+ gtk_entry_set_text(GTK_ENTRY(ProcessFieldsConvertTo),PROCESS_FIELDS_CONVERT_TO);
/* List creation for check buttons in group */
pf_cb_group1 = g_list_append (pf_cb_group1,ProcessFieldsConvertIntoSpace);
pf_cb_group1 = g_list_append (pf_cb_group1,ProcessFieldsConvertSpace);
@@ -2168,7 +2283,8 @@ void Open_ScannerWindow (gint scanner_type)
gtk_tooltips_set_tip(Tips,ProcessFieldsConvertSpace,
_("The space character is replaced by one underscore character. "
"Example, before: 'Text In An Entry', after: 'Text_In_An_Entry'."),NULL);
- gtk_tooltips_set_tip(Tips,ProcessFieldsConvert,_("Replace a character by an other one."),NULL);
+ gtk_tooltips_set_tip(Tips,ProcessFieldsConvert,
+ _("Replace a string by an other one. Note that the search is case sensitive."),NULL);
/* Separator line */
Separator = gtk_hseparator_new();
@@ -2217,16 +2333,16 @@ void Open_ScannerWindow (gint scanner_type)
gtk_box_pack_start(GTK_BOX(VBox),Separator,FALSE,FALSE,0);
/* Group: insert/remove spaces */
- ProcessFieldsRemoveSpace = gtk_check_button_new_with_label(_("Remove spaces"));
- ProcessFieldsInsertSpace = gtk_check_button_new_with_label(_("Insert a space before an uppercase letter"));
+ ProcessFieldsRemoveSpace = gtk_check_button_new_with_label(_("Remove spaces"));
+ ProcessFieldsInsertSpace = gtk_check_button_new_with_label(_("Insert a space before an uppercase letter"));
ProcessFieldsOnlyOneSpace = gtk_check_button_new_with_label(_("Remove duplicates of space or underscore"));
gtk_box_pack_start(GTK_BOX(VBox),ProcessFieldsRemoveSpace,FALSE,FALSE,0);
gtk_box_pack_start(GTK_BOX(VBox),ProcessFieldsInsertSpace,FALSE,FALSE,0);
gtk_box_pack_start(GTK_BOX(VBox),ProcessFieldsOnlyOneSpace,FALSE,FALSE,0);
/* List creation for check buttons in group */
- pf_cb_group3 = g_list_append (pf_cb_group3,ProcessFieldsRemoveSpace);
- pf_cb_group3 = g_list_append (pf_cb_group3,ProcessFieldsInsertSpace);
- pf_cb_group3 = g_list_append (pf_cb_group3,ProcessFieldsOnlyOneSpace);
+ pf_cb_group3 = g_list_append(pf_cb_group3,ProcessFieldsRemoveSpace);
+ pf_cb_group3 = g_list_append(pf_cb_group3,ProcessFieldsInsertSpace);
+ pf_cb_group3 = g_list_append(pf_cb_group3,ProcessFieldsOnlyOneSpace);
/* Toggled signals */
g_signal_connect(G_OBJECT(ProcessFieldsRemoveSpace), "toggled",G_CALLBACK(Process_Fields_Check_Button_Toggled),pf_cb_group3);
g_signal_connect(G_OBJECT(ProcessFieldsInsertSpace), "toggled",G_CALLBACK(Process_Fields_Check_Button_Toggled),pf_cb_group3);
@@ -2516,16 +2632,6 @@ void ScannerWindow_Quit (void)
{
if (ScannerWindow)
{
- if (SCAN_TAG_DEFAULT_MASK) g_free(SCAN_TAG_DEFAULT_MASK);
- SCAN_TAG_DEFAULT_MASK = g_strdup(gtk_entry_get_text(GTK_ENTRY(GTK_BIN(ScanTagMaskCombo)->child)));
- Add_String_To_Combo_List(ScanTagListModel, SCAN_TAG_DEFAULT_MASK);
- Save_Rename_File_Masks_List(ScanTagListModel, MASK_EDITOR_TEXT);
-
- if (RENAME_FILE_DEFAULT_MASK) g_free(RENAME_FILE_DEFAULT_MASK);
- RENAME_FILE_DEFAULT_MASK = g_strdup(gtk_entry_get_text(GTK_ENTRY(GTK_BIN(RenameFileMaskCombo)->child)));
- Add_String_To_Combo_List(RenameFileListModel, RENAME_FILE_DEFAULT_MASK);
- Save_Rename_File_Masks_List(RenameFileListModel, MASK_EDITOR_TEXT);
-
ScannerWindow_Apply_Changes();
gtk_widget_destroy(ScannerWindow);
@@ -2587,6 +2693,11 @@ void ScannerWindow_Apply_Changes (void)
PROCESS_COPYRIGHT_FIELD = GTK_TOGGLE_BUTTON(ProcessCopyrightField)->active;
PROCESS_URL_FIELD = GTK_TOGGLE_BUTTON(ProcessURLField)->active;
PROCESS_ENCODED_BY_FIELD = GTK_TOGGLE_BUTTON(ProcessEncodedByField)->active;
+
+ if (PROCESS_FIELDS_CONVERT_FROM) g_free(PROCESS_FIELDS_CONVERT_FROM);
+ PROCESS_FIELDS_CONVERT_FROM = g_strdup(gtk_entry_get_text(GTK_ENTRY(ProcessFieldsConvertFrom)));
+ if (PROCESS_FIELDS_CONVERT_TO) g_free(PROCESS_FIELDS_CONVERT_TO);
+ PROCESS_FIELDS_CONVERT_TO = g_strdup(gtk_entry_get_text(GTK_ENTRY(ProcessFieldsConvertTo)));
/* Group: convert one character */
PF_CONVERT_INTO_SPACE = GTK_TOGGLE_BUTTON(ProcessFieldsConvertIntoSpace)->active;
@@ -2600,9 +2711,21 @@ void ScannerWindow_Apply_Changes (void)
PF_CONVERT_FIRST_LETTERS_UPPERCASE = GTK_TOGGLE_BUTTON(ProcessFieldsFirstLettersUppercase)->active;
/* Group: remove/insert space */
- PF_REMOVE_SPACE = GTK_TOGGLE_BUTTON(ProcessFieldsConvertIntoSpace)->active;
- PF_INSERT_SPACE = GTK_TOGGLE_BUTTON(ProcessFieldsConvertSpace)->active;
+ PF_REMOVE_SPACE = GTK_TOGGLE_BUTTON(ProcessFieldsRemoveSpace)->active;
+ PF_INSERT_SPACE = GTK_TOGGLE_BUTTON(ProcessFieldsInsertSpace)->active;
PF_ONLY_ONE_SPACE = GTK_TOGGLE_BUTTON(ProcessFieldsOnlyOneSpace)->active;
+
+ // Save default masks...
+ if (SCAN_TAG_DEFAULT_MASK) g_free(SCAN_TAG_DEFAULT_MASK);
+ SCAN_TAG_DEFAULT_MASK = g_strdup(gtk_entry_get_text(GTK_ENTRY(GTK_BIN(ScanTagMaskCombo)->child)));
+ Add_String_To_Combo_List(ScanTagListModel, SCAN_TAG_DEFAULT_MASK);
+ Save_Rename_File_Masks_List(ScanTagListModel, MASK_EDITOR_TEXT);
+
+ if (RENAME_FILE_DEFAULT_MASK) g_free(RENAME_FILE_DEFAULT_MASK);
+ RENAME_FILE_DEFAULT_MASK = g_strdup(gtk_entry_get_text(GTK_ENTRY(GTK_BIN(RenameFileMaskCombo)->child)));
+ Add_String_To_Combo_List(RenameFileListModel, RENAME_FILE_DEFAULT_MASK);
+ Save_Rename_File_Masks_List(RenameFileListModel, MASK_EDITOR_TEXT);
+
}
}
@@ -2701,7 +2824,7 @@ gboolean Scan_Check_Rename_File_Mask (GtkObject *widget_to_show_hide, GtkEntry *
if (!mask || strlen(mask)<1)
goto Bad_Mask;
- // Since version 1.99.4, it is available!
+ // Since version 1.99.4, it is available! => OK
/*if ( strchr(mask,G_DIR_SEPARATOR)!=NULL ) // Renaming directory is not yet available
goto Bad_Mask;*/
// Not a valid path....
@@ -3017,15 +3140,15 @@ void Mask_Editor_List_Duplicate (void)
GList *selectedRows;
GList *toInsert = NULL;
GtkTreeSelection *selection;
- GtkTreeIter row;
- GtkTreeModel *treemodel;
+ GtkTreeIter rowIter;
+ GtkTreeModel *treeModel;
gboolean valid;
if (!MaskEditorList) return;
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(MaskEditorList));
selectedRows = gtk_tree_selection_get_selected_rows(selection, NULL);
- treemodel = gtk_tree_view_get_model(GTK_TREE_VIEW(MaskEditorList));
+ treeModel = gtk_tree_view_get_model(GTK_TREE_VIEW(MaskEditorList));
if (g_list_length(selectedRows) == 0)
{
@@ -3035,14 +3158,15 @@ void Mask_Editor_List_Duplicate (void)
return;
}
- /* Loop through selected rows, duplicating them into a GList */
- /* We cannot directly insert because the paths in selectedRows get out of date after an insertion */
- while(selectedRows)
+ /* Loop through selected rows, duplicating them into a GList
+ * We cannot directly insert because the paths in selectedRows
+ * get out of date after an insertion */
+ while (selectedRows)
{
- valid = gtk_tree_model_get_iter(treemodel, &row, (GtkTreePath*) selectedRows->data);
+ valid = gtk_tree_model_get_iter(treeModel, &rowIter, (GtkTreePath*) selectedRows->data);
if (valid)
{
- gtk_tree_model_get(treemodel, &row, MASK_EDITOR_TEXT, &text, -1);
+ gtk_tree_model_get(treeModel, &rowIter, MASK_EDITOR_TEXT, &text, -1);
toInsert = g_list_append(toInsert, text);
}
@@ -3050,18 +3174,22 @@ void Mask_Editor_List_Duplicate (void)
if (!selectedRows) break;
}
- /* Duplicate the relevant entries, by looping through the list backwards (to preserve original order) */
+ /* Duplicate the relevant entries, by looping through the list backwards
+ * (to preserve original order) */
toInsert = g_list_last(toInsert);
- while(toInsert)
+ while (toInsert)
{
- gtk_list_store_insert(GTK_LIST_STORE(treemodel), &row, 0);
- gtk_list_store_set(GTK_LIST_STORE(treemodel), &row, MASK_EDITOR_TEXT, (gchar*) toInsert->data, -1);
+ gtk_list_store_insert(GTK_LIST_STORE(treeModel), &rowIter, 0);
+ gtk_list_store_set(GTK_LIST_STORE(treeModel), &rowIter, MASK_EDITOR_TEXT, (gchar*) toInsert->data, -1);
g_free(toInsert->data);
toInsert = toInsert->prev;
if (!toInsert) break;
}
-
+ // Set focus to the last inserted line
+ if (toInsert)
+ Mask_Editor_List_Set_Row_Visible(treeModel,&rowIter);
+
/* Free data no longer needed */
selectedRows = g_list_first(selectedRows);
toInsert = g_list_first(toInsert);
@@ -3071,7 +3199,7 @@ void Mask_Editor_List_Duplicate (void)
g_list_free(toInsert);
}
-void Mask_Editor_List_Add(void)
+void Mask_Editor_List_Add (void)
{
gint i = 0;
GtkTreeIter iter;
@@ -3183,14 +3311,15 @@ void Mask_Editor_List_Move_Up (void)
selectedRowsCopy = selectedRows;
- while(selectedRows)
+ while (selectedRows)
{
currentPath = (GtkTreePath*) selectedRows->data;
valid = gtk_tree_model_get_iter(treemodel, &currentFile, currentPath);
if (valid)
{
/* Find the entry above the node... */
- if (gtk_tree_path_prev(currentPath)) {
+ if (gtk_tree_path_prev(currentPath))
+ {
/* ...and if it exists, swap the two rows by iter */
gtk_tree_model_get_iter(treemodel, &nextFile, currentPath);
gtk_list_store_swap(GTK_LIST_STORE(treemodel), &currentFile, &nextFile);
@@ -3225,7 +3354,8 @@ void Mask_Editor_List_Move_Down (void)
treemodel = gtk_tree_view_get_model(GTK_TREE_VIEW(MaskEditorList));
selectedRows = gtk_tree_selection_get_selected_rows(selection, NULL);
- if (g_list_length(selectedRows) == 0) {
+ if (g_list_length(selectedRows) == 0)
+ {
Log_Print(_("Move Down: No row selected!"));
g_list_foreach(selectedRows, (GFunc)gtk_tree_path_free, NULL);
g_list_free(selectedRows);
@@ -3242,8 +3372,8 @@ void Mask_Editor_List_Move_Down (void)
{
/* Find the entry below the node and swap the two nodes by iter */
gtk_tree_path_next(currentPath);
- gtk_tree_model_get_iter(treemodel, &nextFile, currentPath);
- gtk_list_store_swap(GTK_LIST_STORE(treemodel), &currentFile, &nextFile);
+ if (gtk_tree_model_get_iter(treemodel, &nextFile, currentPath))
+ gtk_list_store_swap(GTK_LIST_STORE(treemodel), &currentFile, &nextFile);
}
if (!selectedRows->next) break;
@@ -3255,6 +3385,25 @@ void Mask_Editor_List_Move_Down (void)
}
/*
+ * Set a row visible in the mask editor list (by scrolling the list)
+ */
+void Mask_Editor_List_Set_Row_Visible (GtkTreeModel *treeModel, GtkTreeIter *rowIter)
+{
+ /*
+ * TODO: Make this only scroll to the row if it is not visible
+ * (like in easytag GTK1)
+ * See function gtk_tree_view_get_visible_rect() ??
+ */
+ GtkTreePath *rowPath;
+
+ if (!treeModel) return;
+
+ rowPath = gtk_tree_model_get_path(treeModel, rowIter);
+ gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(MaskEditorList), rowPath, NULL, FALSE, 0, 0);
+ gtk_tree_path_free(rowPath);
+}
+
+/*
* Save the currently displayed mask list in the mask editor
*/
void Mask_Editor_List_Save_Button (void)