maemo-ui/src/mmyth_ui.c
author morphbr
Thu Apr 19 22:38:46 2007 +0100 (2007-04-19)
branchtrunk
changeset 577 7dc357cbaa40
parent 244 c88244670b08
child 754 cb885ee44618
permissions -rw-r--r--
[svn r582] * GMyth-Streamer (version 0.2):
- Mencoder plugin 100% working (without mythtv stuff)
- Debug messages updated
- Bug fixes inside server/utils
     1 
     2 #include <glib-object.h>
     3 #include <sys/types.h>
     4 #include <sys/stat.h>
     5 #include <unistd.h>
     6 #include <string.h>
     7 #include <stdio.h>
     8 #include <gtk/gtk.h>
     9 #include <gdk/gdkx.h>
    10 #include <gst/interfaces/xoverlay.h>
    11 #include <assert.h>
    12 
    13 #include "mmyth_ui.h"
    14 #include "mmyth_uicommon.h"
    15 #include "mmyth_schedulerui.h"
    16 #include "mmyth_recordui.h"
    17 #include "mmyth_uisettings.h"
    18 #include "mmyth_epg_grid_view.h"
    19 #include "mmyth_tvplayer.h"
    20 
    21 /* GMyth library includes */
    22 
    23 #ifndef MAEMO_PLATFORM
    24 static gint button_press_handler (GtkWidget *widget, GdkEvent *event);
    25 #endif
    26 
    27 static MMythUiCommon *create_main_view (MMythUi * mmyth_ui);
    28 static MMythUiCommon *create_video_view (MMythUi * mmyth_ui);
    29 static MMythUiCommon *create_epg_grid_view (MMythUi * mmyth_ui);
    30 static MMythUiCommon *create_record_view (MMythUi * mmyth_ui);
    31 static MMythUiCommon *create_schedule_view (MMythUi * mmyth_ui);
    32 
    33 static void cb_video_close_button (GtkButton * button, gpointer user_data);
    34 static void cb_record_button (GtkButton * button, gpointer user_data);
    35 static void cb_menu_item_settings (GtkMenuItem *menuitem, gpointer user_data);
    36 
    37 /* main box from button box separator*/
    38 static GtkWidget *main_vseparator = NULL;
    39 
    40 GdkPixbuf *icon_sports, *icon_news, 
    41           *icon_movies, *icon_shows, *icon_default;
    42 
    43 #ifndef MAEMO_PLATFORM
    44 /* FIXME: */
    45 static MMythUi *popup_mmyth_ui;
    46 #endif
    47 
    48 MMythUi *
    49 mmyth_ui_initialize (
    50 #ifdef MAEMO_PLATFORM
    51 	HildonProgram *program,
    52 #endif
    53 	GtkWidget * main_window)
    54 {
    55     MMythUi *mmyth_ui;
    56 
    57     mmyth_ui = g_new0 (MMythUi, 1);
    58 
    59     mmyth_ui->backend_info = gmyth_backend_info_new_full( "localhost", "mythtv", "mythtv", "mythconverg", 6543 );
    60 
    61     mmyth_ui->main_window = main_window;    
    62     mmyth_ui->videow = NULL;
    63     mmyth_ui->mmyth_recordui = NULL;
    64     mmyth_ui->mmyth_schedulerui = NULL;
    65 	
    66     /* Horizontal box that divides the view into control and video area */
    67     mmyth_ui->main_hbox = gtk_hbox_new (FALSE, 0);
    68     gtk_widget_show (mmyth_ui->main_hbox);
    69     g_object_ref (mmyth_ui->main_hbox);
    70 
    71     main_bg_color.red   = 65000;
    72     main_bg_color.green = 65000;
    73     main_bg_color.blue  = 65000;
    74     
    75     
    76 #ifndef MAEMO_PLATFORM
    77     /* Popup menu */
    78     popup_mmyth_ui = mmyth_ui;
    79     g_signal_connect (G_OBJECT (mmyth_ui->main_hbox), "event",
    80                       G_CALLBACK (button_press_handler),
    81                       G_OBJECT (mmyth_ui->main_hbox));    
    82 
    83 #else // #ifdef MAEMO
    84 
    85     mmyth_ui->main_menu = GTK_MENU(gtk_menu_new());
    86     hildon_program_set_common_menu(program, mmyth_ui->main_menu);
    87 
    88     mmyth_ui->menu_setup = gtk_menu_item_new_with_label("Setup");
    89     gtk_widget_set_size_request (GTK_WIDGET (mmyth_ui->menu_setup), 150, 40);
    90     gtk_menu_append(mmyth_ui->main_menu, mmyth_ui->menu_setup);
    91 
    92     g_signal_connect(G_OBJECT(mmyth_ui->menu_setup), "activate", G_CALLBACK(cb_menu_item_settings), mmyth_ui);
    93 
    94     gtk_widget_show_all (GTK_WIDGET (mmyth_ui->main_menu));
    95 #endif
    96     
    97     // Main widget is mmyth_ui->main_hbox
    98     mmyth_ui->main_uicommon       = create_main_view (mmyth_ui);
    99 
   100     gtk_container_add (GTK_CONTAINER (mmyth_ui->main_window),
   101                        mmyth_ui->main_hbox);
   102 
   103     mmyth_ui_set_widget (mmyth_ui, mmyth_ui->main_uicommon);
   104 
   105     return mmyth_ui;
   106 }
   107 
   108 void
   109 mmyth_ui_finalize (MMythUi * mmyth_ui)
   110 {
   111     if (mmyth_ui != NULL) {
   112     	if (mmyth_ui->main_uicommon)
   113 	    	mmyth_uicommon_free (mmyth_ui->main_uicommon);
   114     	if (mmyth_ui->video_uicommon)
   115 		    mmyth_uicommon_free (mmyth_ui->video_uicommon);
   116 		if (mmyth_ui->epg_grid_uicommon)
   117 		    mmyth_uicommon_free (mmyth_ui->epg_grid_uicommon);
   118 		if (mmyth_ui->record_uicommon)
   119 		    mmyth_uicommon_free (mmyth_ui->record_uicommon);	    
   120 		if (mmyth_ui->schedule_uicommon)
   121 		    mmyth_uicommon_free (mmyth_ui->schedule_uicommon);
   122 
   123 	    g_free (mmyth_ui);
   124     }
   125 }
   126 
   127 void
   128 mmyth_ui_set_widget (MMythUi * mmyth_ui, MMythUiCommon * new_uicommon)
   129 {
   130 	if (new_uicommon == NULL) {
   131 		g_warning ("MMythUI setting a NULL UI_Common as current display\n");
   132 		return;
   133 	}
   134 		
   135     if (mmyth_ui->current_uicommon) {
   136         if (mmyth_ui->current_uicommon == mmyth_ui->video_uicommon) {
   137             gtk_widget_hide (mmyth_ui->current_uicommon->main_widget);
   138             gtk_widget_hide (mmyth_ui->videow);
   139         }
   140         else {
   141             gtk_container_remove (GTK_CONTAINER (mmyth_ui->main_hbox),
   142                                   mmyth_ui->current_uicommon->main_widget);
   143         }
   144 
   145         gtk_container_remove (GTK_CONTAINER (mmyth_ui->main_hbox),
   146                               mmyth_ui->current_uicommon->event_box);
   147         gtk_container_remove (GTK_CONTAINER (mmyth_ui->main_hbox),
   148                               main_vseparator);        
   149 
   150     }
   151 
   152     if (new_uicommon->main_widget == mmyth_ui->video_alignment) {
   153         //gst_player_video_show (GST_PLAYER_VIDEO(mmyth_ui->videow));
   154         gtk_widget_show (mmyth_ui->video_alignment);
   155         gtk_widget_show (mmyth_ui->videow);
   156     }
   157     else {
   158         /* FIXME: Fst call is NULL when mmyth_player_init fails */
   159         if(mmyth_ui->video_alignment != NULL)
   160             gtk_widget_hide (mmyth_ui->video_alignment);
   161         /* FIXME: Fst call is NULL when mmyth_player_init fails */
   162         if(mmyth_ui->videow != NULL)
   163             gtk_widget_hide (mmyth_ui->videow);
   164 
   165         gtk_box_pack_start (GTK_BOX (mmyth_ui->main_hbox),
   166                             new_uicommon->main_widget, TRUE, TRUE, 0);
   167     }
   168 
   169     if(main_vseparator == NULL) {
   170         /* FIXME: should free this variable*/
   171         main_vseparator = gtk_vseparator_new();
   172         g_object_ref (main_vseparator);                   
   173     }  
   174     gtk_box_pack_start (GTK_BOX (mmyth_ui->main_hbox),
   175                         main_vseparator, FALSE, FALSE, 0);    
   176     gtk_widget_show (main_vseparator);
   177 
   178     gtk_box_pack_end (GTK_BOX (mmyth_ui->main_hbox), new_uicommon->event_box, FALSE,
   179                       FALSE, 0);         
   180 
   181     mmyth_ui->current_uicommon = new_uicommon;
   182 
   183 }
   184 
   185 /* The close callback is the same for all windows*/
   186 static void
   187 cb_not_impl_button (GtkButton * button, gpointer user_data)
   188 {
   189     MMythUi *mmyth_ui = (MMythUi *) user_data;
   190 
   191     GtkWidget *msg_dialog = gtk_message_dialog_new (
   192                                            GTK_WINDOW(mmyth_ui->main_window),
   193                                            GTK_DIALOG_MODAL |
   194                                            GTK_DIALOG_DESTROY_WITH_PARENT,
   195                                            GTK_MESSAGE_INFO,
   196                                            GTK_BUTTONS_OK,
   197                                            "Feature not implemented");
   198     gtk_widget_set_size_request (msg_dialog, 350, 120);
   199 
   200     gtk_dialog_run (GTK_DIALOG (msg_dialog));
   201 
   202     gtk_widget_destroy(GTK_WIDGET(msg_dialog)); 
   203 }
   204 
   205 /******************************************************************************
   206  *                        POPUP MENU WIDGET METHODS                           *
   207  *****************************************************************************/
   208 
   209 static void 
   210 cb_menu_item_settings (GtkMenuItem *menuitem,
   211                             gpointer user_data)
   212 {
   213     
   214     MMythUi *mmyth_ui = (MMythUi*) user_data;
   215    
   216     if (mmyth_uisettings_run (GTK_WINDOW (mmyth_ui->main_window))) {
   217     	// If user changes the settings, we restart the context
   218     	g_debug ("[%s] Restarting mmyth_context to new settings", __FUNCTION__);
   219     	//gmyth_context_initialize();
   220     }
   221 }
   222 
   223 #ifndef MAEMO_PLATFORM
   224 
   225 static void 
   226 detacher (GtkWidget *attach_widget,GtkMenu *menu) 
   227 {
   228 	
   229 }
   230 
   231 static void
   232 do_popup_menu (GtkWidget *my_widget, GdkEventButton *event)
   233 {
   234     GtkWidget *popup;
   235 
   236   int button, event_time;
   237 
   238   GtkWidget *item_general;
   239   GtkWidget *image;
   240 
   241   popup = gtk_menu_new ();
   242 
   243   item_general = gtk_image_menu_item_new_with_mnemonic ("Setup");
   244   gtk_widget_show (item_general);
   245   gtk_container_add (GTK_CONTAINER (popup), item_general);
   246 
   247   image = gtk_image_new_from_stock ("gtk-edit", GTK_ICON_SIZE_MENU);
   248   gtk_widget_show (image);
   249   gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item_general), image);
   250 
   251   g_signal_connect (G_OBJECT(item_general), "activate", G_CALLBACK (cb_menu_item_settings), popup_mmyth_ui);
   252 
   253     if (event) {
   254       button = event->button;
   255       event_time = event->time;
   256     } else {
   257       button = 0;
   258       event_time = gtk_get_current_event_time ();
   259     }
   260     
   261     gtk_menu_attach_to_widget (GTK_MENU (popup), my_widget, detacher);
   262     gtk_menu_popup (GTK_MENU (popup), NULL, NULL, NULL, NULL, 
   263                   button, event_time);
   264     gtk_widget_show_all(popup);
   265 }
   266 
   267 /* Respond to a button-press by posting a menu passed in as widget.
   268  *
   269  * Note that the "widget" argument is the menu being posted, NOT
   270  * the button that was pressed.
   271  */
   272 static gint 
   273 button_press_handler (GtkWidget *widget, GdkEvent *event)
   274 {
   275 
   276     if (event->type == GDK_BUTTON_PRESS) {
   277       GdkEventButton *bevent = (GdkEventButton *) event; 
   278           /* Ignore double-clicks and triple-clicks */
   279       if (bevent->button == 3)
   280         {
   281           do_popup_menu (widget, bevent);
   282           return TRUE;
   283         }
   284     }
   285 
   286     /* Tell calling code that we have not handled this event; pass it on. */
   287     return FALSE;
   288 }
   289 #endif
   290 
   291 /******************************************************************************
   292  *                          MAIN APP VIEW METHODS                             *
   293  *****************************************************************************/
   294 
   295 static void
   296 cb_close_button (GtkButton * button, gpointer user_data)
   297 {
   298     MMythUi *mmyth_ui = (MMythUi *) user_data;
   299 
   300     mmyth_ui_set_widget (mmyth_ui, mmyth_ui->main_uicommon);
   301 }
   302 
   303 static void
   304 cb_watch_tv_button (GtkButton * button, gpointer user_data)
   305 {
   306     MMythUi *mmyth_ui = (MMythUi *) user_data;
   307 	gboolean res = FALSE;
   308 	
   309 	if (!(mmyth_ui->video_uicommon))
   310 		mmyth_ui->video_uicommon = create_video_view (mmyth_ui);
   311 	
   312 	// Creates the tv player that will retrieve the mythtv content, decode and show it
   313 	mmyth_ui->tvplayer = mmyth_tvplayer_new ();
   314 	/* choose here if this is a LiveTV session */
   315 	mmyth_ui->tvplayer->is_livetv = TRUE;
   316 
   317 	res = mmyth_tvplayer_initialize (mmyth_ui->tvplayer, mmyth_ui->backend_info);
   318 
   319 	if (!res) {
   320 		g_warning ("[%s] Could not initialize tvplayer", __FUNCTION__);
   321 
   322 		g_object_unref (mmyth_ui->tvplayer);
   323 		mmyth_ui->tvplayer = NULL;
   324 
   325 		GtkWidget *dialog = gtk_message_dialog_new (
   326 				GTK_WINDOW(mmyth_ui->main_window),
   327 				GTK_DIALOG_DESTROY_WITH_PARENT,
   328                 GTK_MESSAGE_ERROR,
   329                 GTK_BUTTONS_CLOSE,
   330 			 	"MMyth found errors while starting TV Player, please check "
   331 			 	"the GStreamer installation");
   332 
   333 		gtk_dialog_run (GTK_DIALOG (dialog));
   334 		gtk_widget_destroy (dialog);
   335 		
   336 		return;
   337 	}
   338 	//res = mmyth_tvplayer_livetv_setup (mmyth_ui->tvplayer);
   339 	//
   340 	if (mmyth_ui && mmyth_ui->tvplayer && res) {
   341 		mmyth_tvplayer_set_widget (mmyth_ui->tvplayer, mmyth_ui->videow);
   342 		mmyth_tvplayer_start_playing (mmyth_ui->tvplayer);
   343 	} else {
   344 		// TODO: Show Alert with error description!
   345 		g_warning ("[%s] MMythUI can't initialize tv_player", __FUNCTION__);
   346 		g_object_unref (mmyth_ui->tvplayer);
   347 		mmyth_ui->tvplayer = NULL;
   348 		// FIXME: Show the exact error that happened
   349 		GtkWidget *dialog = gtk_message_dialog_new (
   350 				GTK_WINDOW(mmyth_ui->main_window),
   351 				GTK_DIALOG_DESTROY_WITH_PARENT,
   352                 GTK_MESSAGE_ERROR,
   353                 GTK_BUTTONS_CLOSE,
   354                 "Error while starting TV Player, please check if the backend"
   355                 " is running properly and a tv card is available!");
   356 		gtk_dialog_run (GTK_DIALOG (dialog));
   357 		gtk_widget_destroy (dialog);		
   358 		return;
   359 	}
   360 	mmyth_ui_set_widget (mmyth_ui, mmyth_ui->video_uicommon);
   361 	
   362 }
   363 
   364 static void 
   365 cb_epg_button (GtkButton * button, gpointer user_data)
   366 {
   367     MMythUi *mmyth_ui = (MMythUi *) user_data;
   368     
   369     if (!(mmyth_ui->epg_grid_uicommon))
   370     	mmyth_ui->epg_grid_uicommon = create_epg_grid_view(mmyth_ui);
   371     	
   372     mmyth_ui_set_widget (mmyth_ui, mmyth_ui->epg_grid_uicommon);
   373 }
   374 
   375 static MMythUiCommon *
   376 create_main_view (MMythUi * mmyth_ui)
   377 {
   378     MMythUiCommon *ui_common;
   379     GtkWidget *main_widget;
   380     GtkWidget *image;
   381 
   382 	g_debug ("Creating Main UI Common");
   383 	
   384     // FIXME: file path
   385 #ifdef MMYTH_DEV
   386     image = gtk_image_new_from_file ("../pixmaps/mmyth_logo.png");
   387 #else
   388     image = gtk_image_new_from_file ( PIX_DIR "mmyth_logo.png");
   389 #endif
   390     
   391     main_widget = gtk_event_box_new();
   392     
   393     gtk_container_add (GTK_CONTAINER (main_widget),
   394                        image);
   395 
   396 
   397     gtk_widget_show_all (main_widget);
   398     g_object_ref (main_widget);
   399 
   400     ui_common = mmyth_uicommon_new (main_widget,
   401                                     "Watch TV", "EPG", "Recording");
   402 
   403     /* Button signals */
   404     // FIXME
   405     g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
   406                       G_CALLBACK (cb_watch_tv_button), mmyth_ui);
   407     g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
   408                       G_CALLBACK (cb_epg_button), mmyth_ui);
   409     g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
   410                       G_CALLBACK (cb_record_button), mmyth_ui);
   411 
   412     return ui_common;
   413 
   414 }
   415 
   416 /******************************************************************************
   417  *                         epg GRID VIEW METHODS                              *
   418  *****************************************************************************/
   419 
   420 static MMythUiCommon *
   421 create_epg_grid_view (MMythUi * mmyth_ui)
   422 {
   423     MMythUiCommon *ui_common;        
   424 
   425 	g_debug ("Creating EPG Grid UI Common");
   426 	
   427     GtkWidget *epg_grid_view = GTK_WIDGET (epg_grid_view_new (mmyth_ui));
   428     
   429     ui_common = mmyth_uicommon_new (epg_grid_view,
   430                                     "Play", "Record",
   431                                     "Close");    
   432     
   433     /* Button signals */
   434     g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
   435                       G_CALLBACK (cb_not_impl_button), mmyth_ui);
   436     g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
   437                       G_CALLBACK (cb_record_button), mmyth_ui);
   438     g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
   439                       G_CALLBACK (cb_close_button), mmyth_ui);
   440     
   441     return ui_common;
   442 }
   443 /******************************************************************************
   444  *                         SCHEDULE VIEW METHODS                                *
   445  ******************************************************************************/
   446 
   447 static void
   448 cb_save_new_schedule (GtkButton *button, gpointer user_data)
   449 {
   450     MMythUi *mmyth_ui = (MMythUi *) user_data;
   451 
   452 	if (!(mmyth_ui->schedule_uicommon))
   453 		mmyth_ui->schedule_uicommon = create_schedule_view(mmyth_ui);
   454 		
   455     mmyth_schedulerui_save (mmyth_ui->mmyth_schedulerui);
   456     
   457     mmyth_recordui_reload_schedule (mmyth_ui->mmyth_recordui);
   458     
   459     mmyth_ui_set_widget (mmyth_ui, mmyth_ui->record_uicommon);
   460     
   461 }
   462 
   463 static void
   464 cb_edit_scheduled (GtkTreeView * tree_view, GtkTreePath *path, 
   465 		           GtkTreeViewColumn *column, gpointer user_data)
   466 {
   467     MMythUi *mmyth_ui = (MMythUi *) user_data;
   468     GtkTreeSelection *selection;
   469 	GtkTreeModel *list_store;
   470 	GtkTreeIter iter;
   471 	int index;
   472     //gint new_row = 0, record_id = 0;
   473 	ScheduleInfo *schedule_info;
   474 	GList *schedule_list;
   475 	//GtkTreeIter iter;
   476 	gint res;
   477 
   478 	//gtk_tree_store_clear(recordui->sch_tree_store);	
   479 
   480 	res = gmyth_scheduler_get_schedule_list(mmyth_ui->mmyth_recordui->scheduler, &(schedule_list));
   481 	if (res < 0) {
   482 		g_warning ("[%s] Retrieved NULL list of scheduled data from database", __FUNCTION__);
   483 		//return FALSE;
   484 	}
   485 	printf("\nX %d", res); fflush(stdout);
   486     
   487    	selection = 
   488         gtk_tree_view_get_selection(GTK_TREE_VIEW(mmyth_ui->mmyth_recordui->sch_treeview));
   489     
   490     gtk_tree_selection_get_selected(selection, &list_store, &iter);
   491 	gtk_tree_model_get(list_store, &iter, 4, &index, -1);
   492     
   493     mmyth_ui_set_widget (mmyth_ui, mmyth_ui->schedule_uicommon);
   494     
   495 	if (!(mmyth_ui->schedule_uicommon))
   496 		mmyth_ui->schedule_uicommon = create_schedule_view(mmyth_ui);
   497 		
   498 	schedule_list = g_list_nth(schedule_list, g_ascii_strtoull( gtk_tree_path_to_string(path), NULL, 10 ));
   499 	schedule_info = (ScheduleInfo*) schedule_list->data;
   500 
   501     printf("\nstarttime: %ld", schedule_info->start_time->tv_sec); fflush(stdout);
   502 }
   503 
   504 static MMythUiCommon *
   505 create_schedule_view (MMythUi * mmyth_ui)
   506 {
   507     MMythUiCommon *ui_common;        
   508     GtkWidget *schedule_widget;
   509     
   510     g_debug ("Creating Schedule UI Common");
   511 
   512 	mmyth_ui->mmyth_schedulerui = mmyth_schedulerui_new ( mmyth_ui->backend_info );
   513 	if (mmyth_ui->mmyth_schedulerui == NULL) {
   514 		g_warning ("[%s] Error while creating scheduler ui", __FUNCTION__);
   515 		return NULL;
   516 	}
   517 	
   518 	schedule_widget = mmyth_ui->mmyth_schedulerui->main_widget;
   519 
   520     gtk_widget_show_all (schedule_widget);
   521     g_object_ref (schedule_widget);
   522     
   523     ui_common = mmyth_uicommon_new (schedule_widget,
   524                                     "Save", "Clear",
   525                                     "Cancel");    
   526 
   527     /* Button signals */
   528     g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
   529                       G_CALLBACK (cb_save_new_schedule), mmyth_ui);
   530     g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
   531                       G_CALLBACK (cb_not_impl_button), mmyth_ui);
   532     g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
   533                       G_CALLBACK (cb_record_button), mmyth_ui);
   534     
   535     return ui_common;
   536 }
   537 /******************************************************************************
   538  *                         RECORD VIEW METHODS                                *
   539  ******************************************************************************/
   540 static void
   541 cb_record_button (GtkButton * button, gpointer user_data)
   542 {
   543     MMythUi *mmyth_ui = (MMythUi *) user_data;
   544 
   545 	if (!(mmyth_ui->record_uicommon)) {
   546 		mmyth_ui->record_uicommon = create_record_view (mmyth_ui);
   547 		mmyth_ui->schedule_uicommon = create_schedule_view (mmyth_ui);
   548 	}
   549 	
   550 	mmyth_recordui_reload_all (mmyth_ui->mmyth_recordui);
   551 	
   552     mmyth_ui_set_widget (mmyth_ui, mmyth_ui->record_uicommon);
   553 
   554 } 
   555 
   556 static void
   557 cb_record_close_button (GtkButton * button, gpointer user_data)
   558 {
   559     MMythUi *mmyth_ui = (MMythUi *) user_data;
   560 
   561 	mmyth_ui_set_widget(mmyth_ui, mmyth_ui->main_uicommon);
   562 
   563 	mmyth_recordui_free(mmyth_ui->mmyth_recordui);
   564 	
   565 	if (mmyth_ui->record_uicommon) {
   566 		gtk_widget_destroy (mmyth_ui->record_uicommon->main_widget);
   567 		mmyth_uicommon_free(mmyth_ui->record_uicommon);
   568 		mmyth_ui->record_uicommon = NULL;
   569 	}
   570 
   571 	if (mmyth_ui->schedule_uicommon) {
   572 	//	mmyth_uicommon_free(mmyth_ui->schedule_uicommon);
   573 	}	
   574 } 
   575 
   576 
   577 
   578 
   579 static void
   580 play_selected_recorded (gpointer user_data)
   581 {
   582     MMythUi *mmyth_ui = (MMythUi *) user_data;
   583     gboolean res = FALSE;
   584 
   585     gchar *path = mmyth_recordui_get_selected_recorded (mmyth_ui->mmyth_recordui);
   586     
   587     if (path == NULL) {
   588     	// This should never happens. Play button is just activated when
   589     	// a recording is selected.
   590     	g_warning ("[%s] Play button pressed while none recorded is selected", __FUNCTION__);
   591     	return;
   592     }
   593 
   594 	if (!(mmyth_ui->video_uicommon))
   595 		mmyth_ui->video_uicommon = create_video_view (mmyth_ui);
   596 	
   597 	// Creates the tv player that will retrieve the mythtv content, decode and show it
   598 	mmyth_ui->tvplayer = mmyth_tvplayer_new ();
   599 	g_debug ("[%s] New TV Player created: %d\n", __FUNCTION__, (int) (mmyth_ui->tvplayer));
   600 	res = mmyth_tvplayer_initialize (mmyth_ui->tvplayer, mmyth_ui->backend_info);
   601 	if (!res) {
   602 		g_warning ("[%s] Could not initialize tvplayer", __FUNCTION__);
   603 
   604 		g_object_unref (mmyth_ui->tvplayer);
   605 		mmyth_ui->tvplayer = NULL;
   606 
   607 		GtkWidget *dialog = gtk_message_dialog_new (
   608 				GTK_WINDOW(mmyth_ui->main_window),
   609 				GTK_DIALOG_DESTROY_WITH_PARENT,
   610                 GTK_MESSAGE_ERROR,
   611                 GTK_BUTTONS_CLOSE,
   612 			 	"MMyth found errors while starting TV Player, please check "
   613 			 	"the GStreamer installation");
   614 
   615 		gtk_dialog_run (GTK_DIALOG (dialog));
   616 		gtk_widget_destroy (dialog);
   617 		
   618 		return;
   619 	}		
   620 
   621 	res = mmyth_tvplayer_record_setup (mmyth_ui->tvplayer, path);
   622 	
   623 	if (mmyth_ui && mmyth_ui->tvplayer && res) {
   624 		mmyth_tvplayer_set_widget (mmyth_ui->tvplayer, mmyth_ui->videow);
   625 		mmyth_tvplayer_start_playing (mmyth_ui->tvplayer);
   626 	} else {
   627 		// TODO: Show Alert with error description!
   628 		g_warning ("[%s] MMythUI can't initialize tv_player", __FUNCTION__);
   629 		g_object_unref (mmyth_ui->tvplayer);
   630 		mmyth_ui->tvplayer = NULL;
   631 		// FIXME: Show the exact error that happened
   632 		GtkWidget *dialog = gtk_message_dialog_new (
   633 				GTK_WINDOW(mmyth_ui->main_window),
   634 				GTK_DIALOG_DESTROY_WITH_PARENT,
   635                 GTK_MESSAGE_ERROR,
   636                 GTK_BUTTONS_CLOSE,
   637                 "Error while starting TV Player, please check if the backend"
   638                 " is running properly and a tv card is available!");
   639 		gtk_dialog_run (GTK_DIALOG (dialog));
   640 		gtk_widget_destroy (dialog);		
   641 		return;
   642 	}
   643 	
   644 	mmyth_ui_set_widget (mmyth_ui, mmyth_ui->video_uicommon);    
   645 }
   646 
   647 static void
   648 cb_play_clicked_recorded (GtkTreeView * tree_view, GtkTreePath *path, 
   649 		GtkTreeViewColumn *column, gpointer user_data)
   650 {
   651 	play_selected_recorded (user_data);
   652 }
   653 
   654 static void
   655 cb_play_selected (GtkButton * button, gpointer user_data)
   656 {
   657 	play_selected_recorded (user_data);
   658 }
   659 
   660 static void
   661 cb_schedule_button (GtkButton * button, gpointer user_data)
   662 {
   663     MMythUi *mmyth_ui = (MMythUi *) user_data;
   664 
   665     mmyth_ui_set_widget (mmyth_ui, mmyth_ui->schedule_uicommon);
   666 }
   667 
   668 void
   669 cb_switch_page (GtkNotebook *notebook, GtkNotebookPage *page,
   670 		guint page_num, gpointer user_data)
   671 {
   672     MMythUi *mmyth_ui = (MMythUi *) user_data;
   673     MMythUiCommon *ui_common; 
   674     
   675 	assert (mmyth_ui);
   676 	assert (mmyth_ui->record_uicommon);
   677 	
   678     ui_common = mmyth_ui->record_uicommon;
   679     
   680     if (page_num == 0) { // Switched to Schedule list
   681     	gtk_button_set_label (GTK_BUTTON (ui_common->button1), "New");
   682 		g_signal_handlers_disconnect_by_func (
   683 			G_OBJECT (ui_common->button1), G_CALLBACK (cb_play_selected), mmyth_ui);
   684 	    g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
   685             G_CALLBACK (cb_schedule_button), mmyth_ui);
   686     } else if (page_num == 1) {
   687     	gtk_button_set_label (GTK_BUTTON (ui_common->button1), "Play");
   688 		g_signal_handlers_disconnect_by_func (
   689 			G_OBJECT (ui_common->button1), G_CALLBACK (cb_schedule_button), mmyth_ui);
   690 	    g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
   691             G_CALLBACK (cb_play_selected), mmyth_ui);
   692     }
   693 }
   694                                             
   695                                             
   696 static MMythUiCommon *
   697 create_record_view (MMythUi * mmyth_ui)
   698 {
   699     MMythUiCommon *ui_common;        
   700     
   701    	g_debug ("Creating Record UI Common");
   702    	
   703 	mmyth_ui->mmyth_recordui = mmyth_recordui_new ( mmyth_ui->backend_info );
   704 
   705 	// FIXME: Change MMythRecordUI to a GtkWidget child and avoid this call!
   706     gtk_widget_show_all (mmyth_ui->mmyth_recordui->scrolled_window);
   707     
   708     ui_common = mmyth_uicommon_new (mmyth_ui->mmyth_recordui->scrolled_window, "New", "Delete", "<<Back");    
   709     g_object_ref (mmyth_ui->mmyth_recordui->scrolled_window);
   710         
   711     /* Button signals */
   712     g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
   713                       G_CALLBACK (cb_schedule_button), mmyth_ui);
   714     g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
   715                       G_CALLBACK (mmyth_recordui_delete_selected), mmyth_ui->mmyth_recordui);
   716     g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
   717                       G_CALLBACK (cb_record_close_button), mmyth_ui);
   718     g_signal_connect (G_OBJECT (mmyth_ui->mmyth_recordui->notebook),
   719 		      "switch-page", G_CALLBACK (cb_switch_page), mmyth_ui);
   720     g_signal_connect (G_OBJECT (mmyth_ui->mmyth_recordui->rec_treeview),
   721 		      "row-activated", G_CALLBACK (cb_play_clicked_recorded), mmyth_ui);
   722     g_signal_connect (G_OBJECT (mmyth_ui->mmyth_recordui->sch_treeview),
   723 		      "row-activated", G_CALLBACK (cb_edit_scheduled), mmyth_ui);
   724     return ui_common;
   725 }
   726 
   727 
   728 /******************************************************************************
   729  *                         GST VIDEO WIDGET METHODS                           *
   730  *****************************************************************************/
   731 
   732 static void
   733 cb_video_close_button (GtkButton * button, gpointer user_data)
   734 {
   735     MMythUi *mmyth_ui = (MMythUi *) user_data;
   736 	
   737 	g_debug ("MMythUI video close button pressed");
   738 	
   739 	if (mmyth_ui && mmyth_ui->tvplayer) {
   740 	    mmyth_tvplayer_stop_playing (mmyth_ui->tvplayer);
   741 
   742 		g_object_unref (mmyth_ui->tvplayer);
   743 		mmyth_ui->tvplayer = NULL;	    
   744 	} else {
   745 		g_warning ("cb_video_close_button called with NULL pointer\n");
   746 	}
   747 	
   748     mmyth_ui_set_widget (mmyth_ui, mmyth_ui->main_uicommon);
   749 }
   750 
   751 
   752 static MMythUiCommon *
   753 create_video_view (MMythUi * mmyth_ui)
   754 {
   755 
   756     MMythUiCommon *ui_common;
   757 
   758 	g_debug ("Creating Video UI Common");
   759 	
   760 	/* Creates widget to be user by MMythTVPlayer to draw the video */
   761     mmyth_ui->videow = gtk_drawing_area_new ();
   762     // FIXME: Get the widget size from settings
   763     gtk_widget_set_size_request (mmyth_ui->videow, 300, 240);
   764 
   765     //mmiptv_ui->logo = gdk_pixbuf_new_from_file ("logo.png", NULL);
   766 
   767 	// Creates an alignment to place the video widget inside
   768     mmyth_ui->video_alignment = gtk_alignment_new (0.5, 0.5, 1, 1);
   769     gtk_widget_hide (mmyth_ui->video_alignment);
   770 
   771     gtk_container_add (GTK_CONTAINER (mmyth_ui->video_alignment),
   772                        mmyth_ui->videow);
   773 
   774     /* Add the gst video widget to hbox. It should never be removed. */    
   775     /* FIXME: mmyth_ui->video_alignment == NULL when mmyth_player_init fails */
   776     if((mmyth_ui->main_hbox != NULL) && (mmyth_ui->video_alignment != NULL)) {
   777         gtk_box_pack_start (GTK_BOX (mmyth_ui->main_hbox),
   778                             mmyth_ui->video_alignment, TRUE, TRUE, 0);    
   779 	} else {
   780 		g_warning ("[%s] Error while adding video_alignment to main widget", __FUNCTION__);	
   781     }
   782 
   783     g_object_ref (mmyth_ui->videow);
   784     g_object_ref (mmyth_ui->video_alignment);
   785 
   786     ui_common = mmyth_uicommon_new (mmyth_ui->video_alignment,
   787                                     "  Full\nScreen", "Other\nServices",
   788                                     "Close");
   789                                     
   790     
   791     g_signal_connect (G_OBJECT (ui_common->button1), "clicked",
   792                       G_CALLBACK (cb_not_impl_button), mmyth_ui);
   793     g_signal_connect (G_OBJECT (ui_common->button2), "clicked",
   794                       G_CALLBACK (cb_not_impl_button), mmyth_ui);    
   795     g_signal_connect (G_OBJECT (ui_common->button3), "clicked",
   796                       G_CALLBACK (cb_video_close_button), mmyth_ui);
   797 
   798 	if (ui_common)
   799 		g_debug ("Video UI_Common sucessfull created");
   800 		
   801     return ui_common;
   802 }
   803 
   804 
   805 
   806 GtkWidget*
   807 mmyth_ui_get_video_widget (MMythUi *mmyth_ui) {
   808 	
   809 	if (mmyth_ui && mmyth_ui->videow) {
   810 	
   811 		return mmyth_ui->videow;
   812 	}
   813 	
   814 	return NULL;	
   815 }