/* LASH Control Panel * Copyright (C) 2006 Dave Robillard * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include #include #include "panel.h" #include "project.h" #include "config.h" #define WINDOW_TITLE "LASH Control Panel" void quit_cb(GtkButton * button, void *data); project_t * get_project(panel_t * panel, const char *const name) { project_t *project = NULL; GtkTreeModel *tree_model = GTK_TREE_MODEL(panel->projects); GtkTreeIter iter; if (gtk_tree_model_get_iter_first(tree_model, &iter)) do { gtk_tree_model_get(tree_model, &iter, PROJECT_PROJECT_COLUMN, &project, -1); if (!strcmp(name, project->name)) return project; } while (gtk_tree_model_iter_next(tree_model, &iter)); fprintf(stderr, "Error: Unable to find project '%s'!", name); return NULL; } void error_dialog(panel_t * client, const char *message) { GtkWidget *dialog; gint response; dialog = gtk_message_dialog_new(GTK_WINDOW(client->window), GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "%s", message); response = gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); } void about_cb(GtkButton* button, void* client) { /*panel_t* panel = (panel_t*)client;*/ GtkWidget *dialog; gint response; dialog = gtk_about_dialog_new(); gtk_about_dialog_set_name(GTK_ABOUT_DIALOG(dialog), "LASH Panel"); gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(dialog), PACKAGE_VERSION); gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(dialog), "Copyright (C) 2006 Dave Robillard"); gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(dialog), "http://www.nongnu.org/lash"); response = gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); } void server_disconnect(panel_t * panel) { error_dialog(panel, "The server disconnected!"); exit(0); } void event_project_add(panel_t * panel, lash_event_t * event) { project_t *project = NULL; const char *name = lash_event_get_string(event); GtkTreeIter iter; printf("Add project: %s\n", name); if (panel->num_projects == 0) gtk_label_set_text(GTK_LABEL(panel->no_projects_label), ""); gtk_list_store_append(panel->projects, &iter); project = project_create(panel->lash_client, name); gtk_list_store_set(panel->projects, &iter, PROJECT_PROJECT_COLUMN, project, -1); project->page_number = gtk_notebook_append_page(GTK_NOTEBOOK(panel->project_notebook), project->box, project->tab_label); panel->num_projects++; } void event_project_remove(panel_t * panel, lash_event_t * event) { const char *name = lash_event_get_string(event); project_t *project = get_project(panel, name); GtkTreeModel *tree_model = GTK_TREE_MODEL(panel->projects); GtkTreeIter iter; printf("Remove project: %s\n", name); if (panel->num_projects == 1) gtk_label_set_text(GTK_LABEL(panel->no_projects_label), "(No projects open. Start a LASH client, or load a project from the File menu)"); if (project != NULL) if (gtk_tree_model_get_iter_first(tree_model, &iter)) do { gtk_tree_model_get(tree_model, &iter, PROJECT_PROJECT_COLUMN, &project, -1); if (!strcmp(name, project->name)) { gtk_list_store_remove(panel->projects, &iter); gtk_notebook_remove_page(GTK_NOTEBOOK (panel->project_notebook), project->page_number); project_destroy(project); break; } } while (gtk_tree_model_iter_next(tree_model, &iter)); panel->num_projects--; } void event_project_dir(panel_t * panel, lash_event_t * event) { const char *name = lash_event_get_project(event); const char *dir = lash_event_get_string(event); project_t *project = get_project(panel, name); printf("Change project dir: %s = %s\n", name, dir); if (project != NULL) { project_set_dir(project, dir); } } void event_project_name(panel_t * panel, lash_event_t * event) { const char *old_name = lash_event_get_project(event); const char *new_name = lash_event_get_string(event); project_t *project = get_project(panel, old_name); printf("Change project name: %s = %s\n", old_name, new_name); if (project != NULL) project_set_name(project, new_name); } void event_client_add(panel_t * panel, lash_event_t * event) { const char *project_name = lash_event_get_project(event); project_t *project = get_project(panel, project_name); char *client_id_str = malloc(37); char *search_id_str = NULL; uuid_t client_id; GtkTreeIter iter; GtkTreeModel *tree_model; int client_exists = FALSE; lash_event_get_client_id(event, client_id); uuid_unparse(client_id, client_id_str); printf("Add client (%s): %s\n", project_name, client_id_str); if (client_id != NULL && project != NULL) { tree_model = GTK_TREE_MODEL(project->clients); if (gtk_tree_model_get_iter_first(tree_model, &iter)) { do { gtk_tree_model_get(tree_model, &iter, CLIENT_ID_COLUMN, &search_id_str, -1); if (!strcmp(search_id_str, client_id_str)) { client_exists = TRUE; break; } } while (gtk_tree_model_iter_next(tree_model, &iter)); } if (!client_exists) { gtk_list_store_append(project->clients, &iter); gtk_list_store_set(project->clients, &iter, CLIENT_ID_COLUMN, client_id_str, -1); } } } void event_client_name(panel_t * panel, lash_event_t * event) { const char *project_name = lash_event_get_project(event); const char *client_name = lash_event_get_string(event); project_t *project = get_project(panel, project_name); GtkTreeModel *tree_model = NULL; GtkTreeIter iter; uuid_t client_id; char *search_id_str = NULL; char *client_id_str = malloc(37); lash_event_get_client_id(event, client_id); uuid_unparse(client_id, client_id_str); printf("Change client name (%s): %s = %s\n", project_name, client_id_str, client_name); if (project != NULL) { tree_model = GTK_TREE_MODEL(project->clients); if (gtk_tree_model_get_iter_first(tree_model, &iter)) do { gtk_tree_model_get(tree_model, &iter, CLIENT_ID_COLUMN, &search_id_str, -1); if (!strcmp(search_id_str, client_id_str)) { gtk_list_store_set(project->clients, &iter, CLIENT_NAME_COLUMN, client_name, -1); break; } } while (gtk_tree_model_iter_next(tree_model, &iter)); } } void deal_with_event(panel_t * panel, lash_event_t * event) { switch (lash_event_get_type(event)) { case LASH_Project_Add: event_project_add(panel, event); break; case LASH_Project_Remove: event_project_remove(panel, event); break; case LASH_Project_Dir: event_project_dir(panel, event); break; case LASH_Project_Name: event_project_name(panel, event); break; case LASH_Client_Add: event_client_add(panel, event); break; case LASH_Client_Name: event_client_name(panel, event); break; case LASH_Jack_Client_Name: break; case LASH_Alsa_Client_ID: break; case LASH_Percentage: break; default: break; } } gboolean idle_cb(gpointer data) { panel_t *panel; lash_event_t *event; /*lash_config_t * config; */ panel = (panel_t *) data; while ((event = lash_get_event(panel->lash_client))) { deal_with_event(panel, event); } /*while ((config = lash_get_config(panel->lash_client)) ) { * add_config(panel, config); * } */ return TRUE; } void quit_cb(GtkButton * button, void *data) { gtk_main_quit(); } void open_cb(GtkButton * button, void *data) { panel_t *panel = (panel_t *) data; int response = GTK_RESPONSE_NONE; char *filename = NULL; lash_event_t *event = NULL; GtkWidget *open_dialog = gtk_file_chooser_dialog_new("Open Project", GTK_WINDOW(panel->window), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL); response = gtk_dialog_run(GTK_DIALOG(open_dialog)); if (response == GTK_RESPONSE_OK) { filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(open_dialog)); event = lash_event_new_with_type(LASH_Project_Add); lash_event_set_string(event, filename); lash_send_event(panel->lash_client, event); } gtk_widget_destroy(open_dialog); } panel_t * panel_create(lash_client_t * lash_client) { panel_t *panel = NULL; GtkWidget *main_box = NULL; GtkWidget *menu_bar = NULL; GtkWidget *file_menu = NULL; GtkWidget *file_menuitem = NULL; GtkWidget *help_menu = NULL; GtkWidget *help_menuitem = NULL; GtkWidget *open_menu_item = NULL; GtkWidget *menu_separator = NULL; GtkWidget *quit_menu_item = NULL; GtkWidget *about_menu_item = NULL; guint status_context; panel = lash_malloc(sizeof(panel_t)); panel->lash_client = lash_client; panel->projects = gtk_list_store_new(PROJECT_NUM_COLUMNS, G_TYPE_POINTER); panel->num_projects = 0; panel->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(panel->window), WINDOW_TITLE); gtk_window_set_default_size(GTK_WINDOW(panel->window), 450, 282); g_signal_connect(G_OBJECT(panel->window), "delete_event", G_CALLBACK(quit_cb), NULL); main_box = gtk_vbox_new(FALSE, 0); gtk_widget_show(main_box); gtk_container_add(GTK_CONTAINER(panel->window), main_box); /* * menu bar */ file_menu = gtk_menu_new(); open_menu_item = gtk_image_menu_item_new_with_label("Open Project..."); gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(open_menu_item), gtk_image_new_from_stock(GTK_STOCK_OPEN, GTK_ICON_SIZE_MENU)); gtk_menu_shell_append(GTK_MENU_SHELL(file_menu), open_menu_item); g_signal_connect(G_OBJECT(open_menu_item), "activate", G_CALLBACK(open_cb), panel); gtk_widget_show(open_menu_item); menu_separator = gtk_separator_menu_item_new(); gtk_menu_shell_append(GTK_MENU_SHELL(file_menu), menu_separator); gtk_widget_show(menu_separator); quit_menu_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT, NULL); gtk_menu_shell_append(GTK_MENU_SHELL(file_menu), quit_menu_item); g_signal_connect(G_OBJECT(quit_menu_item), "activate", G_CALLBACK(quit_cb), panel); gtk_widget_show(quit_menu_item); file_menuitem = gtk_menu_item_new_with_label("File"); gtk_widget_show(file_menuitem); gtk_menu_item_set_submenu(GTK_MENU_ITEM(file_menuitem), file_menu); help_menu = gtk_menu_new(); help_menuitem = gtk_menu_item_new_with_label("Help"); gtk_widget_show(help_menuitem); gtk_menu_item_set_submenu(GTK_MENU_ITEM(help_menuitem), help_menu); about_menu_item = gtk_image_menu_item_new_with_label("About..."); gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(about_menu_item), gtk_image_new_from_stock(GTK_STOCK_ABOUT, GTK_ICON_SIZE_MENU)); gtk_menu_shell_append(GTK_MENU_SHELL(help_menu), about_menu_item); g_signal_connect(G_OBJECT(about_menu_item), "activate", G_CALLBACK(about_cb), panel); gtk_widget_show(about_menu_item); menu_bar = gtk_menu_bar_new(); gtk_widget_show(menu_bar); gtk_box_pack_start(GTK_BOX(main_box), menu_bar, FALSE, TRUE, 0); gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), file_menuitem); gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), help_menuitem); /* * projects notebook */ panel->project_notebook = gtk_notebook_new(); gtk_notebook_set_tab_pos(GTK_NOTEBOOK(panel->project_notebook), GTK_POS_TOP); gtk_widget_show(panel->project_notebook); gtk_box_pack_start(GTK_BOX(main_box), panel->project_notebook, TRUE, TRUE, 0); /* * "no project" label (shown instead of a notebook tab when no projects are present) */ panel->no_projects_label = gtk_label_new("No projects open. Start a LASH client, or load a project from the File menu."); gtk_widget_show(panel->no_projects_label); gtk_box_pack_start(GTK_BOX(main_box), panel->no_projects_label, FALSE, TRUE, 10); /* * status bar */ panel->status_bar = gtk_statusbar_new(); gtk_widget_show(panel->status_bar); status_context = gtk_statusbar_get_context_id(GTK_STATUSBAR(panel->status_bar), "connected"); gtk_statusbar_push(GTK_STATUSBAR(panel->status_bar), status_context, g_strdup_printf("Connected to server %s", lash_get_server_name(lash_client))); gtk_box_pack_start(GTK_BOX(main_box), panel->status_bar, FALSE, TRUE, 0); gtk_timeout_add(1000, idle_cb, panel); gtk_widget_show(panel->window); return panel; }