#include #include #include #include #include "misc.h" #include "firststart.h" typedef struct { char *title; int type; gboolean complete; GtkWidget * (*create) (); GtkWidget *page; }WIZARD_PAGES; static int WIZ_connect_ready = 0; static int WIZ_library_ready = 0; static GtkAssistant *wiz; enum { WIZ_INTRO_PAGE=0, WIZ_DB_PAGE, WIZ_MUSIC_PAGE, WIZ_LASTFM_PAGE, WIZ_SUMMARY_PAGE }; static GtkWidget *create_intro_page(); static GtkWidget *create_database_config_page(); static GtkWidget *create_library_config_page(); static GtkWidget *create_lastfm_config_page(); static GtkWidget *create_summary_page(); static WIZARD_PAGES wiz_pages[] = { { "Introduction",GTK_ASSISTANT_PAGE_INTRO,TRUE,create_intro_page,NULL }, { "Database Configuration",GTK_ASSISTANT_PAGE_CONTENT,FALSE, create_database_config_page,NULL }, { "Music Library",GTK_ASSISTANT_PAGE_CONTENT,FALSE, create_library_config_page,NULL }, { "Last.fm Configuration",GTK_ASSISTANT_PAGE_CONTENT,FALSE, create_lastfm_config_page,NULL }, { "That's all folks!",GTK_ASSISTANT_PAGE_CONFIRM,TRUE,create_summary_page,NULL }, { NULL } }; static GtkWidget *create_intro_page(){ GtkWidget *page; GtkWidget *intro; intro = gtk_label_new( "Welcome to the Amatory Media Player first start wizard. This assistant\n\ will guide you through the initial configuration process."); gtk_misc_set_alignment(GTK_MISC(intro),0,0); page = gtk_hbox_new(FALSE,0); gtk_box_pack_start(GTK_BOX(page),intro,FALSE,FALSE,0); gtk_container_set_border_width (GTK_CONTAINER (page), 20); return page; } static GtkWidget *create_lastfm_config_page(){ GtkWidget *page; GtkWidget *label; page = gtk_vbox_new(FALSE,10); gtk_container_set_border_width (GTK_CONTAINER (page), 20); label = gtk_label_new( "Amatory uses Last.fm extensively to provide recommendations, statistics,\ and album covers. If you have a last.fm account, please enter your login\ information below"); gtk_label_set_line_wrap(GTK_LABEL(label),TRUE); gtk_misc_set_alignment(GTK_MISC(label),0,0); gtk_box_pack_start(GTK_BOX(page),label,FALSE,FALSE,0); g_signal_connect( G_OBJECT( label ), "size-allocate", G_CALLBACK( on_size_allocate_tadeboro_hack ), NULL ); return page; } static void on_database_driver_changed(GtkComboBox *combo, GtkWidget *widget){ WIZ_connect_ready |= 0x1; if(WIZ_connect_ready == 0x7)gtk_widget_set_sensitive(widget,TRUE); } static void on_database_user_changed(GtkEditable *editable, GtkWidget *widget){ if(gtk_entry_get_text_length(GTK_ENTRY(editable))) WIZ_connect_ready |= 0x2; else WIZ_connect_ready &= ~0x2; gtk_widget_set_sensitive(widget,(WIZ_connect_ready == 0x7) ? TRUE : FALSE); } static void on_database_pass_changed(GtkEditable *editable, GtkWidget *widget){ if(gtk_entry_get_text_length(GTK_ENTRY(editable))) WIZ_connect_ready |= 0x4; else WIZ_connect_ready &= ~0x4; gtk_widget_set_sensitive(widget,(WIZ_connect_ready == 0x7) ? TRUE : FALSE); } static void on_database_connect_clicked(GtkWidget *button, GtkLabel *label){ GtkWidget *widget; widget = g_object_get_data(G_OBJECT(button),"user"); gtk_widget_set_sensitive(widget,FALSE); widget = g_object_get_data(G_OBJECT(button),"pass"); gtk_widget_set_sensitive(widget,FALSE); widget = g_object_get_data(G_OBJECT(button),"combo"); gtk_widget_set_sensitive(widget,FALSE); gtk_label_set_text(label,"Connected"); gtk_widget_set_sensitive(button,FALSE); gtk_assistant_set_page_complete(wiz,wiz_pages[WIZ_DB_PAGE].page,TRUE); } static void on_add_folder_clicked(GtkWidget *button, GtkFileChooser *chooser){ GtkListStore *store; GtkTreeIter iter; gchar *folder=NULL; gchar *existing=NULL; gboolean rv; folder = gtk_file_chooser_get_filename(chooser); store = g_object_get_data(G_OBJECT(button),"store"); // Check if path already exists rv = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store),&iter); while(rv == TRUE){ gtk_tree_model_get(GTK_TREE_MODEL(store),&iter,0,&existing,-1); if(strcmp(existing,folder)== 0) { g_free(existing); goto done; } g_free(existing); rv = gtk_tree_model_iter_next(GTK_TREE_MODEL(store),&iter); } gtk_list_store_append (store, &iter); gtk_list_store_set (store, &iter,0,folder,-1); WIZ_library_ready++; gtk_assistant_set_page_complete(GTK_ASSISTANT(wiz), wiz_pages[WIZ_MUSIC_PAGE].page,TRUE); done: g_free(folder); } static gboolean on_treeview_key_press_event(GtkTreeView *view,GdkEventKey *event,gpointer udata){ gboolean rv; GList *list=NULL; GList *walker=NULL; GtkTreeModel *model; GtkTreeIter iter; GtkTreeSelection *selector; rv = FALSE; model = gtk_tree_view_get_model(view); selector = gtk_tree_view_get_selection (view); if(event->keyval == GDK_Delete){ if(gtk_tree_selection_count_selected_rows(selector) == 0){ return TRUE; } /* Get all selected rows */ list = gtk_tree_selection_get_selected_rows(selector,NULL); /* Walk backwards or else we mess with the paths */ walker = g_list_last(list); for(;walker!=NULL;walker=walker->prev){ rv = gtk_tree_model_get_iter(model,&iter,walker->data); if(rv==FALSE){ printf("couldnt find iter for path\n"); goto done; } rv = gtk_list_store_remove(GTK_LIST_STORE(model),&iter); WIZ_library_ready--; } done: g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL); g_list_free (list); } if(!WIZ_library_ready) gtk_assistant_set_page_complete(GTK_ASSISTANT(wiz), wiz_pages[WIZ_MUSIC_PAGE].page,FALSE); return rv; } static GtkWidget *create_database_config_page(){ GtkWidget *page; GtkWidget *combo; GtkWidget *button; GtkWidget *frame; GtkWidget *vbox,*hbox; GtkWidget *label; page = gtk_vbox_new(FALSE,10); gtk_container_set_border_width (GTK_CONTAINER (page), 20); label = gtk_label_new( "Please select a database driver and enter login information. Then click\ 'connect' to verify the connection before continuing on to the\ next page\n"); gtk_label_set_line_wrap(GTK_LABEL(label),TRUE); gtk_misc_set_alignment(GTK_MISC(label),0,0); gtk_box_pack_start(GTK_BOX(page),label,FALSE,FALSE,0); g_signal_connect( G_OBJECT( label ), "size-allocate", G_CALLBACK( on_size_allocate_tadeboro_hack ), NULL ); /* Driver selection */ frame = gtk_frame_new("Database Drivers Available"); combo = gtk_combo_box_new_text(); gtk_combo_box_append_text(GTK_COMBO_BOX(combo),"MySQL"); gtk_combo_box_append_text(GTK_COMBO_BOX(combo),"SQLite"); vbox = gtk_vbox_new(FALSE,0); gtk_container_add(GTK_CONTAINER(vbox),combo); gtk_container_set_border_width (GTK_CONTAINER (vbox),10); gtk_container_add(GTK_CONTAINER(frame),vbox); gtk_box_pack_start(GTK_BOX(page),frame,FALSE,FALSE,0); /* Login credentials */ frame = gtk_frame_new("Login Information"); hbox = gtk_hbox_new(FALSE,10); vbox = gtk_vbox_new(TRUE,2); label = gtk_label_new("Username"); gtk_misc_set_alignment(GTK_MISC(label),0,0.5); gtk_box_pack_start(GTK_BOX(vbox),label,TRUE,TRUE,0); label = gtk_label_new("Password"); gtk_misc_set_alignment(GTK_MISC(label),0,0.5); gtk_box_pack_start(GTK_BOX(vbox),label,TRUE,TRUE,0); gtk_box_pack_start(GTK_BOX(hbox),vbox,FALSE,FALSE,2); vbox = gtk_vbox_new(TRUE,2); GtkWidget *user = gtk_entry_new(); GtkWidget *pass = gtk_entry_new(); gtk_entry_set_visibility(GTK_ENTRY(pass), FALSE); gtk_box_pack_start(GTK_BOX(vbox),user,TRUE,TRUE,0); gtk_box_pack_start(GTK_BOX(vbox),pass,TRUE,TRUE,0); gtk_box_pack_start(GTK_BOX(hbox),vbox,TRUE,TRUE,2); gtk_container_set_border_width (GTK_CONTAINER (hbox),10); gtk_container_add(GTK_CONTAINER(frame),hbox); gtk_box_pack_start(GTK_BOX(page),frame,FALSE,FALSE,0); /* Verification */ frame = gtk_frame_new("Verification"); button = gtk_button_new_with_label("Connect"); gtk_widget_set_sensitive(button,FALSE); label = gtk_label_new("Not connected"); g_object_set_data(G_OBJECT(button),"user",user); g_object_set_data(G_OBJECT(button),"pass",pass); g_object_set_data(G_OBJECT(button),"combo",combo); hbox = gtk_hbox_new(FALSE, 5); gtk_box_pack_start(GTK_BOX(hbox),button,FALSE,FALSE,2); gtk_box_pack_start(GTK_BOX(hbox),label,FALSE,FALSE,2); gtk_container_set_border_width (GTK_CONTAINER (hbox),10); gtk_container_add(GTK_CONTAINER(frame),hbox); gtk_box_pack_start(GTK_BOX(page),frame,FALSE,FALSE,0); g_signal_connect(G_OBJECT(user),"changed", G_CALLBACK(on_database_user_changed),button); g_signal_connect(G_OBJECT(pass),"changed", G_CALLBACK(on_database_pass_changed),button); g_signal_connect(G_OBJECT(combo),"changed", G_CALLBACK(on_database_driver_changed),button); g_signal_connect(G_OBJECT(button),"clicked", G_CALLBACK(on_database_connect_clicked),label); return page; } static GtkWidget *create_library_config_page(){ GtkWidget *page; GtkWidget *label; GtkWidget *hbox; GtkWidget *button; GtkWidget *file_button; page = gtk_vbox_new(FALSE,10); gtk_container_set_border_width (GTK_CONTAINER (page), 20); label = gtk_label_new( "Add your music collection to the database by selecting \ a folder and then clicking 'Add Folder'. You can add as many folders \ as you want. You can remove existing folders by selecting them \ from the list below and pressing the 'Delete' key\n"); gtk_label_set_line_wrap(GTK_LABEL(label),TRUE); gtk_misc_set_alignment(GTK_MISC(label),0,0); gtk_box_pack_start(GTK_BOX(page),label,FALSE,FALSE,0); g_signal_connect( G_OBJECT( label ), "size-allocate", G_CALLBACK( on_size_allocate_tadeboro_hack ), NULL ); hbox = gtk_hbox_new(FALSE,5); file_button = gtk_file_chooser_button_new("Select a music folder", GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER); gtk_box_pack_start(GTK_BOX(hbox),file_button,TRUE,TRUE,0); button = gtk_button_new_with_label(" Add Folder "); g_signal_connect(G_OBJECT(button),"clicked", G_CALLBACK(on_add_folder_clicked),file_button); gtk_box_pack_start(GTK_BOX(hbox),button,FALSE,TRUE,0); gtk_box_pack_start(GTK_BOX(page),hbox,FALSE,TRUE,0); GtkListStore *store = gtk_list_store_new(1,G_TYPE_STRING); GtkWidget *treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)); GtkCellRenderer *renderer = gtk_cell_renderer_text_new (); GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes ("Folder", renderer, "text", 0,NULL); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (treeview), TRUE); g_signal_connect(G_OBJECT(treeview),"key-press-event", G_CALLBACK(on_treeview_key_press_event),NULL); g_object_set_data(G_OBJECT(button),"store",store); g_object_unref(store); gtk_tree_selection_set_mode (gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)), GTK_SELECTION_MULTIPLE); GtkWidget *frame = gtk_frame_new(NULL); gtk_container_add(GTK_CONTAINER(frame),treeview); gtk_box_pack_start(GTK_BOX(page),frame,TRUE,TRUE,0); return page; } static GtkWidget *create_summary_page(){ GtkWidget *page; page = gtk_label_new("Summary page"); return page; } static void on_wizard_close_cancel (GtkWidget *widget, gpointer udata){ gtk_main_quit(); } int do_firststart_wizard(int argc, char **argv){ int i; gtk_init(&argc,&argv); wiz = GTK_ASSISTANT(gtk_assistant_new()); { GdkGeometry gdkGeometry; gdkGeometry.min_width= 800; gdkGeometry.min_height = 600; gtk_window_set_geometry_hints(GTK_WINDOW(wiz),GTK_WIDGET(wiz), &gdkGeometry, GDK_HINT_MIN_SIZE); } g_signal_connect (G_OBJECT (wiz), "close", G_CALLBACK (on_wizard_close_cancel), NULL); for(i=0;wiz_pages[i].title;i++){ wiz_pages[i].page = wiz_pages[i].create(); gtk_assistant_append_page(wiz,wiz_pages[i].page); gtk_assistant_set_page_type(wiz,wiz_pages[i].page,wiz_pages[i].type); gtk_assistant_set_page_title(wiz,wiz_pages[i].page,wiz_pages[i].title); gtk_assistant_set_page_complete(wiz,wiz_pages[i].page,wiz_pages[i].complete); } gtk_widget_show_all(GTK_WIDGET(wiz)); gtk_main(); return 0; }