add item lib/cue error flags
[melted_gui] / src / library.c
1 /*
2 * playlist.c -- GTK+ 2 omnplay
3 * Copyright (C) 2011 Maksym Veremeyenko <verem@m1stereo.tv>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software Foundation,
17 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20 #ifdef HAVE_CONFIG_H
21 # include <config.h>
22 #endif
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <gtk/gtk.h>
28 #include <gdk/gdkkeysyms.h>
29 #include <pthread.h>
30
31 #include "omnplay.h"
32 #include "ui.h"
33 #include "timecode.h"
34
35 playlist_item_t* omnplay_library_find(omnplay_instance_t* app, char* id)
36 {
37 int i;
38 playlist_item_t* item = NULL;
39
40 pthread_mutex_lock(&app->library.lock);
41
42 for(i = 0; i < app->library.count && !item; i++)
43 if(!strcasecmp(id, app->library.item[i].id))
44 item = &app->library.item[i];
45
46 pthread_mutex_unlock(&app->library.lock);
47
48 return item;
49 };
50
51 void omnplay_library_normalize_item(omnplay_instance_t* app, playlist_item_t* item)
52 {
53 playlist_item_t* lib;
54
55 pthread_mutex_lock(&app->library.lock);
56
57 lib = omnplay_library_find(app, item->id);
58
59 if(lib)
60 {
61
62 if(!item->title[0])
63 strcpy(item->title, lib->title);
64
65 if(!item->dur)
66 {
67 item->dur = lib->dur;
68 item->in = lib->in;
69 };
70 }
71 else
72 item->error = PLAYLIST_ITEM_ERROR_LIB;
73
74 pthread_mutex_unlock(&app->library.lock);
75 };
76
77 void omnplay_library_sort(omnplay_instance_t* app)
78 {
79 int i, j, m;
80 playlist_item_t item;
81
82 for(i = 0; i < app->library.count; i++)
83 {
84 /* find max */
85 for(j = i + 1, m = i; j < app->library.count; j++)
86 if(strcasecmp(app->library.item[j].id, app->library.item[m].id) < 0)
87 m = j;
88
89 if(m != i)
90 {
91 item = app->library.item[i];
92 app->library.item[i] = app->library.item[m];
93 app->library.item[m] = item;
94 };
95 };
96 };
97
98 int omnplay_library_load_file(playlist_item_t* items, int *pcount, char* filename)
99 {
100 int i, c = 0, r = 0;
101 FILE* f;
102 char *l;
103 int limit = *pcount;
104 playlist_item_t item;
105
106 /* allocate space for strings and items */
107 l = malloc(PATH_MAX);
108
109 *pcount = 0;
110
111 /* open and process file */
112 if((f = fopen(filename, "rt")))
113 {
114 while( !feof(f) && c < (limit -1))
115 {
116 char *s, *sp_r, *sp_b;
117
118 /* load string */
119 memset(l, 0, PATH_MAX);
120 fgets(l, PATH_MAX, f);
121
122 /* remove newlines */
123 if( (s = strchr(l, '\n')) ) *s = 0;
124 if( (s = strchr(l, '\r')) ) *s = 0;
125
126 /* check for empty line */
127 if(l[0] && l[0] != '#' && l[0] != '|')
128 {
129 memset(&item, 0, sizeof(playlist_item_t));
130
131 for(i = 0, sp_b = l; (NULL != (sp_r = strtok(sp_b, "\t"))); i++, sp_b = NULL)
132 {
133 switch(i)
134 {
135 case 0: strncpy(item.id, sp_r, PATH_MAX); break;
136 case 1: tc2frames(sp_r, 25.0, &item.in); break;
137 case 2: tc2frames(sp_r, 25.0, &item.dur); break;
138 case 3: strncpy(item.title, sp_r, PATH_MAX); break;
139 };
140 };
141
142 /* insert item */
143 items[c++] = item;
144 };
145 }
146
147 fclose(f);
148 }
149 else
150 r = -1;
151
152 /* free data */
153 free(l);
154
155 *pcount = c;
156
157 return r;
158 };
159
160 void omnplay_library_load(omnplay_instance_t* app)
161 {
162 pthread_mutex_lock(&app->library.lock);
163
164 if(app->library.filename[0])
165 {
166 app->library.count = MAX_LIBRARY_ITEMS;
167 omnplay_library_load_file(app->library.item, &app->library.count, app->library.filename);
168 };
169
170 omnplay_library_sort(app);
171
172 pthread_mutex_unlock(&app->library.lock);
173
174 omnplay_library_draw(app);
175 };
176
177 static void omnplay_library_save_file(playlist_item_t* item, int count, char* filename)
178 {
179 int i;
180 FILE* f;
181
182 if((f = fopen(filename, "wt")))
183 {
184 char tc_in[32], tc_dur[32];
185
186 for(i = 0; i < count; i++)
187 fprintf(f, "%s\t%s\t%s\t%s\n",
188 item[i].id,
189 frames2tc(item[i].in, 25.0, tc_in),
190 frames2tc(item[i].dur, 25.0, tc_dur),
191 item[i].title);
192
193 fclose(f);
194 };
195 };
196
197 void omnplay_library_save(omnplay_instance_t* app)
198 {
199 pthread_mutex_lock(&app->library.lock);
200
201 if(app->library.filename[0])
202 omnplay_library_save_file(app->library.item, app->library.count,
203 app->library.filename);
204
205 pthread_mutex_unlock(&app->library.lock);
206 };
207
208 static void omnplay_get_content_cb(omnplay_instance_t* app, playlist_item_t* item, void* data)
209 {
210 fprintf(stderr, "requested: id=[%s]\n", item->id);
211 };
212
213 void omnplay_library_refresh(omnplay_instance_t* app)
214 {
215 int count, i;
216 playlist_item_t* items;
217
218
219 items = (playlist_item_t*)malloc(sizeof(playlist_item_t) * MAX_LIBRARY_ITEMS);
220
221 count = omnplay_get_content(app, items, MAX_LIBRARY_ITEMS, omnplay_get_content_cb, NULL);
222
223 if(count > 0)
224 {
225 if(app->library.whois[0])
226 omnplay_whois_list(app, items, &count);
227
228 pthread_mutex_lock(&app->library.lock);
229
230 for(i = 0; i < count; i++)
231 app->library.item[i] = items[i];
232
233 app->library.count = count;
234
235 omnplay_library_sort(app);
236
237 pthread_mutex_unlock(&app->library.lock);
238
239 omnplay_library_draw(app);
240 };
241
242 free(items);
243 };
244
245 void omnplay_library_draw(omnplay_instance_t* app)
246 {
247 int i;
248 char tc[12];
249 GtkListStore *list_store;
250 GtkTreeIter iter;
251
252 list_store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(app->library_grid)));
253 gtk_list_store_clear(list_store);
254
255 pthread_mutex_lock(&app->library.lock);
256
257 for(i = 0;i < app->library.count; i++)
258 {
259 gtk_list_store_append(list_store, &iter);
260
261 gtk_list_store_set(list_store, &iter,
262 0, app->library.item[i].id,
263 1, frames2tc(app->library.item[i].dur, 25.0, tc),
264 2, app->library.item[i].title,
265 3, i,
266 -1 );
267 }
268
269 pthread_mutex_unlock(&app->library.lock);
270 };
271