GtkTargetEntry drag_targets[] = { { (char*) "application/playlist_item_t", 0, 0 } };
-gboolean instance_button_click(instance_t* app, control_buttons_t button)
+static gboolean library_tree_key(GtkWidget *widget, GdkEventKey *event, gpointer data)
+{
+ instance_t* app = (instance_t*)data;
+
+ switch(event->keyval)
+ {
+ case GDK_C:
+ case GDK_c:
+ if(event->state & GDK_CONTROL_MASK)
+ {
+ int count;
+ playlist_item_t* items;
+
+ items = library_get_selected_items(app, &count);
+
+ if(items)
+ {
+ int i;
+
+ for(i = 0; i < count; i++)
+ app->clipboard.item[i] = items[i];
+
+ app->clipboard.count = count;
+ };
+
+ return TRUE;
+ };
+ break;
+ case GDK_V:
+ case GDK_v:
+ if(event->state & GDK_CONTROL_MASK)
+ {
+ g_warning("CTRL+v\n");
+ return TRUE;
+ };
+ break;
+ case GDK_X:
+ case GDK_x:
+ if(event->state & GDK_CONTROL_MASK)
+ {
+ g_warning("CTRL+x\n");
+ return TRUE;
+ };
+ break;
+ case GDK_KEY_BackSpace:
+// omnplay_library_add(app, 0);
+ return TRUE;
+ case GDK_KEY_F5:
+// omnplay_library_refresh(app);
+ return TRUE;
+ };
+
+ return FALSE;
+};
+
+static gboolean playlist_grid_key(GtkWidget *widget, GdkEventKey *event, gpointer data)
+{
+ instance_t* app = (instance_t*)data;
+
+ switch(event->keyval)
+ {
+ case GDK_C:
+ case GDK_c:
+ if(event->state & GDK_CONTROL_MASK)
+ {
+ playlist_item_copy(app);
+ return TRUE;
+ };
+ break;
+ case GDK_V:
+ case GDK_v:
+ if(event->state & GDK_CONTROL_MASK)
+ {
+ playlist_item_paste(app, 0);
+ return TRUE;
+ };
+ break;
+ case GDK_X:
+ case GDK_x:
+ if(event->state & GDK_CONTROL_MASK)
+ {
+ playlist_item_copy(app);
+ playlist_delete_selected_items(app);
+ return TRUE;
+ };
+ break;
+ case GDK_S:
+ case GDK_s:
+ if(event->state & GDK_CONTROL_MASK)
+ {
+// omnplay_playlist_save(app);
+ return TRUE;
+ };
+ break;
+ case GDK_O:
+ case GDK_o:
+ if(event->state & GDK_CONTROL_MASK)
+ {
+// omnplay_playlist_load(app);
+ return TRUE;
+ };
+ break;
+ case GDK_KEY_uparrow:
+ if(event->state & GDK_CONTROL_MASK)
+ {
+ playlist_item_swap(app, -1);
+ return TRUE;
+ };
+ break;
+ case GDK_KEY_downarrow:
+ if(event->state & GDK_CONTROL_MASK)
+ {
+ playlist_item_swap(app, -1);
+ return TRUE;
+ };
+ break;
+ case GDK_KEY_space:
+// omnplay_ctl(app, BUTTON_PLAYER_PLAY);
+ return TRUE;
+ case GDK_KEY_Return:
+// omnplay_ctl(app, BUTTON_PLAYER_CUE);
+ return TRUE;
+ case GDK_KEY_Insert:
+// omnplay_playlist_item_add(app, 0);
+ return TRUE;
+ case GDK_KEY_Delete:
+ playlist_delete_selected_items(app);
+ return TRUE;
+ case GDK_E:
+ case GDK_e:
+// omnplay_playlist_item_edit(app);
+ return TRUE;
+ };
+
+ return FALSE;
+};
+
+static gboolean library_tree_button(GtkWidget *widget, GdkEventButton *event, gpointer data)
+{
+// g_warning("on_library_grid_button: event->button=%d, event->type=%d", event->button, event->type);
+
+ if(event->button==1 && event->type==GDK_2BUTTON_PRESS)
+ {
+// omnplay_library_add((omnplay_instance_t* )data, 0);
+ return TRUE;
+ };
+
+ return FALSE;
+};
+
+static gboolean playlist_grid_button(GtkWidget *widget, GdkEventButton *event, gpointer data)
+{
+ instance_t* app = (instance_t*)data;
+
+// g_warning("on_playlist_grid_button");
+
+ if(event->button==1 && event->type==GDK_2BUTTON_PRESS)
+ {
+// omnplay_playlist_item_edit(app);
+ return TRUE;
+ };
+
+ return FALSE;
+};
+
+static gboolean instance_button_click(instance_t* app, control_buttons_t button)
{
-#if 0
switch(button)
{
case BUTTON_PLAYLIST_ITEM_ADD:
- omnplay_playlist_item_add(app, 0);
+ playlist_item_add(app, 0);
break;
case BUTTON_PLAYLIST_ITEM_DEL:
- omnplay_playlist_item_del(app);
+ playlist_delete_selected_items(app);
break;
case BUTTON_PLAYLIST_ITEM_EDIT:
- omnplay_playlist_item_edit(app);
+ playlist_item_edit(app);
break;
case BUTTON_PLAYLIST_LOAD:
- omnplay_playlist_load(app);
+ playlist_load(app);
break;
case BUTTON_PLAYLIST_SAVE:
- omnplay_playlist_save(app);
+ playlist_save(app);
break;
case BUTTON_PLAYLIST_BLOCK_SINGLE:
case BUTTON_PLAYLIST_BLOCK_LOOP:
- omnplay_playlist_block(app, button);
+ playlist_block(app, (BUTTON_PLAYLIST_BLOCK_LOOP == button)?1:0);
break;
case BUTTON_PLAYLIST_ITEM_UP:
- omnplay_playlist_item_swap(app, -1);
+ playlist_item_swap(app, -1);
break;
case BUTTON_PLAYLIST_ITEM_DOWN:
- omnplay_playlist_item_swap(app, +1);
+ playlist_item_swap(app, +1);
break;
case BUTTON_PLAYER_CUE:
case BUTTON_PLAYER_PLAY:
case BUTTON_PLAYER_PAUSE:
case BUTTON_PLAYER_STOP:
- omnplay_ctl(app, button);
+// omnplay_ctl(app, button);
break;
case BUTTON_LIBRARY_ADD:
- omnplay_library_add(app, 0);
+// omnplay_library_add(app, 0);
+ playlist_item_add_from_library(app, 0);
break;
case BUTTON_LIBRARY_REFRESH:
- omnplay_library_refresh(app);
+// omnplay_library_refresh(app);
break;
case BUTTON_LIBRARY_FIND:
- omnplay_library_search(app, 0);
+// omnplay_library_search(app, 0);
break;
case BUTTON_LIBRARY_FIND_NEXT:
- omnplay_library_search(app, 1);
+// omnplay_library_search(app, 1);
break;
case BUTTON_PLAYLIST_RELINK:
- omnplay_playlist_relink(app);
+// omnplay_playlist_relink(app);
break;
+ default:
+ g_warning("instance_button_click: unknow button clicked");
};
-#endif
return TRUE;
};
gtk_signal_connect( GTK_OBJECT( app->window ), "destroy",
GTK_SIGNAL_FUNC(on_main_window_destroy), app);
-#if 0
gtk_widget_add_events(app->playlist_grid, GDK_BUTTON_PRESS_MASK);
gtk_widget_add_events(app->playlist_grid, GDK_KEY_PRESS_MASK);
gtk_signal_connect(GTK_OBJECT(app->playlist_grid), "key-press-event",
- GTK_SIGNAL_FUNC(on_playlist_grid_key), app);
+ GTK_SIGNAL_FUNC(playlist_grid_key), app);
- gtk_widget_add_events(app->library_grid, GDK_BUTTON_PRESS_MASK);
- gtk_widget_add_events(app->library_grid, GDK_KEY_PRESS_MASK);
- gtk_signal_connect(GTK_OBJECT(app->library_grid), "key-press-event",
- GTK_SIGNAL_FUNC(on_library_grid_key), app);
+ gtk_widget_add_events(app->library_tree, GDK_BUTTON_PRESS_MASK);
+ gtk_widget_add_events(app->library_tree, GDK_KEY_PRESS_MASK);
+ gtk_signal_connect(GTK_OBJECT(app->library_tree), "key-press-event",
+ GTK_SIGNAL_FUNC(library_tree_key), app);
gtk_signal_connect(GTK_OBJECT(app->playlist_grid), "button-press-event",
- GTK_SIGNAL_FUNC(on_playlist_grid_button), app);
+ GTK_SIGNAL_FUNC(playlist_grid_button), app);
- gtk_signal_connect(GTK_OBJECT(app->library_grid), "button-press-event",
- GTK_SIGNAL_FUNC(on_library_grid_button), app);
-#endif
+ gtk_signal_connect(GTK_OBJECT(app->library_tree), "button-press-event",
+ GTK_SIGNAL_FUNC(library_tree_button), app);
/* create lock */
pthread_mutexattr_init(&attr);
#include "playlist.h"
#include "ui.h"
#include "timecode.h"
+#include "library.h"
extern GtkTargetEntry drag_targets[];
start = list[0];
stop = list[c - 1];
+ if(loop)
+ loop = PLAYLIST_BLOCK_LOOP;
+
if(!playlist_range_cued(app, start, stop))
{
/* update selected item */
pthread_mutex_unlock(&app->playlist.lock);
};
-#if 0
+void playlist_item_copy(instance_t* app)
+{
+ int *list, i, c;
+
+ list = playlist_get_selected_items_idx(app, &c);
+ if(!list) return;
+
+ for(i = 0; i < c; i++)
+ app->clipboard.item[i] = app->playlist.item[list[i]];
+ app->clipboard.count = c;
+
+ free(list);
+};
+
+void playlist_item_paste(instance_t* app, int after)
+{
+ int idx, i;
+ playlist_item_type_t t;
+
+ /* find insert position */
+ idx = playlist_get_first_selected_item_idx(app);
+ if(idx < 0)
+ idx = 0;
+ else
+ idx += (after)?1:0;
+
+ if(!playlist_insert_check(app, idx, &t))
+ return;
+
+ /* clear item */
+ if(app->clipboard.count)
+ {
+ for(i = 0; i < app->clipboard.count; i++)
+ {
+ app->clipboard.item[i].type = t;
+ app->clipboard.item[i].error = 0;
+ };
+ playlist_insert_items(app, idx, app->clipboard.item, app->clipboard.count);
+ };
+};
+
+void playlist_item_swap(instance_t* app, int dir)
+{
+ int sel, a, b, e = 1;
+ playlist_item_t item;
+
+ /* find insert position */
+ sel = playlist_get_first_selected_item_idx(app);
+ if(sel < 0)
+ return;
+
+ if(dir < 0)
+ {
+ a = sel - 1;
+ b = sel;
+ sel = a;
+ }
+ else
+ {
+ a = sel;
+ b = sel + 1;
+ sel = b;
+ };
+
+ /* check for playing block */
+ if(playlist_idx_cued(app, a, NULL) || playlist_idx_cued(app, b, NULL))
+ return;
+
+ pthread_mutex_lock(&app->playlist.lock);
+ pthread_mutex_lock(&app->players.lock);
+
+ /* swap */
+ item = app->playlist.item[a];
+ app->playlist.item[a] = app->playlist.item[b];
+ app->playlist.item[b] = item;
+
+ /* rewite type */
+ if(app->playlist.item[a].type != app->playlist.item[b].type)
+ {
+ e = 0;
+ app->playlist.item[a].type = PLAYLIST_ITEM_BLOCK_SINGLE;
+ app->playlist.item[b].type = PLAYLIST_ITEM_BLOCK_SINGLE;
+ };
+
+ /* redraw main items */
+ ui_playlist_draw_item(app, a);
+ ui_playlist_draw_item(app, b);
+
+ /* fix block types */
+ if(a && !e)
+ {
+ app->playlist.item[a - 1].type = (playlist_item_type_t)(app->playlist.item[a - 1].type |
+ PLAYLIST_BLOCK_END);
+ ui_playlist_draw_item(app, a - 1);
+ };
+ if(b + 1 < app->playlist.count && !e)
+ {
+ app->playlist.item[b + 1].type = (playlist_item_type_t)(app->playlist.item[b + 1].type |
+ PLAYLIST_BLOCK_BEGIN);
+ ui_playlist_draw_item(app, b + 1);
+ };
+
+ /* select */
+ ui_playlist_select_item(app, sel);
+
+ pthread_mutex_unlock(&app->players.lock);
+ pthread_mutex_unlock(&app->playlist.lock);
+};
+
-static int load_file_ply(omnplay_instance_t* app, char* filename)
+static int playlist_load_file_ply(instance_t* app, char* filename)
{
FILE* f;
char *ID, *CH, *B, *IN, *OUT, *DUR, *REST, *l;
pthread_mutex_lock(&app->playlist.lock);
for(i = 0; i < count && app->playlist.count + 1 < MAX_PLAYLIST_ITEMS; i++)
{
- omnplay_library_normalize_item(app, &items[i]);
+// omnplay_library_normalize_item(app, &items[i]);
app->playlist.item[app->playlist.count++] = items[i];
};
app->playlist.ver_curr++;
return count;
};
-void omnplay_playlist_load(omnplay_instance_t* app)
+void playlist_load(instance_t* app)
{
int r;
GtkWidget *dialog;
filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
- r = load_file_ply(app, filename);
+ r = playlist_load_file_ply(app, filename);
if(r)
- omnplay_playlist_draw(app);
+ ui_playlist_draw(app);
if(app->playlist.path)
g_free(app->playlist.path);
gtk_widget_destroy (dialog);
};
-static int save_file_ply(omnplay_instance_t* app, char* filename)
+static int playlist_save_file_ply(instance_t* app, char* filename)
{
int i;
FILE* f;
frames2tc(app->playlist.item[i].in, 25.0, tc1),
frames2tc(app->playlist.item[i].in + app->playlist.item[i].dur, 25.0, tc2),
frames2tc(app->playlist.item[i].dur, 25.0, tc3));
+
+ fclose(f);
};
free(filename);
return 0;
};
-void omnplay_playlist_save(omnplay_instance_t* app)
+void playlist_save(instance_t* app)
{
int r;
GtkWidget *dialog;
r = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(dialog))), "id"));
- r = save_file_ply(app, filename);
+ r = playlist_save_file_ply(app, filename);
if(app->playlist.path)
g_free(app->playlist.path);
}
gtk_widget_destroy (dialog);
-
};
-void omnplay_playlist_draw(omnplay_instance_t* app)
-{
- int i;
- int* sels;
- char tc1[12], tc2[12];
- GtkListStore *list_store;
- GtkTreeIter iter;
- sels = omnplay_selected_idxs_playlist(app);
-
- list_store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(app->playlist_grid)));
- gtk_list_store_clear(list_store);
+void playlist_relink(instance_t* app)
+{
+ int i, cnt;
+ int *list;
pthread_mutex_lock(&app->playlist.lock);
-
- for(i = 0;i < app->playlist.count; i++)
+ list = playlist_get_selected_items_idx(app, &cnt);
+ if(list)
{
- char ch[3];
-
- if(PLAYLIST_BLOCK_BEGIN & app->playlist.item[i].type)
- snprintf(ch, sizeof(ch), "%c", 'A' + app->playlist.item[i].player);
- else
- ch[0] = 0;
-
- gtk_list_store_append(list_store, &iter);
-
- gtk_list_store_set(list_store, &iter,
- 0, "",
- 1, app->playlist.block_icons[app->playlist.item[i].type],
- 2, ch,
- 3, app->playlist.item[i].id,
- 4, frames2tc(app->playlist.item[i].in, 25.0, tc1),
- 5, frames2tc(app->playlist.item[i].dur, 25.0, tc2),
- 6, app->playlist.item[i].title,
- 7, i,
- 8, (app->playlist.item[i].error != 0),
- 9, (app->playlist.item[i].error & PLAYLIST_ITEM_ERROR_LIB)?"red":"orange",
- -1 );
- }
-
- app->playlist.ver_prev = app->playlist.ver_curr;
-
- if(sels)
- {
- GtkTreePath *path;
+ for(i = 0; i < cnt; i++)
+ {
+ /* check for playing block */
+ if(playlist_idx_cued(app, list[i], NULL))
+ continue;
- /* select */
- path = gtk_tree_path_new_from_indices(sels[1], -1);
- gtk_tree_selection_select_path(gtk_tree_view_get_selection(GTK_TREE_VIEW(app->playlist_grid)), path);
- gtk_tree_view_set_cursor(GTK_TREE_VIEW(app->playlist_grid), path, NULL, FALSE);
- gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(app->playlist_grid), path, NULL, FALSE, 0, 0);
- gtk_tree_path_free(path);
+ /* relink item */
+ library_relink_item(app, &app->playlist.item[list[i]]);
+ };
- free(sels);
+ free(list);
};
-
pthread_mutex_unlock(&app->playlist.lock);
+
+ /* redraw playlist */
+ ui_playlist_draw(app);
};
-typedef struct omnplay_playlist_draw_item_desc
+void playlist_item_add(instance_t* app, int after)
{
- GtkListStore *list_store;
- omnplay_instance_t* app;
int idx;
-} omnplay_playlist_draw_item_t;
+ playlist_item_t item;
+ playlist_item_type_t t;
-static gboolean omnplay_playlist_draw_item_proc(
- GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer user_data)
-{
- int i;
- char tc1[12], tc2[12];
- char ch[3];
- omnplay_playlist_draw_item_t* item = (omnplay_playlist_draw_item_t*)user_data;
- omnplay_instance_t* app = item->app;
+ /* find insert position */
+ idx = playlist_get_first_selected_item_idx(app);
+ if(idx < 0)
+ idx = 0;
+ else
+ idx += (after)?1:0;
- gtk_tree_model_get(model, iter, 7, &i, -1);
+ if(!playlist_insert_check(app, idx, &t))
+ return;
- if(i != item->idx) return FALSE;
+ g_warning("allowed insert into idx=%d\n", idx);
- if(PLAYLIST_BLOCK_BEGIN & app->playlist.item[i].type)
- snprintf(ch, sizeof(ch), "%c", 'A' + app->playlist.item[i].player);
- else
- ch[0] = 0;
-
- gtk_list_store_set(item->list_store, iter,
- 0, "",
- 1, app->playlist.block_icons[app->playlist.item[i].type],
- 2, ch,
- 3, app->playlist.item[i].id,
- 4, frames2tc(app->playlist.item[i].in, 25.0, tc1),
- 5, frames2tc(app->playlist.item[i].dur, 25.0, tc2),
- 6, app->playlist.item[i].title,
- 7, i,
- 8, (app->playlist.item[i].error != 0),
- 9, (app->playlist.item[i].error & PLAYLIST_ITEM_ERROR_LIB)?"red":"orange",
- -1 );
-
- return TRUE;
+ /* clear item */
+ memset(&item, 0, sizeof(playlist_item_t));
+ if(ui_playlist_item_dialog(app, &item))
+ {
+ library_normalize_item(app, &item);
+ item.type = t;
+ playlist_insert_items(app, idx, &item, 1);
+ };
};
-void omnplay_playlist_draw_item(omnplay_instance_t* app, int idx)
+void playlist_item_edit(instance_t* app)
{
- GtkListStore *list_store;
- omnplay_playlist_draw_item_t item;
+ int idx;
+ playlist_item_t item;
- list_store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(app->playlist_grid)));
+ /* find insert position */
+ idx = playlist_get_first_selected_item_idx(app);
- pthread_mutex_lock(&app->playlist.lock);
+ if(idx < 0)
+ return;
- item.idx = idx;
- item.app = app;
- item.list_store = list_store;
- gtk_tree_model_foreach(GTK_TREE_MODEL(list_store), omnplay_playlist_draw_item_proc, &item);
+ /* check for playing block */
+ if(playlist_idx_cued(app, idx, NULL))
+ return;
- pthread_mutex_unlock(&app->playlist.lock);
+ item = app->playlist.item[idx];
+
+ if(ui_playlist_item_dialog(app, &item))
+ {
+ library_normalize_item(app, &item);
+ app->playlist.item[idx] = item;
+ ui_playlist_draw_item(app, idx);
+ };
};
-static gboolean omnplay_playlist_draw_item_rem_proc(
- GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer user_data)
+void playlist_item_add_from_library(instance_t* app, int after)
{
- int i;
- void** args = (void**)user_data;
- GtkListStore *list_store = (GtkListStore *)args[1];
- int idx = (int)args[2];
- char* rem = (char*)args[3];
-
- gtk_tree_model_get(model, iter, 7, &i, -1);
-
- if(i != idx) return FALSE;
-
- gtk_list_store_set(list_store, iter, 0, rem, -1);
-
- return TRUE;
};
-void omnplay_playlist_draw_item_rem(omnplay_instance_t* app, int idx, char* rem)
+void playlist_normalize(instance_t* app)
{
- void* item[4];
- GtkListStore *list_store;
-
- list_store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(app->playlist_grid)));
-
- item[0] = (void*)app;
- item[1] = (void*)list_store;
- item[2] = (void*)idx;
- item[3] = (void*)rem;
+ int i;
- gtk_tree_model_foreach(GTK_TREE_MODEL(list_store), omnplay_playlist_draw_item_rem_proc, item);
+ /* normalize playlist */
+ for(i = 0; i < app->playlist.count; i++)
+ if(library_normalize_item(app, &app->playlist.item[i]))
+ ui_playlist_draw_item(app, i);
};
-
-#endif