2 * playlist.c -- GTK+ 2 omnplay
3 * Copyright (C) 2011 Maksym Veremeyenko <verem@m1stereo.tv>
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.
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.
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.
28 #include <gdk/gdkkeysyms.h>
35 playlist_item_t
* omnplay_library_find(omnplay_instance_t
* app
, char* id
)
38 playlist_item_t
* item
= NULL
;
40 pthread_mutex_lock(&app
->library
.lock
);
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
];
46 pthread_mutex_unlock(&app
->library
.lock
);
51 int omnplay_library_normalize_item(omnplay_instance_t
* app
, playlist_item_t
* item
)
56 pthread_mutex_lock(&app
->library
.lock
);
58 lib
= omnplay_library_find(app
, item
->id
);
67 strcpy(item
->title
, lib
->title
);
71 if(!item
->dur
|| item
->in
< lib
->in
|| (item
->in
+ item
->dur
) > (lib
->in
+ lib
->dur
))
81 item
->error
= PLAYLIST_ITEM_ERROR_LIB
;
84 pthread_mutex_unlock(&app
->library
.lock
);
89 void omnplay_library_sort(omnplay_instance_t
* app
)
94 for(i
= 0; i
< app
->library
.count
; i
++)
97 for(j
= i
+ 1, m
= i
; j
< app
->library
.count
; j
++)
98 if(strcasecmp(app
->library
.item
[j
].id
, app
->library
.item
[m
].id
) < 0)
103 item
= app
->library
.item
[i
];
104 app
->library
.item
[i
] = app
->library
.item
[m
];
105 app
->library
.item
[m
] = item
;
110 int omnplay_library_load_file(playlist_item_t
* items
, int *pcount
, char* filename
)
116 playlist_item_t item
;
118 /* allocate space for strings and items */
119 l
= malloc(PATH_MAX
);
123 /* open and process file */
124 if((f
= fopen(filename
, "rt")))
126 while( !feof(f
) && c
< (limit
-1))
128 char *s
, *sp_r
, *sp_b
;
131 memset(l
, 0, PATH_MAX
);
132 fgets(l
, PATH_MAX
, f
);
134 /* remove newlines */
135 if( (s
= strchr(l
, '\n')) ) *s
= 0;
136 if( (s
= strchr(l
, '\r')) ) *s
= 0;
138 /* check for empty line */
139 if(l
[0] && l
[0] != '#' && l
[0] != '|')
141 memset(&item
, 0, sizeof(playlist_item_t
));
143 for(i
= 0, sp_b
= l
; (NULL
!= (sp_r
= strtok(sp_b
, "\t"))); i
++, sp_b
= NULL
)
147 case 0: strncpy(item
.id
, sp_r
, PATH_MAX
); break;
148 case 1: tc2frames(sp_r
, 25.0, &item
.in
); break;
149 case 2: tc2frames(sp_r
, 25.0, &item
.dur
); break;
150 case 3: strncpy(item
.title
, sp_r
, PATH_MAX
); break;
172 void omnplay_library_load(omnplay_instance_t
* app
)
174 pthread_mutex_lock(&app
->library
.lock
);
176 if(app
->library
.filename
[0])
178 app
->library
.count
= MAX_LIBRARY_ITEMS
;
179 omnplay_library_load_file(app
->library
.item
, &app
->library
.count
, app
->library
.filename
);
182 omnplay_library_sort(app
);
184 pthread_mutex_unlock(&app
->library
.lock
);
186 omnplay_library_draw(app
);
189 static void omnplay_library_save_file(playlist_item_t
* item
, int count
, char* filename
)
194 if((f
= fopen(filename
, "wt")))
196 char tc_in
[32], tc_dur
[32];
198 for(i
= 0; i
< count
; i
++)
199 fprintf(f
, "%s\t%s\t%s\t%s\n",
201 frames2tc(item
[i
].in
, 25.0, tc_in
),
202 frames2tc(item
[i
].dur
, 25.0, tc_dur
),
209 void omnplay_library_save(omnplay_instance_t
* app
)
211 pthread_mutex_lock(&app
->library
.lock
);
213 if(app
->library
.filename
[0])
214 omnplay_library_save_file(app
->library
.item
, app
->library
.count
,
215 app
->library
.filename
);
217 pthread_mutex_unlock(&app
->library
.lock
);
220 static void omnplay_get_content_cb(omnplay_instance_t
* app
, playlist_item_t
* item
, void* data
)
223 gtk_label_set_text(GTK_LABEL(app
->library
.refresh_ui
[1]), item
->id
);
228 static void* omnplay_library_refresh_proc(void* data
)
230 omnplay_instance_t
* app
= (omnplay_instance_t
*)data
;
232 playlist_item_t
* items
;
234 items
= (playlist_item_t
*)malloc(sizeof(playlist_item_t
) * MAX_LIBRARY_ITEMS
);
236 count
= omnplay_get_content(app
, items
, MAX_LIBRARY_ITEMS
, omnplay_get_content_cb
, NULL
);
241 gtk_label_set_text(GTK_LABEL(app
->library
.refresh_ui
[1]), "Quering whois...");
245 if(app
->library
.whois
[0])
246 omnplay_whois_list(app
, items
, &count
);
248 pthread_mutex_lock(&app
->library
.lock
);
250 for(i
= 0; i
< count
; i
++)
251 app
->library
.item
[i
] = items
[i
];
253 app
->library
.count
= count
;
255 omnplay_library_sort(app
);
257 pthread_mutex_unlock(&app
->library
.lock
);
260 omnplay_library_draw(app
);
268 omnplay_playlist_normalize(app
);
269 gtk_widget_destroy(app
->library
.refresh_ui
[0]);
276 void omnplay_library_refresh(omnplay_instance_t
* app
)
278 if(app
->library
.refresh_ui
[0])
279 pthread_join(app
->library
.refresh_thread
, NULL
);
281 /* create UI for monitoring update */
282 ui_library_refresh(app
, &app
->library
.refresh_ui
[0], &app
->library
.refresh_ui
[1]);
284 pthread_create(&app
->library
.refresh_thread
, NULL
,
285 omnplay_library_refresh_proc
, app
);
289 void omnplay_library_draw(omnplay_instance_t
* app
)
293 GtkListStore
*list_store
;
296 list_store
= GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(app
->library_grid
)));
297 gtk_list_store_clear(list_store
);
299 pthread_mutex_lock(&app
->library
.lock
);
301 for(i
= 0;i
< app
->library
.count
; i
++)
303 gtk_list_store_append(list_store
, &iter
);
305 gtk_list_store_set(list_store
, &iter
,
306 0, app
->library
.item
[i
].id
,
307 1, frames2tc(app
->library
.item
[i
].dur
, 25.0, tc
),
308 2, app
->library
.item
[i
].title
,
315 pthread_mutex_unlock(&app
->library
.lock
);
318 static void get_selected_idx_library_proc(GtkTreeModel
*model
, GtkTreePath
*path
, GtkTreeIter
*iter
, gpointer data
)
320 int idx
, *list
= (int*)data
;
321 gtk_tree_model_get(model
, iter
, 3, &idx
, -1);
322 list
[list
[0] + 1] = idx
;
323 list
[0] = list
[0] + 1;
326 static int* get_selected_idx_library(omnplay_instance_t
* app
)
329 GtkTreeSelection
*selection
;
331 selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(app
->library_grid
));
334 list
= (int*)malloc(sizeof(int) * (MAX_LIBRARY_ITEMS
+ 1));
335 memset(list
, 0, sizeof(int) * (MAX_LIBRARY_ITEMS
+ 1));
337 gtk_tree_selection_selected_foreach(
339 get_selected_idx_library_proc
,
353 playlist_item_t
* omnplay_library_get_selected(omnplay_instance_t
* app
, int *count
)
356 playlist_item_t
* items
= NULL
;
358 pthread_mutex_lock(&app
->library
.lock
);
362 idxs
= get_selected_idx_library(app
);
369 items
= (playlist_item_t
*)malloc(sizeof(playlist_item_t
) * (idxs
[0] + 1));
371 /* clear last item */
372 memset(&items
[idxs
[0]], 0, sizeof(playlist_item_t
));
375 for(i
= 0; i
< idxs
[0]; i
++)
376 items
[i
] = app
->library
.item
[idxs
[i
+ 1]];
382 pthread_mutex_unlock(&app
->library
.lock
);