renatofilho@20: 
renatofilho@20: #include <glib-object.h>
renatofilho@20: #include <sys/types.h>
renatofilho@20: #include <sys/stat.h>
renatofilho@20: #include <unistd.h>
renatofilho@20: #include <string.h>
renatofilho@20: #include <stdio.h>
renatofilho@20: #include <gtk/gtk.h>
renatofilho@20: #include <gdk/gdkx.h>
renatofilho@20: #include <gst/interfaces/xoverlay.h>
renatofilho@20: #include <assert.h>
renatofilho@20: 
renatofilho@20: #include "mmyth_ui.h"
renatofilho@20: #include "mmyth_uicommon.h"
renatofilho@20: #include "mmyth_schedulerui.h"
renatofilho@20: #include "mmyth_recordui.h"
renatofilho@20: #include "mmyth_uisettings.h"
renatofilho@20: #include "mmyth_epg_grid_view.h"
renatofilho@20: #include "mmyth_tvplayer.h"
renatofilho@20: 
renatofilho@754: /*
renatofilho@754:  * GMyth library includes 
renatofilho@754:  */
renatofilho@20: 
renatofilho@20: #ifndef MAEMO_PLATFORM
renatofilho@754: static gint     button_press_handler(GtkWidget * widget, GdkEvent * event);
renatofilho@20: #endif
renatofilho@20: 
renatofilho@754: static MMythUiCommon *create_main_view(MMythUi * mmyth_ui);
renatofilho@754: static MMythUiCommon *create_video_view(MMythUi * mmyth_ui);
renatofilho@754: static MMythUiCommon *create_epg_grid_view(MMythUi * mmyth_ui);
renatofilho@754: static MMythUiCommon *create_record_view(MMythUi * mmyth_ui);
renatofilho@754: static MMythUiCommon *create_schedule_view(MMythUi * mmyth_ui);
renatofilho@20: 
renatofilho@754: static void     cb_video_close_button(GtkButton * button,
renatofilho@754:                                       gpointer user_data);
renatofilho@754: static void     cb_record_button(GtkButton * button, gpointer user_data);
renatofilho@754: static void     cb_menu_item_settings(GtkMenuItem * menuitem,
renatofilho@754:                                       gpointer user_data);
renatofilho@20: 
renatofilho@754: /*
renatofilho@754:  * main box from button box separator
renatofilho@754:  */
renatofilho@20: static GtkWidget *main_vseparator = NULL;
renatofilho@20: 
renatofilho@754: GdkPixbuf      *icon_sports,
renatofilho@754:                *icon_news,
renatofilho@754:                *icon_movies,
renatofilho@754:                *icon_shows,
renatofilho@754:                *icon_default;
renatofilho@20: 
renatofilho@20: #ifndef MAEMO_PLATFORM
renatofilho@754: /*
renatofilho@754:  * FIXME: 
renatofilho@754:  */
renatofilho@20: static MMythUi *popup_mmyth_ui;
renatofilho@20: #endif
renatofilho@20: 
renatofilho@754: MMythUi        *
renatofilho@754: mmyth_ui_initialize(
renatofilho@20: #ifdef MAEMO_PLATFORM
renatofilho@754:                        HildonProgram * program,
renatofilho@20: #endif
renatofilho@754:                        GtkWidget * main_window)
renatofilho@20: {
renatofilho@754:     MMythUi        *mmyth_ui;
renatofilho@20: 
renatofilho@754:     mmyth_ui = g_new0(MMythUi, 1);
renatofilho@20: 
renatofilho@754:     mmyth_ui->backend_info =
renatofilho@754:         gmyth_backend_info_new_full("localhost", "mythtv", "mythtv",
renatofilho@754:                                     "mythconverg", 6543);
rosfran@208: 
renatofilho@754:     mmyth_ui->main_window = main_window;
renatofilho@20:     mmyth_ui->videow = NULL;
renatofilho@20:     mmyth_ui->mmyth_recordui = NULL;
renatofilho@20:     mmyth_ui->mmyth_schedulerui = NULL;
renatofilho@20: 
renatofilho@754:     /*
renatofilho@754:      * Horizontal box that divides the view into control and video area 
renatofilho@754:      */
renatofilho@754:     mmyth_ui->main_hbox = gtk_hbox_new(FALSE, 0);
renatofilho@754:     gtk_widget_show(mmyth_ui->main_hbox);
renatofilho@754:     g_object_ref(mmyth_ui->main_hbox);
renatofilho@754: 
renatofilho@754:     main_bg_color.red = 65000;
renatofilho@20:     main_bg_color.green = 65000;
renatofilho@754:     main_bg_color.blue = 65000;
renatofilho@754: 
renatofilho@754: 
renatofilho@20: #ifndef MAEMO_PLATFORM
renatofilho@754:     /*
renatofilho@754:      * Popup menu 
renatofilho@754:      */
renatofilho@20:     popup_mmyth_ui = mmyth_ui;
renatofilho@754:     g_signal_connect(G_OBJECT(mmyth_ui->main_hbox), "event",
renatofilho@754:                      G_CALLBACK(button_press_handler),
renatofilho@754:                      G_OBJECT(mmyth_ui->main_hbox));
renatofilho@20: 
renatofilho@754: #else                           // #ifdef MAEMO
renatofilho@20: 
renatofilho@20:     mmyth_ui->main_menu = GTK_MENU(gtk_menu_new());
renatofilho@20:     hildon_program_set_common_menu(program, mmyth_ui->main_menu);
renatofilho@20: 
renatofilho@20:     mmyth_ui->menu_setup = gtk_menu_item_new_with_label("Setup");
renatofilho@754:     gtk_widget_set_size_request(GTK_WIDGET(mmyth_ui->menu_setup), 150, 40);
renatofilho@20:     gtk_menu_append(mmyth_ui->main_menu, mmyth_ui->menu_setup);
renatofilho@20: 
renatofilho@754:     g_signal_connect(G_OBJECT(mmyth_ui->menu_setup), "activate",
renatofilho@754:                      G_CALLBACK(cb_menu_item_settings), mmyth_ui);
renatofilho@20: 
renatofilho@754:     gtk_widget_show_all(GTK_WIDGET(mmyth_ui->main_menu));
renatofilho@20: #endif
renatofilho@754: 
renatofilho@20:     // Main widget is mmyth_ui->main_hbox
renatofilho@754:     mmyth_ui->main_uicommon = create_main_view(mmyth_ui);
renatofilho@20: 
renatofilho@754:     gtk_container_add(GTK_CONTAINER(mmyth_ui->main_window),
renatofilho@754:                       mmyth_ui->main_hbox);
renatofilho@20: 
renatofilho@754:     mmyth_ui_set_widget(mmyth_ui, mmyth_ui->main_uicommon);
renatofilho@20: 
renatofilho@20:     return mmyth_ui;
renatofilho@20: }
renatofilho@20: 
renatofilho@20: void
renatofilho@754: mmyth_ui_finalize(MMythUi * mmyth_ui)
renatofilho@20: {
renatofilho@20:     if (mmyth_ui != NULL) {
renatofilho@754:         if (mmyth_ui->main_uicommon)
renatofilho@754:             mmyth_uicommon_free(mmyth_ui->main_uicommon);
renatofilho@754:         if (mmyth_ui->video_uicommon)
renatofilho@754:             mmyth_uicommon_free(mmyth_ui->video_uicommon);
renatofilho@754:         if (mmyth_ui->epg_grid_uicommon)
renatofilho@754:             mmyth_uicommon_free(mmyth_ui->epg_grid_uicommon);
renatofilho@754:         if (mmyth_ui->record_uicommon)
renatofilho@754:             mmyth_uicommon_free(mmyth_ui->record_uicommon);
renatofilho@754:         if (mmyth_ui->schedule_uicommon)
renatofilho@754:             mmyth_uicommon_free(mmyth_ui->schedule_uicommon);
renatofilho@20: 
renatofilho@754:         g_free(mmyth_ui);
renatofilho@20:     }
renatofilho@20: }
renatofilho@20: 
renatofilho@20: void
renatofilho@754: mmyth_ui_set_widget(MMythUi * mmyth_ui, MMythUiCommon * new_uicommon)
renatofilho@20: {
renatofilho@754:     if (new_uicommon == NULL) {
renatofilho@754:         g_warning("MMythUI setting a NULL UI_Common as current display\n");
renatofilho@754:         return;
renatofilho@754:     }
renatofilho@754: 
renatofilho@20:     if (mmyth_ui->current_uicommon) {
renatofilho@20:         if (mmyth_ui->current_uicommon == mmyth_ui->video_uicommon) {
renatofilho@754:             gtk_widget_hide(mmyth_ui->current_uicommon->main_widget);
renatofilho@754:             gtk_widget_hide(mmyth_ui->videow);
renatofilho@754:         } else {
renatofilho@754:             gtk_container_remove(GTK_CONTAINER(mmyth_ui->main_hbox),
renatofilho@754:                                  mmyth_ui->current_uicommon->main_widget);
renatofilho@20:         }
renatofilho@20: 
renatofilho@754:         gtk_container_remove(GTK_CONTAINER(mmyth_ui->main_hbox),
renatofilho@754:                              mmyth_ui->current_uicommon->event_box);
renatofilho@754:         gtk_container_remove(GTK_CONTAINER(mmyth_ui->main_hbox),
renatofilho@754:                              main_vseparator);
renatofilho@20: 
renatofilho@20:     }
renatofilho@20: 
renatofilho@20:     if (new_uicommon->main_widget == mmyth_ui->video_alignment) {
renatofilho@754:         // gst_player_video_show (GST_PLAYER_VIDEO(mmyth_ui->videow));
renatofilho@754:         gtk_widget_show(mmyth_ui->video_alignment);
renatofilho@754:         gtk_widget_show(mmyth_ui->videow);
renatofilho@754:     } else {
renatofilho@754:         /*
renatofilho@754:          * FIXME: Fst call is NULL when mmyth_player_init fails 
renatofilho@754:          */
renatofilho@754:         if (mmyth_ui->video_alignment != NULL)
renatofilho@754:             gtk_widget_hide(mmyth_ui->video_alignment);
renatofilho@754:         /*
renatofilho@754:          * FIXME: Fst call is NULL when mmyth_player_init fails 
renatofilho@754:          */
renatofilho@754:         if (mmyth_ui->videow != NULL)
renatofilho@754:             gtk_widget_hide(mmyth_ui->videow);
renatofilho@20: 
renatofilho@754:         gtk_box_pack_start(GTK_BOX(mmyth_ui->main_hbox),
renatofilho@754:                            new_uicommon->main_widget, TRUE, TRUE, 0);
renatofilho@20:     }
renatofilho@20: 
renatofilho@754:     if (main_vseparator == NULL) {
renatofilho@754:         /*
renatofilho@754:          * FIXME: should free this variable
renatofilho@754:          */
renatofilho@20:         main_vseparator = gtk_vseparator_new();
renatofilho@754:         g_object_ref(main_vseparator);
renatofilho@754:     }
renatofilho@754:     gtk_box_pack_start(GTK_BOX(mmyth_ui->main_hbox),
renatofilho@754:                        main_vseparator, FALSE, FALSE, 0);
renatofilho@754:     gtk_widget_show(main_vseparator);
renatofilho@20: 
renatofilho@754:     gtk_box_pack_end(GTK_BOX(mmyth_ui->main_hbox), new_uicommon->event_box,
renatofilho@754:                      FALSE, FALSE, 0);
renatofilho@20: 
renatofilho@20:     mmyth_ui->current_uicommon = new_uicommon;
renatofilho@20: 
renatofilho@20: }
renatofilho@20: 
renatofilho@754: /*
renatofilho@754:  * The close callback is the same for all windows
renatofilho@754:  */
renatofilho@20: static void
renatofilho@754: cb_not_impl_button(GtkButton * button, gpointer user_data)
renatofilho@20: {
renatofilho@754:     MMythUi        *mmyth_ui = (MMythUi *) user_data;
renatofilho@20: 
renatofilho@754:     GtkWidget      *msg_dialog =
renatofilho@754:         gtk_message_dialog_new(GTK_WINDOW(mmyth_ui->main_window),
renatofilho@754:                                GTK_DIALOG_MODAL |
renatofilho@754:                                GTK_DIALOG_DESTROY_WITH_PARENT,
renatofilho@754:                                GTK_MESSAGE_INFO,
renatofilho@754:                                GTK_BUTTONS_OK,
renatofilho@754:                                "Feature not implemented");
renatofilho@754:     gtk_widget_set_size_request(msg_dialog, 350, 120);
renatofilho@20: 
renatofilho@754:     gtk_dialog_run(GTK_DIALOG(msg_dialog));
renatofilho@20: 
renatofilho@754:     gtk_widget_destroy(GTK_WIDGET(msg_dialog));
renatofilho@20: }
renatofilho@20: 
renatofilho@20: /******************************************************************************
renatofilho@20:  *                        POPUP MENU WIDGET METHODS                           *
renatofilho@20:  *****************************************************************************/
renatofilho@20: 
renatofilho@754: static void
renatofilho@754: cb_menu_item_settings(GtkMenuItem * menuitem, gpointer user_data)
renatofilho@20: {
renatofilho@754: 
renatofilho@754:     MMythUi        *mmyth_ui = (MMythUi *) user_data;
renatofilho@754: 
renatofilho@754:     if (mmyth_uisettings_run(GTK_WINDOW(mmyth_ui->main_window))) {
renatofilho@754:         // If user changes the settings, we restart the context
renatofilho@754:         g_debug("[%s] Restarting mmyth_context to new settings",
renatofilho@754:                 __FUNCTION__);
renatofilho@754:         // gmyth_context_initialize();
renatofilho@20:     }
renatofilho@20: }
renatofilho@20: 
renatofilho@20: #ifndef MAEMO_PLATFORM
renatofilho@20: 
renatofilho@754: static void
renatofilho@754: detacher(GtkWidget * attach_widget, GtkMenu * menu)
renatofilho@20: {
renatofilho@754: 
renatofilho@20: }
renatofilho@20: 
renatofilho@20: static void
renatofilho@754: do_popup_menu(GtkWidget * my_widget, GdkEventButton * event)
renatofilho@20: {
renatofilho@754:     GtkWidget      *popup;
renatofilho@20: 
renatofilho@754:     int             button,
renatofilho@754:                     event_time;
renatofilho@20: 
renatofilho@754:     GtkWidget      *item_general;
renatofilho@754:     GtkWidget      *image;
renatofilho@20: 
renatofilho@754:     popup = gtk_menu_new();
renatofilho@20: 
renatofilho@754:     item_general = gtk_image_menu_item_new_with_mnemonic("Setup");
renatofilho@754:     gtk_widget_show(item_general);
renatofilho@754:     gtk_container_add(GTK_CONTAINER(popup), item_general);
renatofilho@20: 
renatofilho@754:     image = gtk_image_new_from_stock("gtk-edit", GTK_ICON_SIZE_MENU);
renatofilho@754:     gtk_widget_show(image);
renatofilho@754:     gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item_general),
renatofilho@754:                                   image);
renatofilho@20: 
renatofilho@754:     g_signal_connect(G_OBJECT(item_general), "activate",
renatofilho@754:                      G_CALLBACK(cb_menu_item_settings), popup_mmyth_ui);
renatofilho@20: 
renatofilho@20:     if (event) {
renatofilho@754:         button = event->button;
renatofilho@754:         event_time = event->time;
renatofilho@20:     } else {
renatofilho@754:         button = 0;
renatofilho@754:         event_time = gtk_get_current_event_time();
renatofilho@20:     }
renatofilho@754: 
renatofilho@754:     gtk_menu_attach_to_widget(GTK_MENU(popup), my_widget, detacher);
renatofilho@754:     gtk_menu_popup(GTK_MENU(popup), NULL, NULL, NULL, NULL,
renatofilho@754:                    button, event_time);
renatofilho@20:     gtk_widget_show_all(popup);
renatofilho@20: }
renatofilho@20: 
renatofilho@754: /*
renatofilho@754:  * Respond to a button-press by posting a menu passed in as widget. Note
renatofilho@754:  * that the "widget" argument is the menu being posted, NOT the button
renatofilho@754:  * that was pressed. 
renatofilho@20:  */
renatofilho@754: static          gint
renatofilho@754: button_press_handler(GtkWidget * widget, GdkEvent * event)
renatofilho@20: {
renatofilho@20: 
renatofilho@20:     if (event->type == GDK_BUTTON_PRESS) {
renatofilho@754:         GdkEventButton *bevent = (GdkEventButton *) event;
renatofilho@754:         /*
renatofilho@754:          * Ignore double-clicks and triple-clicks 
renatofilho@754:          */
renatofilho@754:         if (bevent->button == 3) {
renatofilho@754:             do_popup_menu(widget, bevent);
renatofilho@754:             return TRUE;
renatofilho@20:         }
renatofilho@20:     }
renatofilho@20: 
renatofilho@754:     /*
renatofilho@754:      * Tell calling code that we have not handled this event; pass it on. 
renatofilho@754:      */
renatofilho@20:     return FALSE;
renatofilho@20: }
renatofilho@20: #endif
renatofilho@20: 
renatofilho@20: /******************************************************************************
renatofilho@20:  *                          MAIN APP VIEW METHODS                             *
renatofilho@20:  *****************************************************************************/
renatofilho@20: 
renatofilho@20: static void
renatofilho@754: cb_close_button(GtkButton * button, gpointer user_data)
renatofilho@20: {
renatofilho@754:     MMythUi        *mmyth_ui = (MMythUi *) user_data;
renatofilho@20: 
renatofilho@754:     mmyth_ui_set_widget(mmyth_ui, mmyth_ui->main_uicommon);
renatofilho@20: }
renatofilho@20: 
renatofilho@20: static void
renatofilho@754: cb_watch_tv_button(GtkButton * button, gpointer user_data)
renatofilho@20: {
renatofilho@754:     MMythUi        *mmyth_ui = (MMythUi *) user_data;
renatofilho@754:     gboolean        res = FALSE;
renatofilho@20: 
renatofilho@754:     if (!(mmyth_ui->video_uicommon))
renatofilho@754:         mmyth_ui->video_uicommon = create_video_view(mmyth_ui);
renatofilho@20: 
renatofilho@754:     // Creates the tv player that will retrieve the mythtv content, decode 
renatofilho@754:     // and show it
renatofilho@754:     mmyth_ui->tvplayer = mmyth_tvplayer_new();
renatofilho@754:     /*
renatofilho@754:      * choose here if this is a LiveTV session 
renatofilho@754:      */
renatofilho@754:     mmyth_ui->tvplayer->is_livetv = TRUE;
renatofilho@20: 
renatofilho@754:     res =
renatofilho@754:         mmyth_tvplayer_initialize(mmyth_ui->tvplayer,
renatofilho@754:                                   mmyth_ui->backend_info);
renatofilho@20: 
renatofilho@754:     if (!res) {
renatofilho@754:         g_warning("[%s] Could not initialize tvplayer", __FUNCTION__);
renatofilho@20: 
renatofilho@754:         g_object_unref(mmyth_ui->tvplayer);
renatofilho@754:         mmyth_ui->tvplayer = NULL;
renatofilho@754: 
renatofilho@754:         GtkWidget      *dialog =
renatofilho@754:             gtk_message_dialog_new(GTK_WINDOW(mmyth_ui->main_window),
renatofilho@754:                                    GTK_DIALOG_DESTROY_WITH_PARENT,
renatofilho@754:                                    GTK_MESSAGE_ERROR,
renatofilho@754:                                    GTK_BUTTONS_CLOSE,
renatofilho@754:                                    "MMyth found errors while starting TV Player, please check "
renatofilho@754:                                    "the GStreamer installation");
renatofilho@754: 
renatofilho@754:         gtk_dialog_run(GTK_DIALOG(dialog));
renatofilho@754:         gtk_widget_destroy(dialog);
renatofilho@754: 
renatofilho@754:         return;
renatofilho@754:     }
renatofilho@754:     // res = mmyth_tvplayer_livetv_setup (mmyth_ui->tvplayer);
renatofilho@754:     // 
renatofilho@754:     if (mmyth_ui && mmyth_ui->tvplayer && res) {
renatofilho@754:         mmyth_tvplayer_set_widget(mmyth_ui->tvplayer, mmyth_ui->videow);
renatofilho@754:         mmyth_tvplayer_start_playing(mmyth_ui->tvplayer);
renatofilho@754:     } else {
renatofilho@754:         // TODO: Show Alert with error description!
renatofilho@754:         g_warning("[%s] MMythUI can't initialize tv_player", __FUNCTION__);
renatofilho@754:         g_object_unref(mmyth_ui->tvplayer);
renatofilho@754:         mmyth_ui->tvplayer = NULL;
renatofilho@754:         // FIXME: Show the exact error that happened
renatofilho@754:         GtkWidget      *dialog =
renatofilho@754:             gtk_message_dialog_new(GTK_WINDOW(mmyth_ui->main_window),
renatofilho@754:                                    GTK_DIALOG_DESTROY_WITH_PARENT,
renatofilho@754:                                    GTK_MESSAGE_ERROR,
renatofilho@754:                                    GTK_BUTTONS_CLOSE,
renatofilho@754:                                    "Error while starting TV Player, please check if the backend"
renatofilho@754:                                    " is running properly and a tv card is available!");
renatofilho@754:         gtk_dialog_run(GTK_DIALOG(dialog));
renatofilho@754:         gtk_widget_destroy(dialog);
renatofilho@754:         return;
renatofilho@754:     }
renatofilho@754:     mmyth_ui_set_widget(mmyth_ui, mmyth_ui->video_uicommon);
renatofilho@754: 
renatofilho@20: }
renatofilho@20: 
renatofilho@754: static void
renatofilho@754: cb_epg_button(GtkButton * button, gpointer user_data)
renatofilho@20: {
renatofilho@754:     MMythUi        *mmyth_ui = (MMythUi *) user_data;
renatofilho@754: 
renatofilho@20:     if (!(mmyth_ui->epg_grid_uicommon))
renatofilho@754:         mmyth_ui->epg_grid_uicommon = create_epg_grid_view(mmyth_ui);
renatofilho@754: 
renatofilho@754:     mmyth_ui_set_widget(mmyth_ui, mmyth_ui->epg_grid_uicommon);
renatofilho@20: }
renatofilho@20: 
renatofilho@20: static MMythUiCommon *
renatofilho@754: create_main_view(MMythUi * mmyth_ui)
renatofilho@20: {
renatofilho@754:     MMythUiCommon  *ui_common;
renatofilho@754:     GtkWidget      *main_widget;
renatofilho@754:     GtkWidget      *image;
renatofilho@20: 
renatofilho@754:     g_debug("Creating Main UI Common");
renatofilho@754: 
renatofilho@20:     // FIXME: file path
renatofilho@20: #ifdef MMYTH_DEV
renatofilho@754:     image = gtk_image_new_from_file("../pixmaps/mmyth_logo.png");
renatofilho@20: #else
renatofilho@754:     image = gtk_image_new_from_file(PIX_DIR "mmyth_logo.png");
renatofilho@20: #endif
renatofilho@754: 
renatofilho@20:     main_widget = gtk_event_box_new();
renatofilho@20: 
renatofilho@754:     gtk_container_add(GTK_CONTAINER(main_widget), image);
renatofilho@20: 
renatofilho@20: 
renatofilho@754:     gtk_widget_show_all(main_widget);
renatofilho@754:     g_object_ref(main_widget);
renatofilho@20: 
renatofilho@754:     ui_common = mmyth_uicommon_new(main_widget,
renatofilho@754:                                    "Watch TV", "EPG", "Recording");
renatofilho@754: 
renatofilho@754:     /*
renatofilho@754:      * Button signals 
renatofilho@754:      */
renatofilho@20:     // FIXME
renatofilho@754:     g_signal_connect(G_OBJECT(ui_common->button1), "clicked",
renatofilho@754:                      G_CALLBACK(cb_watch_tv_button), mmyth_ui);
renatofilho@754:     g_signal_connect(G_OBJECT(ui_common->button2), "clicked",
renatofilho@754:                      G_CALLBACK(cb_epg_button), mmyth_ui);
renatofilho@754:     g_signal_connect(G_OBJECT(ui_common->button3), "clicked",
renatofilho@754:                      G_CALLBACK(cb_record_button), mmyth_ui);
renatofilho@20: 
renatofilho@20:     return ui_common;
renatofilho@20: 
renatofilho@20: }
renatofilho@20: 
renatofilho@20: /******************************************************************************
renatofilho@20:  *                         epg GRID VIEW METHODS                              *
renatofilho@20:  *****************************************************************************/
renatofilho@20: 
renatofilho@20: static MMythUiCommon *
renatofilho@754: create_epg_grid_view(MMythUi * mmyth_ui)
renatofilho@20: {
renatofilho@754:     MMythUiCommon  *ui_common;
renatofilho@20: 
renatofilho@754:     g_debug("Creating EPG Grid UI Common");
renatofilho@754: 
renatofilho@754:     GtkWidget      *epg_grid_view =
renatofilho@754:         GTK_WIDGET(epg_grid_view_new(mmyth_ui));
renatofilho@754: 
renatofilho@754:     ui_common = mmyth_uicommon_new(epg_grid_view,
renatofilho@754:                                    "Play", "Record", "Close");
renatofilho@754: 
renatofilho@754:     /*
renatofilho@754:      * Button signals 
renatofilho@754:      */
renatofilho@754:     g_signal_connect(G_OBJECT(ui_common->button1), "clicked",
renatofilho@754:                      G_CALLBACK(cb_not_impl_button), mmyth_ui);
renatofilho@754:     g_signal_connect(G_OBJECT(ui_common->button2), "clicked",
renatofilho@754:                      G_CALLBACK(cb_record_button), mmyth_ui);
renatofilho@754:     g_signal_connect(G_OBJECT(ui_common->button3), "clicked",
renatofilho@754:                      G_CALLBACK(cb_close_button), mmyth_ui);
renatofilho@754: 
renatofilho@20:     return ui_common;
renatofilho@20: }
renatofilho@20: /******************************************************************************
renatofilho@20:  *                         SCHEDULE VIEW METHODS                                *
renatofilho@20:  ******************************************************************************/
renatofilho@20: 
renatofilho@20: static void
renatofilho@754: cb_save_new_schedule(GtkButton * button, gpointer user_data)
renatofilho@20: {
renatofilho@754:     MMythUi        *mmyth_ui = (MMythUi *) user_data;
renatofilho@20: 
renatofilho@754:     if (!(mmyth_ui->schedule_uicommon))
renatofilho@754:         mmyth_ui->schedule_uicommon = create_schedule_view(mmyth_ui);
renatofilho@754: 
renatofilho@754:     mmyth_schedulerui_save(mmyth_ui->mmyth_schedulerui);
renatofilho@754: 
renatofilho@754:     mmyth_recordui_reload_schedule(mmyth_ui->mmyth_recordui);
renatofilho@754: 
renatofilho@754:     mmyth_ui_set_widget(mmyth_ui, mmyth_ui->record_uicommon);
renatofilho@754: 
renatofilho@20: }
renatofilho@20: 
renatofilho@20: static void
renatofilho@754: cb_edit_scheduled(GtkTreeView * tree_view, GtkTreePath * path,
renatofilho@754:                   GtkTreeViewColumn * column, gpointer user_data)
renatofilho@20: {
renatofilho@754:     MMythUi        *mmyth_ui = (MMythUi *) user_data;
renatofilho@20:     GtkTreeSelection *selection;
renatofilho@754:     GtkTreeModel   *list_store;
renatofilho@754:     GtkTreeIter     iter;
renatofilho@754:     int             index;
renatofilho@754:     // gint new_row = 0, record_id = 0;
renatofilho@754:     ScheduleInfo   *schedule_info;
renatofilho@754:     GList          *schedule_list;
renatofilho@754:     // GtkTreeIter iter;
renatofilho@754:     gint            res;
renatofilho@20: 
renatofilho@754:     // gtk_tree_store_clear(recordui->sch_tree_store); 
renatofilho@20: 
renatofilho@754:     res =
renatofilho@754:         gmyth_scheduler_get_schedule_list(mmyth_ui->mmyth_recordui->
renatofilho@754:                                           scheduler, &(schedule_list));
renatofilho@754:     if (res < 0) {
renatofilho@754:         g_warning
renatofilho@754:             ("[%s] Retrieved NULL list of scheduled data from database",
renatofilho@754:              __FUNCTION__);
renatofilho@754:         // return FALSE;
renatofilho@754:     }
renatofilho@754:     printf("\nX %d", res);
renatofilho@754:     fflush(stdout);
renatofilho@754: 
renatofilho@754:     selection =
renatofilho@754:         gtk_tree_view_get_selection(GTK_TREE_VIEW
renatofilho@754:                                     (mmyth_ui->mmyth_recordui->
renatofilho@754:                                      sch_treeview));
renatofilho@754: 
renatofilho@20:     gtk_tree_selection_get_selected(selection, &list_store, &iter);
renatofilho@754:     gtk_tree_model_get(list_store, &iter, 4, &index, -1);
renatofilho@20: 
renatofilho@754:     mmyth_ui_set_widget(mmyth_ui, mmyth_ui->schedule_uicommon);
renatofilho@754: 
renatofilho@754:     if (!(mmyth_ui->schedule_uicommon))
renatofilho@754:         mmyth_ui->schedule_uicommon = create_schedule_view(mmyth_ui);
renatofilho@754: 
renatofilho@754:     schedule_list =
renatofilho@754:         g_list_nth(schedule_list,
renatofilho@754:                    g_ascii_strtoull(gtk_tree_path_to_string(path), NULL,
renatofilho@754:                                     10));
renatofilho@754:     schedule_info = (ScheduleInfo *) schedule_list->data;
renatofilho@754: 
renatofilho@754:     printf("\nstarttime: %ld", schedule_info->start_time->tv_sec);
renatofilho@754:     fflush(stdout);
renatofilho@20: }
renatofilho@20: 
renatofilho@20: static MMythUiCommon *
renatofilho@754: create_schedule_view(MMythUi * mmyth_ui)
renatofilho@20: {
renatofilho@754:     MMythUiCommon  *ui_common;
renatofilho@754:     GtkWidget      *schedule_widget;
renatofilho@20: 
renatofilho@754:     g_debug("Creating Schedule UI Common");
renatofilho@20: 
renatofilho@754:     mmyth_ui->mmyth_schedulerui =
renatofilho@754:         mmyth_schedulerui_new(mmyth_ui->backend_info);
renatofilho@754:     if (mmyth_ui->mmyth_schedulerui == NULL) {
renatofilho@754:         g_warning("[%s] Error while creating scheduler ui", __FUNCTION__);
renatofilho@754:         return NULL;
renatofilho@754:     }
renatofilho@20: 
renatofilho@754:     schedule_widget = mmyth_ui->mmyth_schedulerui->main_widget;
renatofilho@754: 
renatofilho@754:     gtk_widget_show_all(schedule_widget);
renatofilho@754:     g_object_ref(schedule_widget);
renatofilho@754: 
renatofilho@754:     ui_common = mmyth_uicommon_new(schedule_widget,
renatofilho@754:                                    "Save", "Clear", "Cancel");
renatofilho@754: 
renatofilho@754:     /*
renatofilho@754:      * Button signals 
renatofilho@754:      */
renatofilho@754:     g_signal_connect(G_OBJECT(ui_common->button1), "clicked",
renatofilho@754:                      G_CALLBACK(cb_save_new_schedule), mmyth_ui);
renatofilho@754:     g_signal_connect(G_OBJECT(ui_common->button2), "clicked",
renatofilho@754:                      G_CALLBACK(cb_not_impl_button), mmyth_ui);
renatofilho@754:     g_signal_connect(G_OBJECT(ui_common->button3), "clicked",
renatofilho@754:                      G_CALLBACK(cb_record_button), mmyth_ui);
renatofilho@754: 
renatofilho@20:     return ui_common;
renatofilho@20: }
renatofilho@20: /******************************************************************************
renatofilho@20:  *                         RECORD VIEW METHODS                                *
renatofilho@20:  ******************************************************************************/
renatofilho@20: static void
renatofilho@754: cb_record_button(GtkButton * button, gpointer user_data)
renatofilho@20: {
renatofilho@754:     MMythUi        *mmyth_ui = (MMythUi *) user_data;
renatofilho@20: 
renatofilho@754:     if (!(mmyth_ui->record_uicommon)) {
renatofilho@754:         mmyth_ui->record_uicommon = create_record_view(mmyth_ui);
renatofilho@754:         mmyth_ui->schedule_uicommon = create_schedule_view(mmyth_ui);
renatofilho@20:     }
renatofilho@20: 
renatofilho@754:     mmyth_recordui_reload_all(mmyth_ui->mmyth_recordui);
renatofilho@20: 
renatofilho@754:     mmyth_ui_set_widget(mmyth_ui, mmyth_ui->record_uicommon);
renatofilho@20: 
renatofilho@20: }
renatofilho@20: 
renatofilho@20: static void
renatofilho@754: cb_record_close_button(GtkButton * button, gpointer user_data)
renatofilho@20: {
renatofilho@754:     MMythUi        *mmyth_ui = (MMythUi *) user_data;
renatofilho@754: 
renatofilho@754:     mmyth_ui_set_widget(mmyth_ui, mmyth_ui->main_uicommon);
renatofilho@754: 
renatofilho@754:     mmyth_recordui_free(mmyth_ui->mmyth_recordui);
renatofilho@754: 
renatofilho@754:     if (mmyth_ui->record_uicommon) {
renatofilho@754:         gtk_widget_destroy(mmyth_ui->record_uicommon->main_widget);
renatofilho@754:         mmyth_uicommon_free(mmyth_ui->record_uicommon);
renatofilho@754:         mmyth_ui->record_uicommon = NULL;
renatofilho@754:     }
renatofilho@754: 
renatofilho@754:     if (mmyth_ui->schedule_uicommon) {
renatofilho@754:         // mmyth_uicommon_free(mmyth_ui->schedule_uicommon);
renatofilho@754:     }
renatofilho@754: }
renatofilho@754: 
renatofilho@754: 
renatofilho@754: 
renatofilho@754: 
renatofilho@754: static void
renatofilho@754: play_selected_recorded(gpointer user_data)
renatofilho@754: {
renatofilho@754:     MMythUi        *mmyth_ui = (MMythUi *) user_data;
renatofilho@754:     gboolean        res = FALSE;
renatofilho@754: 
renatofilho@754:     gchar          *path =
renatofilho@754:         mmyth_recordui_get_selected_recorded(mmyth_ui->mmyth_recordui);
renatofilho@754: 
renatofilho@754:     if (path == NULL) {
renatofilho@754:         // This should never happens. Play button is just activated when
renatofilho@754:         // a recording is selected.
renatofilho@754:         g_warning
renatofilho@754:             ("[%s] Play button pressed while none recorded is selected",
renatofilho@754:              __FUNCTION__);
renatofilho@754:         return;
renatofilho@754:     }
renatofilho@754: 
renatofilho@754:     if (!(mmyth_ui->video_uicommon))
renatofilho@754:         mmyth_ui->video_uicommon = create_video_view(mmyth_ui);
renatofilho@754: 
renatofilho@754:     // Creates the tv player that will retrieve the mythtv content, decode 
renatofilho@754:     // and show it
renatofilho@754:     mmyth_ui->tvplayer = mmyth_tvplayer_new();
renatofilho@754:     g_debug("[%s] New TV Player created: %d\n", __FUNCTION__,
renatofilho@754:             (int) (mmyth_ui->tvplayer));
renatofilho@754:     res =
renatofilho@754:         mmyth_tvplayer_initialize(mmyth_ui->tvplayer,
renatofilho@754:                                   mmyth_ui->backend_info);
renatofilho@754:     if (!res) {
renatofilho@754:         g_warning("[%s] Could not initialize tvplayer", __FUNCTION__);
renatofilho@754: 
renatofilho@754:         g_object_unref(mmyth_ui->tvplayer);
renatofilho@754:         mmyth_ui->tvplayer = NULL;
renatofilho@754: 
renatofilho@754:         GtkWidget      *dialog =
renatofilho@754:             gtk_message_dialog_new(GTK_WINDOW(mmyth_ui->main_window),
renatofilho@754:                                    GTK_DIALOG_DESTROY_WITH_PARENT,
renatofilho@754:                                    GTK_MESSAGE_ERROR,
renatofilho@754:                                    GTK_BUTTONS_CLOSE,
renatofilho@754:                                    "MMyth found errors while starting TV Player, please check "
renatofilho@754:                                    "the GStreamer installation");
renatofilho@754: 
renatofilho@754:         gtk_dialog_run(GTK_DIALOG(dialog));
renatofilho@754:         gtk_widget_destroy(dialog);
renatofilho@754: 
renatofilho@754:         return;
renatofilho@754:     }
renatofilho@754: 
renatofilho@754:     res = mmyth_tvplayer_record_setup(mmyth_ui->tvplayer, path);
renatofilho@754: 
renatofilho@754:     if (mmyth_ui && mmyth_ui->tvplayer && res) {
renatofilho@754:         mmyth_tvplayer_set_widget(mmyth_ui->tvplayer, mmyth_ui->videow);
renatofilho@754:         mmyth_tvplayer_start_playing(mmyth_ui->tvplayer);
renatofilho@754:     } else {
renatofilho@754:         // TODO: Show Alert with error description!
renatofilho@754:         g_warning("[%s] MMythUI can't initialize tv_player", __FUNCTION__);
renatofilho@754:         g_object_unref(mmyth_ui->tvplayer);
renatofilho@754:         mmyth_ui->tvplayer = NULL;
renatofilho@754:         // FIXME: Show the exact error that happened
renatofilho@754:         GtkWidget      *dialog =
renatofilho@754:             gtk_message_dialog_new(GTK_WINDOW(mmyth_ui->main_window),
renatofilho@754:                                    GTK_DIALOG_DESTROY_WITH_PARENT,
renatofilho@754:                                    GTK_MESSAGE_ERROR,
renatofilho@754:                                    GTK_BUTTONS_CLOSE,
renatofilho@754:                                    "Error while starting TV Player, please check if the backend"
renatofilho@754:                                    " is running properly and a tv card is available!");
renatofilho@754:         gtk_dialog_run(GTK_DIALOG(dialog));
renatofilho@754:         gtk_widget_destroy(dialog);
renatofilho@754:         return;
renatofilho@754:     }
renatofilho@754: 
renatofilho@754:     mmyth_ui_set_widget(mmyth_ui, mmyth_ui->video_uicommon);
renatofilho@20: }
renatofilho@20: 
renatofilho@20: static void
renatofilho@754: cb_play_clicked_recorded(GtkTreeView * tree_view, GtkTreePath * path,
renatofilho@754:                          GtkTreeViewColumn * column, gpointer user_data)
renatofilho@20: {
renatofilho@754:     play_selected_recorded(user_data);
renatofilho@20: }
renatofilho@20: 
renatofilho@20: static void
renatofilho@754: cb_play_selected(GtkButton * button, gpointer user_data)
renatofilho@20: {
renatofilho@754:     play_selected_recorded(user_data);
renatofilho@754: }
renatofilho@20: 
renatofilho@754: static void
renatofilho@754: cb_schedule_button(GtkButton * button, gpointer user_data)
renatofilho@754: {
renatofilho@754:     MMythUi        *mmyth_ui = (MMythUi *) user_data;
renatofilho@754: 
renatofilho@754:     mmyth_ui_set_widget(mmyth_ui, mmyth_ui->schedule_uicommon);
renatofilho@20: }
renatofilho@20: 
renatofilho@20: void
renatofilho@754: cb_switch_page(GtkNotebook * notebook, GtkNotebookPage * page,
renatofilho@754:                guint page_num, gpointer user_data)
renatofilho@20: {
renatofilho@754:     MMythUi        *mmyth_ui = (MMythUi *) user_data;
renatofilho@754:     MMythUiCommon  *ui_common;
renatofilho@754: 
renatofilho@754:     assert(mmyth_ui);
renatofilho@754:     assert(mmyth_ui->record_uicommon);
renatofilho@754: 
renatofilho@20:     ui_common = mmyth_ui->record_uicommon;
renatofilho@754: 
renatofilho@754:     if (page_num == 0) {        // Switched to Schedule list
renatofilho@754:         gtk_button_set_label(GTK_BUTTON(ui_common->button1), "New");
renatofilho@754:         g_signal_handlers_disconnect_by_func(G_OBJECT(ui_common->button1),
renatofilho@754:                                              G_CALLBACK(cb_play_selected),
renatofilho@754:                                              mmyth_ui);
renatofilho@754:         g_signal_connect(G_OBJECT(ui_common->button1), "clicked",
renatofilho@754:                          G_CALLBACK(cb_schedule_button), mmyth_ui);
renatofilho@20:     } else if (page_num == 1) {
renatofilho@754:         gtk_button_set_label(GTK_BUTTON(ui_common->button1), "Play");
renatofilho@754:         g_signal_handlers_disconnect_by_func(G_OBJECT(ui_common->button1),
renatofilho@754:                                              G_CALLBACK
renatofilho@754:                                              (cb_schedule_button),
renatofilho@754:                                              mmyth_ui);
renatofilho@754:         g_signal_connect(G_OBJECT(ui_common->button1), "clicked",
renatofilho@754:                          G_CALLBACK(cb_play_selected), mmyth_ui);
renatofilho@20:     }
renatofilho@20: }
renatofilho@754: 
renatofilho@754: 
renatofilho@20: static MMythUiCommon *
renatofilho@754: create_record_view(MMythUi * mmyth_ui)
renatofilho@20: {
renatofilho@754:     MMythUiCommon  *ui_common;
renatofilho@20: 
renatofilho@754:     g_debug("Creating Record UI Common");
renatofilho@754: 
renatofilho@754:     mmyth_ui->mmyth_recordui = mmyth_recordui_new(mmyth_ui->backend_info);
renatofilho@754: 
renatofilho@754:     // FIXME: Change MMythRecordUI to a GtkWidget child and avoid this
renatofilho@754:     // call!
renatofilho@754:     gtk_widget_show_all(mmyth_ui->mmyth_recordui->scrolled_window);
renatofilho@754: 
renatofilho@754:     ui_common =
renatofilho@754:         mmyth_uicommon_new(mmyth_ui->mmyth_recordui->scrolled_window,
renatofilho@754:                            "New", "Delete", "<<Back");
renatofilho@754:     g_object_ref(mmyth_ui->mmyth_recordui->scrolled_window);
renatofilho@754: 
renatofilho@754:     /*
renatofilho@754:      * Button signals 
renatofilho@754:      */
renatofilho@754:     g_signal_connect(G_OBJECT(ui_common->button1), "clicked",
renatofilho@754:                      G_CALLBACK(cb_schedule_button), mmyth_ui);
renatofilho@754:     g_signal_connect(G_OBJECT(ui_common->button2), "clicked",
renatofilho@754:                      G_CALLBACK(mmyth_recordui_delete_selected),
renatofilho@754:                      mmyth_ui->mmyth_recordui);
renatofilho@754:     g_signal_connect(G_OBJECT(ui_common->button3), "clicked",
renatofilho@754:                      G_CALLBACK(cb_record_close_button), mmyth_ui);
renatofilho@754:     g_signal_connect(G_OBJECT(mmyth_ui->mmyth_recordui->notebook),
renatofilho@754:                      "switch-page", G_CALLBACK(cb_switch_page), mmyth_ui);
renatofilho@754:     g_signal_connect(G_OBJECT(mmyth_ui->mmyth_recordui->rec_treeview),
renatofilho@754:                      "row-activated", G_CALLBACK(cb_play_clicked_recorded),
renatofilho@754:                      mmyth_ui);
renatofilho@754:     g_signal_connect(G_OBJECT(mmyth_ui->mmyth_recordui->sch_treeview),
renatofilho@754:                      "row-activated", G_CALLBACK(cb_edit_scheduled),
renatofilho@754:                      mmyth_ui);
renatofilho@20:     return ui_common;
renatofilho@20: }
renatofilho@20: 
renatofilho@20: 
renatofilho@20: /******************************************************************************
renatofilho@20:  *                         GST VIDEO WIDGET METHODS                           *
renatofilho@20:  *****************************************************************************/
renatofilho@20: 
renatofilho@20: static void
renatofilho@754: cb_video_close_button(GtkButton * button, gpointer user_data)
renatofilho@20: {
renatofilho@754:     MMythUi        *mmyth_ui = (MMythUi *) user_data;
renatofilho@20: 
renatofilho@754:     g_debug("MMythUI video close button pressed");
renatofilho@754: 
renatofilho@754:     if (mmyth_ui && mmyth_ui->tvplayer) {
renatofilho@754:         mmyth_tvplayer_stop_playing(mmyth_ui->tvplayer);
renatofilho@754: 
renatofilho@754:         g_object_unref(mmyth_ui->tvplayer);
renatofilho@754:         mmyth_ui->tvplayer = NULL;
renatofilho@754:     } else {
renatofilho@754:         g_warning("cb_video_close_button called with NULL pointer\n");
renatofilho@754:     }
renatofilho@754: 
renatofilho@754:     mmyth_ui_set_widget(mmyth_ui, mmyth_ui->main_uicommon);
renatofilho@20: }
renatofilho@20: 
renatofilho@20: 
renatofilho@20: static MMythUiCommon *
renatofilho@754: create_video_view(MMythUi * mmyth_ui)
renatofilho@20: {
renatofilho@20: 
renatofilho@754:     MMythUiCommon  *ui_common;
renatofilho@20: 
renatofilho@754:     g_debug("Creating Video UI Common");
renatofilho@754: 
renatofilho@754:     /*
renatofilho@754:      * Creates widget to be user by MMythTVPlayer to draw the video 
renatofilho@754:      */
renatofilho@754:     mmyth_ui->videow = gtk_drawing_area_new();
renatofilho@20:     // FIXME: Get the widget size from settings
renatofilho@754:     gtk_widget_set_size_request(mmyth_ui->videow, 300, 240);
renatofilho@20: 
renatofilho@754:     // mmiptv_ui->logo = gdk_pixbuf_new_from_file ("logo.png", NULL);
renatofilho@20: 
renatofilho@754:     // Creates an alignment to place the video widget inside
renatofilho@754:     mmyth_ui->video_alignment = gtk_alignment_new(0.5, 0.5, 1, 1);
renatofilho@754:     gtk_widget_hide(mmyth_ui->video_alignment);
renatofilho@20: 
renatofilho@754:     gtk_container_add(GTK_CONTAINER(mmyth_ui->video_alignment),
renatofilho@754:                       mmyth_ui->videow);
renatofilho@20: 
renatofilho@754:     /*
renatofilho@754:      * Add the gst video widget to hbox. It should never be removed. 
renatofilho@754:      */
renatofilho@754:     /*
renatofilho@754:      * FIXME: mmyth_ui->video_alignment == NULL when mmyth_player_init
renatofilho@754:      * fails 
renatofilho@754:      */
renatofilho@754:     if ((mmyth_ui->main_hbox != NULL)
renatofilho@754:         && (mmyth_ui->video_alignment != NULL)) {
renatofilho@754:         gtk_box_pack_start(GTK_BOX(mmyth_ui->main_hbox),
renatofilho@754:                            mmyth_ui->video_alignment, TRUE, TRUE, 0);
renatofilho@754:     } else {
renatofilho@754:         g_warning("[%s] Error while adding video_alignment to main widget",
renatofilho@754:                   __FUNCTION__);
renatofilho@20:     }
renatofilho@20: 
renatofilho@754:     g_object_ref(mmyth_ui->videow);
renatofilho@754:     g_object_ref(mmyth_ui->video_alignment);
renatofilho@20: 
renatofilho@754:     ui_common = mmyth_uicommon_new(mmyth_ui->video_alignment,
renatofilho@754:                                    "  Full\nScreen", "Other\nServices",
renatofilho@754:                                    "Close");
renatofilho@20: 
renatofilho@754: 
renatofilho@754:     g_signal_connect(G_OBJECT(ui_common->button1), "clicked",
renatofilho@754:                      G_CALLBACK(cb_not_impl_button), mmyth_ui);
renatofilho@754:     g_signal_connect(G_OBJECT(ui_common->button2), "clicked",
renatofilho@754:                      G_CALLBACK(cb_not_impl_button), mmyth_ui);
renatofilho@754:     g_signal_connect(G_OBJECT(ui_common->button3), "clicked",
renatofilho@754:                      G_CALLBACK(cb_video_close_button), mmyth_ui);
renatofilho@754: 
renatofilho@754:     if (ui_common)
renatofilho@754:         g_debug("Video UI_Common sucessfull created");
renatofilho@754: 
renatofilho@20:     return ui_common;
renatofilho@20: }
renatofilho@20: 
renatofilho@20: 
renatofilho@20: 
renatofilho@754: GtkWidget      *
renatofilho@754: mmyth_ui_get_video_widget(MMythUi * mmyth_ui)
renatofilho@754: {
renatofilho@754: 
renatofilho@754:     if (mmyth_ui && mmyth_ui->videow) {
renatofilho@754: 
renatofilho@754:         return mmyth_ui->videow;
renatofilho@754:     }
renatofilho@754: 
renatofilho@754:     return NULL;
renatofilho@20: }