1 /* cssed (c) Iago Rubio 2003, 2005 - A tiny CSS editor.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Library General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16 */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 #include <string.h>
23 #include <gtk/gtk.h>
24
25 #include "cssedwindow.h"
26 #include "document.h"
27 #include "support.h"
28 #include "utils.h"
29 #include "debug.h"
30 #include "file-type-manager.h"
31
32 #define g_slist_first(n) g_slist_nth (n,0)
33
34 // FILE TYPE IMPLEMENTATION
35 CssedFileType*
cssed_file_type_new()36 cssed_file_type_new()
37 {
38 CssedFileType* type;
39 type = g_malloc0(sizeof(CssedFileType));
40 return type;
41 }
42
43 void
cssed_file_type_free_item(gpointer item,gpointer user_data)44 cssed_file_type_free_item (gpointer item, gpointer user_data)
45 {
46 g_free(item);
47 }
48
49 void
cssed_file_type_free(CssedFileType * type)50 cssed_file_type_free(CssedFileType* type)
51 {
52 if( !type ) return;
53 g_free(type->label_language);
54 g_free(type->lable_file);
55 g_slist_foreach(type->patterns, cssed_file_type_free_item, NULL);
56 g_slist_free(type->patterns);
57 g_free(type);
58 }
59
60 void
cssed_file_type_add_pattern_spec(CssedFileType * type,gchar * spec)61 cssed_file_type_add_pattern_spec(CssedFileType* type, gchar* spec)
62 {
63 type->patterns = g_slist_append (type->patterns, (gpointer) g_strdup(spec));
64 }
65
66 //FILE TYPE MANAGER IMPLEMENTATION
67 gboolean
patterns_hash_table_key_equal_func(gconstpointer a,gconstpointer b)68 patterns_hash_table_key_equal_func(gconstpointer a,
69 gconstpointer b)
70 {
71 if( !a && !b ) return TRUE;
72 if( !a ) return FALSE;
73 if( !b ) return FALSE;
74 if( strcmp((gchar*) a, (gchar*) b) == 0 ) return TRUE;
75 return FALSE;
76 }
77
78 void
patterns_hash_table_free_entry(gpointer key,gpointer value,gpointer user_data)79 patterns_hash_table_free_entry (gpointer key,
80 gpointer value,
81 gpointer user_data)
82 {
83 GSList *list;
84 list = g_slist_first((GSList*) value);
85 while(list)
86 {
87 g_free(list->data);
88 list = g_slist_next(list);
89 }
90 g_slist_free (list);
91 g_free(key);
92 }
93
94 CssedFileTypeManager*
cssed_file_type_manager_new()95 cssed_file_type_manager_new()
96 {
97 CssedFileTypeManager* manager;
98
99 manager = g_malloc0(sizeof(CssedFileTypeManager));
100 memset (manager->filetype, 0, sizeof(gpointer) * CSSED_NUMFILETYPES);
101 manager->patterns_hash_table = g_hash_table_new (g_str_hash, g_str_equal);
102
103 return manager;
104 }
105
106 void
cssed_file_type_manager_free(CssedFileTypeManager * manager)107 cssed_file_type_manager_free( CssedFileTypeManager *manager )
108 {
109 gint i;
110
111 if(!manager) return;
112
113 g_hash_table_foreach(manager->patterns_hash_table, patterns_hash_table_free_entry, NULL);
114 g_hash_table_destroy(manager->patterns_hash_table);
115 // now free all file types
116 for(i=0;i<CSSED_NUMFILETYPES;i++){
117 if( manager->filetype[i] != NULL )
118 cssed_file_type_free(manager->filetype[i]);
119 }
120 g_free(manager);
121 }
122
123 gboolean
patterns_hash_table_find_func(gpointer key,gpointer value,gpointer user_data)124 patterns_hash_table_find_func (gpointer key,
125 gpointer value,
126 gpointer user_data)
127 {
128 gchar *filename;
129 gchar *toupper_pattern;
130 gchar *pattern;
131 gboolean match;
132
133 filename = (gchar*) user_data;
134 pattern = (gchar*) key;
135
136 if( !filename ) return FALSE;
137 match = g_pattern_match_simple( pattern, filename);
138 DBGMSG (__FILE__,__LINE__,"Pattern matching:\n%s with %s (%s)", filename, pattern, match?"MATCH !!":"NO");
139 if( match ) return TRUE;
140
141 // check for uppercase strings, mixed case is not managed
142 if( g_ascii_isupper(filename[strlen(filename)-1]) ){
143 toupper_pattern = g_ascii_strup(pattern, -1);
144 match = g_pattern_match_simple(toupper_pattern, filename);
145 DBGMSG (__FILE__,__LINE__,"Pattern matching:\n%s with %s (%s)", filename, (gchar*) toupper_pattern, match?"MATCH !!":"NO");
146 g_free(toupper_pattern);
147 if( match ) return TRUE;
148 }
149
150 return FALSE;
151 }
152
153 GSList*
cssed_file_type_manager_get_ids_from_filename(CssedFileTypeManager * manager,gchar * filename)154 cssed_file_type_manager_get_ids_from_filename (CssedFileTypeManager *manager, gchar *filename)
155 {
156 GSList *ids; // GList containing all file type ids that matches the file
157 GHashTable* hash;
158
159 hash = manager->patterns_hash_table;
160 ids = (GSList*) g_hash_table_find (hash, patterns_hash_table_find_func, filename);
161 return ids;
162 }
163
164
165 GSList*
cssed_file_type_manager_get_ids_from_pattern(CssedFileTypeManager * manager,gchar * pattern)166 cssed_file_type_manager_get_ids_from_pattern( CssedFileTypeManager *manager, gchar *pattern )
167 {
168 GSList *ids; // GList containing all file type ids that mathes the file
169 GHashTable* hash;
170
171 hash = manager->patterns_hash_table;
172 ids = (GSList*) g_hash_table_lookup (hash, pattern);
173 return ids;
174 }
175
176 CssedFileTypeId
cssed_file_type_manager_get_default_id_from_filename(CssedFileTypeManager * manager,gchar * filename)177 cssed_file_type_manager_get_default_id_from_filename( CssedFileTypeManager *manager, gchar *filename )
178 {
179 gpointer ids; // GSList containing all file type ids that mathes the file
180 GSList* idlist;
181
182 if( !filename ) return CSSED_FILETYPE_UNKNOW;
183 if( !manager ) return CSSED_FILETYPE_UNKNOW;
184
185 // lookup on patterns hash table
186 ids = cssed_file_type_manager_get_ids_from_filename (manager, filename);
187 if( !ids ){
188 return CSSED_FILETYPE_UNKNOW;
189 }else{
190 idlist = g_slist_first( ids ); // the order matters, first is default
191 if( !idlist ) return CSSED_FILETYPE_UNKNOW;
192 else return *((CssedFileTypeId*) idlist->data);
193 }
194 }
195
196 CssedFileType*
cssed_file_type_manager_get_filetype_from_filename(CssedFileTypeManager * manager,gchar * filename)197 cssed_file_type_manager_get_filetype_from_filename( CssedFileTypeManager *manager, gchar *filename )
198 {
199 gint defaultid;
200
201 defaultid = cssed_file_type_manager_get_default_id_from_filename( manager, filename );
202 if( defaultid == CSSED_FILETYPE_UNKNOW ) defaultid = CSSED_FILETYPE_TEXT;
203 return manager->filetype[defaultid];
204 }
205
206 CssedFileType*
cssed_file_type_manager_get_filetype_from_id(CssedFileTypeManager * manager,CssedFileTypeId id)207 cssed_file_type_manager_get_filetype_from_id( CssedFileTypeManager *manager, CssedFileTypeId id )
208 {
209 if( id <= CSSED_FILETYPE_UNKNOW || id >= CSSED_NUMFILETYPES ) return NULL;
210 return manager->filetype[id];
211 }
212
213 void
cssed_file_type_manager_add_pattern(CssedFileTypeManager * manager,gchar * pattern,CssedFileTypeId id)214 cssed_file_type_manager_add_pattern( CssedFileTypeManager *manager, gchar *pattern, CssedFileTypeId id )
215 {
216 GHashTable *hash;
217 GSList *val = NULL;
218 gchar *key;
219 gint *idptr;
220
221 if( !manager ) return; // no NULLs please
222 if( !pattern ) return; // no NULLs please
223 hash = manager->patterns_hash_table;
224 if( !g_hash_table_lookup_extended (hash, pattern, (gpointer) &key, (gpointer) &val) )
225 key = g_strdup(pattern);
226 idptr = g_new0(gint,1);
227 *idptr = id;
228 val = g_slist_append(val, idptr);
229 g_hash_table_insert(hash, key, val);
230 }
231
232 gboolean
cssed_file_type_manager_delete_pattern(CssedFileTypeManager * manager,gchar * pattern)233 cssed_file_type_manager_delete_pattern( CssedFileTypeManager *manager, gchar *pattern )
234 {
235 GSList *val = NULL;
236 gchar *key;
237 GHashTable *hash;
238
239 hash = manager->patterns_hash_table;
240
241 if( g_hash_table_lookup_extended (hash, pattern, (gpointer) &key, (gpointer) &val) ){
242 g_hash_table_remove (hash, (gpointer) &key);
243 patterns_hash_table_free_entry ((gpointer) key, (gpointer) val, NULL);
244 return TRUE;
245 }else{
246 return FALSE;
247 }
248 }
249
250 gboolean
cssed_file_type_manager_pattern_exists(CssedFileTypeManager * manager,gchar * pattern)251 cssed_file_type_manager_pattern_exists( CssedFileTypeManager *manager, gchar *pattern )
252 {
253 if( g_hash_table_lookup(manager->patterns_hash_table, pattern) != NULL ) return TRUE;
254 else return FALSE;
255 }
256
257 /* *********************************************************************
258 This is to use by callback as a file type menu item.
259 It should be set as menu item's data the filetype.
260 Use the function below to set the data.
261 * ******************************************************************** */
262 void
on_file_type_menu_activate(GtkMenuItem * menuitem,gpointer user_data)263 on_file_type_menu_activate (GtkMenuItem * menuitem, gpointer user_data)
264 {
265 CssedFileType* filetype;
266 CssedWindow* window;
267 CssedDoc* doc;
268
269 filetype = g_object_get_data(G_OBJECT(menuitem), "filetype");
270 if ( filetype ){
271 window = CSSED_WINDOW(user_data);
272 doc = document_get_current(window);
273 document_set_filetype( doc, filetype );
274 }
275 }
276
277 void
cssed_file_type_menu_set_default_callback(CssedWindow * window,GtkWidget * filetype_menu,CssedFileType * filetype)278 cssed_file_type_menu_set_default_callback (CssedWindow *window, GtkWidget *filetype_menu, CssedFileType *filetype)
279 {
280 g_object_set_data(G_OBJECT(filetype_menu), "filetype", filetype);
281 g_signal_connect ((gpointer) filetype_menu, "activate",
282 G_CALLBACK (on_file_type_menu_activate), window);
283 }
284