Mercurial > audlegacy
annotate audacious/skinwin.c @ 452:623391b6463b trunk
[svn] Make "Unarchived Winamp 2.x skin" &c translatable.
author | nenolod |
---|---|
date | Mon, 16 Jan 2006 16:05:02 -0800 |
parents | 00afc39b0754 |
children | 257a8d2047fb |
rev | line source |
---|---|
0 | 1 /* BMP - Cross-platform multimedia player |
2 * Copyright (C) 2003-2004 BMP development team. | |
3 * | |
4 * Based on XMMS: | |
5 * Copyright (C) 1998-2003 XMMS development team. | |
6 * | |
7 * This program is free software; you can redistribute it and/or modify | |
8 * it under the terms of the GNU General Public License as published by | |
9 * the Free Software Foundation; either version 2 of the License, or | |
10 * (at your option) any later version. | |
11 * | |
12 * This program is distributed in the hope that it will be useful, | |
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 * GNU General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU General Public License | |
18 * along with this program; if not, write to the Free Software | |
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
20 */ | |
21 | |
22 #ifdef HAVE_CONFIG_H | |
23 # include "config.h" | |
24 #endif | |
25 | |
26 #include "skinwin.h" | |
27 | |
28 #include <glib.h> | |
452
623391b6463b
[svn] Make "Unarchived Winamp 2.x skin" &c translatable.
nenolod
parents:
451
diff
changeset
|
29 #include <glib/gi18n.h> |
0 | 30 #include <gtk/gtk.h> |
31 #include <gdk/gdk.h> | |
32 #include <gdk/gdkkeysyms.h> | |
33 #include <stdlib.h> | |
34 #include <string.h> | |
35 | |
36 #include "main.h" | |
37 #include "skin.h" | |
38 #include "util.h" | |
39 | |
40 #include <gdk/gdkx.h> | |
41 | |
42 | |
43 #define THUMBNAIL_WIDTH 90 | |
44 #define THUMBNAIL_HEIGHT 40 | |
45 | |
46 | |
47 enum SkinViewCols { | |
48 SKIN_VIEW_COL_PREVIEW, | |
49 SKIN_VIEW_COL_NAME, | |
50 SKIN_VIEW_N_COLS | |
51 }; | |
52 | |
53 | |
54 GList *skinlist = NULL; | |
55 | |
56 | |
57 | |
58 static gchar * | |
59 get_thumbnail_filename(const gchar * path) | |
60 { | |
61 gchar *basename, *pngname, *thumbname; | |
62 | |
63 g_return_val_if_fail(path != NULL, NULL); | |
64 | |
65 basename = g_path_get_basename(path); | |
66 pngname = g_strconcat(basename, ".png", NULL); | |
67 | |
68 thumbname = g_build_filename(bmp_paths[BMP_PATH_SKIN_THUMB_DIR], | |
69 pngname, NULL); | |
70 | |
71 g_free(basename); | |
72 g_free(pngname); | |
73 | |
74 return thumbname; | |
75 } | |
76 | |
77 | |
78 static GdkPixbuf * | |
79 skin_get_preview(const gchar * path) | |
80 { | |
81 GdkPixbuf *preview = NULL; | |
82 gchar *dec_path, *preview_path; | |
83 gboolean is_archive = FALSE; | |
84 | |
85 if (file_is_archive(path)) { | |
86 if (!(dec_path = archive_decompress(path))) | |
87 return NULL; | |
88 | |
89 is_archive = TRUE; | |
90 } | |
91 else { | |
92 dec_path = g_strdup(path); | |
93 } | |
94 | |
95 preview_path = find_file_recursively(dec_path, "main.bmp"); | |
96 | |
97 if (preview_path) { | |
98 preview = gdk_pixbuf_new_from_file(preview_path, NULL); | |
99 g_free(preview_path); | |
100 } | |
101 | |
102 if (is_archive) | |
103 del_directory(dec_path); | |
104 | |
105 g_free(dec_path); | |
106 | |
107 return preview; | |
108 } | |
109 | |
110 | |
111 static GdkPixbuf * | |
112 skin_get_thumbnail(const gchar * path) | |
113 { | |
114 GdkPixbuf *scaled = NULL; | |
115 GdkPixbuf *preview; | |
116 gchar *thumbname; | |
117 | |
118 g_return_val_if_fail(path != NULL, NULL); | |
119 | |
120 if (g_str_has_suffix(path, BMP_SKIN_THUMB_DIR_BASENAME)) | |
121 return NULL; | |
122 | |
123 thumbname = get_thumbnail_filename(path); | |
124 | |
125 if (g_file_test(thumbname, G_FILE_TEST_EXISTS)) { | |
126 scaled = gdk_pixbuf_new_from_file(thumbname, NULL); | |
127 g_free(thumbname); | |
128 return scaled; | |
129 } | |
130 | |
131 if (!(preview = skin_get_preview(path))) { | |
132 g_free(thumbname); | |
133 return NULL; | |
134 } | |
135 | |
136 scaled = gdk_pixbuf_scale_simple(preview, | |
137 THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT, | |
138 GDK_INTERP_BILINEAR); | |
139 g_object_unref(preview); | |
140 | |
141 gdk_pixbuf_save(scaled, thumbname, "png", NULL, NULL); | |
142 g_free(thumbname); | |
143 | |
144 return scaled; | |
145 } | |
146 | |
147 static void | |
148 skinlist_add(const gchar * filename) | |
149 { | |
150 SkinNode *node; | |
151 gchar *basename; | |
152 | |
153 g_return_if_fail(filename != NULL); | |
154 | |
155 node = g_new0(SkinNode, 1); | |
156 node->path = g_strdup(filename); | |
157 | |
158 basename = g_path_get_basename(filename); | |
159 | |
160 if (file_is_archive(filename)) { | |
161 node->name = archive_basename(basename); | |
452
623391b6463b
[svn] Make "Unarchived Winamp 2.x skin" &c translatable.
nenolod
parents:
451
diff
changeset
|
162 node->desc = _("Archived Winamp 2.x skin"); |
0 | 163 g_free(basename); |
164 } | |
165 else { | |
166 node->name = basename; | |
452
623391b6463b
[svn] Make "Unarchived Winamp 2.x skin" &c translatable.
nenolod
parents:
451
diff
changeset
|
167 node->desc = _("Unarchived Winamp 2.x skin"); |
0 | 168 } |
169 | |
170 skinlist = g_list_prepend(skinlist, node); | |
171 } | |
172 | |
173 static gboolean | |
174 scan_skindir_func(const gchar * path, const gchar * basename, gpointer data) | |
175 { | |
176 if (g_file_test(path, G_FILE_TEST_IS_REGULAR)) { | |
177 if (file_is_archive(path)) { | |
178 skinlist_add(path); | |
179 } | |
180 } | |
181 else if (g_file_test(path, G_FILE_TEST_IS_DIR)) { | |
182 skinlist_add(path); | |
183 } | |
184 | |
185 return FALSE; | |
186 } | |
187 | |
188 static void | |
189 scan_skindir(const gchar * path) | |
190 { | |
191 GError *error = NULL; | |
192 | |
193 g_return_if_fail(path != NULL); | |
194 | |
195 if (path[0] == '.') | |
196 return; | |
197 | |
198 if (!dir_foreach(path, scan_skindir_func, NULL, &error)) { | |
199 g_warning("Failed to open directory (%s): %s", path, error->message); | |
200 g_error_free(error); | |
201 return; | |
202 } | |
203 } | |
204 | |
205 static gint | |
206 skinlist_compare_func(gconstpointer a, gconstpointer b) | |
207 { | |
208 g_return_val_if_fail(a != NULL && SKIN_NODE(a)->name != NULL, 1); | |
209 g_return_val_if_fail(b != NULL && SKIN_NODE(b)->name != NULL, 1); | |
210 return strcasecmp(SKIN_NODE(a)->name, SKIN_NODE(b)->name); | |
211 } | |
212 | |
213 static void | |
214 skin_free_func(gpointer data) | |
215 { | |
216 g_return_if_fail(data != NULL); | |
217 g_free(SKIN_NODE(data)->name); | |
218 g_free(SKIN_NODE(data)->path); | |
219 g_free(data); | |
220 } | |
221 | |
222 | |
223 static void | |
224 skinlist_clear(void) | |
225 { | |
226 if (!skinlist) | |
227 return; | |
228 | |
229 g_list_foreach(skinlist, (GFunc) skin_free_func, NULL); | |
230 g_list_free(skinlist); | |
231 skinlist = NULL; | |
232 } | |
233 | |
234 void | |
235 skinlist_update(void) | |
236 { | |
237 gchar *skinsdir; | |
238 | |
239 skinlist_clear(); | |
240 | |
241 scan_skindir(bmp_paths[BMP_PATH_USER_SKIN_DIR]); | |
242 scan_skindir(DATA_DIR G_DIR_SEPARATOR_S BMP_SKIN_DIR_BASENAME); | |
243 | |
244 skinsdir = getenv("SKINSDIR"); | |
245 if (skinsdir) { | |
246 gchar **dir_list = g_strsplit(skinsdir, ":", 0); | |
247 gchar **dir; | |
248 | |
249 for (dir = dir_list; *dir; dir++) | |
250 scan_skindir(*dir); | |
251 g_strfreev(dir_list); | |
252 } | |
253 | |
254 skinlist = g_list_sort(skinlist, skinlist_compare_func); | |
255 | |
256 g_assert(skinlist != NULL); | |
257 } | |
258 | |
259 void | |
260 skin_view_update(GtkTreeView * treeview) | |
261 { | |
262 GtkTreeSelection *selection = NULL; | |
263 GtkListStore *store; | |
264 GtkTreeIter iter, iter_current_skin; | |
265 GtkTreePath *path; | |
266 | |
267 GdkPixbuf *thumbnail; | |
268 gchar *name; | |
269 GList *entry; | |
270 | |
271 gtk_widget_set_sensitive(GTK_WIDGET(treeview), FALSE); | |
272 | |
273 store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview)); | |
274 | |
275 gtk_list_store_clear(store); | |
276 | |
277 skinlist_update(); | |
278 | |
279 for (entry = skinlist; entry; entry = g_list_next(entry)) { | |
280 thumbnail = skin_get_thumbnail(SKIN_NODE(entry->data)->path); | |
281 | |
282 if (!thumbnail) | |
283 continue; | |
284 | |
449 | 285 name = g_strdup_printf("<big><b>%s</b></big>\n<i>%s</i>", |
286 SKIN_NODE(entry->data)->name, SKIN_NODE(entry->data)->desc); | |
0 | 287 |
288 gtk_list_store_append(store, &iter); | |
289 gtk_list_store_set(store, &iter, | |
290 SKIN_VIEW_COL_PREVIEW, thumbnail, | |
291 SKIN_VIEW_COL_NAME, name, -1); | |
451
00afc39b0754
[svn] Use g_object_(get|set)_data() on the thumbnail object to store the skin
nenolod
parents:
450
diff
changeset
|
292 g_object_set_data(G_OBJECT(thumbnail), "skinpath", |
00afc39b0754
[svn] Use g_object_(get|set)_data() on the thumbnail object to store the skin
nenolod
parents:
450
diff
changeset
|
293 SKIN_NODE(entry->data)->name); |
0 | 294 g_object_unref(thumbnail); |
295 | |
296 if (g_strstr_len(bmp_active_skin->path, | |
297 strlen(bmp_active_skin->path), name)) { | |
298 iter_current_skin = iter; | |
299 } | |
300 | |
301 while (gtk_events_pending()) | |
302 gtk_main_iteration(); | |
303 } | |
304 | |
305 selection = gtk_tree_view_get_selection(treeview); | |
306 gtk_tree_selection_select_iter(selection, &iter_current_skin); | |
307 | |
308 path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &iter_current_skin); | |
309 gtk_tree_view_scroll_to_cell(treeview, path, NULL, TRUE, 0.5, 0.5); | |
310 gtk_tree_path_free(path); | |
311 | |
312 gtk_widget_set_sensitive(GTK_WIDGET(treeview), TRUE); | |
313 } | |
314 | |
315 | |
316 static void | |
317 skin_view_on_cursor_changed(GtkTreeView * treeview, | |
318 gpointer data) | |
319 { | |
320 GtkTreeModel *model; | |
321 GtkTreeSelection *selection; | |
322 GtkTreeIter iter; | |
451
00afc39b0754
[svn] Use g_object_(get|set)_data() on the thumbnail object to store the skin
nenolod
parents:
450
diff
changeset
|
323 GdkPixbuf *thumbnail; |
0 | 324 |
325 GList *node; | |
451
00afc39b0754
[svn] Use g_object_(get|set)_data() on the thumbnail object to store the skin
nenolod
parents:
450
diff
changeset
|
326 gchar *sel, *name; |
0 | 327 gchar *comp = NULL; |
328 | |
329 selection = gtk_tree_view_get_selection(treeview); | |
330 if (!gtk_tree_selection_get_selected(selection, &model, &iter)) | |
331 return; | |
332 | |
451
00afc39b0754
[svn] Use g_object_(get|set)_data() on the thumbnail object to store the skin
nenolod
parents:
450
diff
changeset
|
333 gtk_tree_model_get(model, &iter, SKIN_VIEW_COL_PREVIEW, &thumbnail, -1); |
450
dd84f79979b4
[svn] Dissect the pango markup using scanf and various string delimiter hacks.
nenolod
parents:
449
diff
changeset
|
334 gtk_tree_model_get(model, &iter, SKIN_VIEW_COL_NAME, &sel, -1); |
dd84f79979b4
[svn] Dissect the pango markup using scanf and various string delimiter hacks.
nenolod
parents:
449
diff
changeset
|
335 |
451
00afc39b0754
[svn] Use g_object_(get|set)_data() on the thumbnail object to store the skin
nenolod
parents:
450
diff
changeset
|
336 name = g_object_get_data(G_OBJECT(thumbnail), "skinpath"); |
0 | 337 |
338 /* FIXME: store name in skinlist */ | |
339 for (node = skinlist; node; node = g_list_next(node)) { | |
340 comp = SKIN_NODE(node->data)->path; | |
341 if (g_strrstr(comp, name)) | |
342 break; | |
343 } | |
344 | |
450
dd84f79979b4
[svn] Dissect the pango markup using scanf and various string delimiter hacks.
nenolod
parents:
449
diff
changeset
|
345 g_free(sel); |
0 | 346 |
347 bmp_active_skin_load(comp); | |
348 } | |
349 | |
350 | |
351 void | |
352 skin_view_realize(GtkTreeView * treeview) | |
353 { | |
354 GtkListStore *store; | |
355 GtkTreeViewColumn *column; | |
356 GtkCellRenderer *renderer; | |
357 GtkTreeSelection *selection; | |
358 | |
359 gtk_widget_show_all(GTK_WIDGET(treeview)); | |
360 | |
361 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE); | |
362 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE); | |
363 | |
364 store = gtk_list_store_new(SKIN_VIEW_N_COLS, GDK_TYPE_PIXBUF, | |
365 G_TYPE_STRING); | |
366 gtk_tree_view_set_model(treeview, GTK_TREE_MODEL(store)); | |
367 | |
368 column = gtk_tree_view_column_new(); | |
369 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); | |
370 gtk_tree_view_column_set_spacing(column, 16); | |
371 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), | |
372 GTK_TREE_VIEW_COLUMN(column)); | |
373 | |
374 renderer = gtk_cell_renderer_pixbuf_new(); | |
375 gtk_tree_view_column_pack_start(column, renderer, FALSE); | |
376 gtk_tree_view_column_set_attributes(column, renderer, "pixbuf", | |
377 SKIN_VIEW_COL_PREVIEW, NULL); | |
378 | |
379 renderer = gtk_cell_renderer_text_new(); | |
380 gtk_tree_view_column_pack_start(column, renderer, TRUE); | |
449 | 381 gtk_tree_view_column_set_attributes(column, renderer, "markup", |
0 | 382 SKIN_VIEW_COL_NAME, NULL); |
383 | |
384 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); | |
385 gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE); | |
386 | |
387 g_signal_connect(treeview, "cursor-changed", | |
388 G_CALLBACK(skin_view_on_cursor_changed), NULL); | |
389 } |