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