~ubuntu-branches/ubuntu/wily/me-tv/wily-proposed

« back to all changes in this revision

Viewing changes to src/application.cc

  • Committer: Bazaar Package Importer
  • Author(s): Michael Lamothe
  • Date: 2010-05-22 13:10:32 UTC
  • mfrom: (1.1.12 upstream) (3.1.11 sid)
  • Revision ID: james.westby@ubuntu.com-20100522131032-ibethpcgb8lpwt1w
Tags: 1.2.4-1
* New upstream release
* Maintainer change to Michael Lamothe
* Updated debian/control
  - Added libunique-dev to Build-Depends
  - Added libdbus-glib-1-dev to Build-Depends
* Added me-tv-player.1 to debian/me-tv.manpages

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
 
21
21
#include "application.h"
22
22
#include "data.h"
23
 
#include "devices_dialog.h"
24
23
#include "crc32.h"
 
24
#include <dbus/dbus-glib.h>
 
25
#include <dbus/dbus-glib-lowlevel.h>
25
26
 
26
27
#define GCONF_PATH                                      "/apps/me-tv"
27
 
#define CURRENT_DATABASE_VERSION        5
28
 
 
29
 
G_BEGIN_DECLS
30
 
void on_record(GtkObject *object, gpointer user_data)
31
 
{
32
 
        g_debug("Handler: %s", __PRETTY_FUNCTION__);
33
 
        get_application().on_record();
34
 
}
35
 
 
36
 
void on_quit()
37
 
{
38
 
        get_application().get_main_window().hide();
39
 
        Gtk::Main::quit();
40
 
}
41
 
 
42
 
void on_next_channel(GtkObject *object, gpointer user_data)
43
 
{
44
 
        g_debug("Handler: %s", __PRETTY_FUNCTION__);
45
 
        get_application().next_channel();
46
 
}
47
 
 
48
 
void on_previous_channel(GtkObject *object, gpointer user_data)
49
 
{
50
 
        g_debug("Handler: %s", __PRETTY_FUNCTION__);
51
 
        get_application().previous_channel();
52
 
}
53
 
 
54
 
void on_change_view_mode(GtkObject *object, gpointer user_data)
55
 
{
56
 
        g_debug("Handler: %s", __PRETTY_FUNCTION__);
57
 
        get_application().get_main_window().on_change_view_mode();
58
 
}
59
 
 
60
 
void on_devices(GtkObject *object, gpointer user_data)
61
 
{
62
 
        g_debug("Handler: %s", __PRETTY_FUNCTION__);
63
 
        get_application().get_main_window().on_devices();
64
 
}
65
 
 
66
 
void on_channels()
67
 
{
68
 
        g_debug("Handler: %s", __PRETTY_FUNCTION__);
69
 
        get_application().get_main_window().on_channels();
70
 
}
71
 
 
72
 
void on_scheduled_recordings()
73
 
{
74
 
        g_debug("Handler: %s", __PRETTY_FUNCTION__);
75
 
        get_application().get_main_window().on_scheduled_recordings();
76
 
}
77
 
 
78
 
void on_meters()
79
 
{
80
 
        g_debug("Handler: %s", __PRETTY_FUNCTION__);
81
 
        get_application().get_main_window().on_meters();
82
 
}
83
 
 
84
 
void on_preferences(GtkObject *object, gpointer user_data)
85
 
{
86
 
        g_debug("Handler: %s", __PRETTY_FUNCTION__);
87
 
        get_application().get_main_window().on_preferences();
88
 
}
89
 
 
90
 
void on_fullscreen()
91
 
{
92
 
        g_debug("Handler: %s", __PRETTY_FUNCTION__);
93
 
        get_application().get_main_window().on_fullscreen();
94
 
}
95
 
 
96
 
void on_mute()
97
 
{
98
 
        g_debug("Handler: %s", __PRETTY_FUNCTION__);
99
 
        get_application().get_main_window().on_mute();
100
 
}
101
 
 
102
 
void on_audio_channel_both()
103
 
{
104
 
        g_debug("Handler: %s", __PRETTY_FUNCTION__);
105
 
        get_application().get_main_window().on_audio_channel_both();
106
 
}
107
 
 
108
 
void on_audio_channel_left()
109
 
{
110
 
        g_debug("Handler: %s", __PRETTY_FUNCTION__);
111
 
        get_application().get_main_window().on_audio_channel_left();
112
 
}
113
 
 
114
 
void on_audio_channel_right()
115
 
{
116
 
        g_debug("Handler: %s", __PRETTY_FUNCTION__);
117
 
        get_application().get_main_window().on_audio_channel_right();
118
 
}
119
 
 
120
 
void on_about()
121
 
{
122
 
        g_debug("Handler: %s", __PRETTY_FUNCTION__);
123
 
        get_application().get_main_window().on_about();
124
 
}
125
 
G_END_DECLS
 
28
#define CURRENT_DATABASE_VERSION        6
126
29
 
127
30
Application* Application::current = NULL;
128
31
 
148
51
        timeout_source                  = 0;
149
52
        database_initialised    = false;
150
53
        
151
 
        // Remove all other handlers first
152
 
        get_signal_error().clear();
153
 
        get_signal_error().connect(sigc::mem_fun(*this, &Application::on_error));
154
 
 
155
54
#ifndef IGNORE_SQLITE3_THREADSAFE_CHECK
156
55
        g_debug("sqlite3_threadsafe() = %d", sqlite3_threadsafe());
157
56
        if (sqlite3_threadsafe() == 0)
162
61
 
163
62
        Crc32::init();
164
63
        
165
 
        client = Gnome::Conf::Client::get_default_client();
 
64
        gconf_client = Gnome::Conf::Client::get_default_client();
166
65
 
167
66
        if (get_int_configuration_value("epg_span_hours") == 0)
168
67
        {
186
85
        g_debug("Loading UI files");
187
86
        
188
87
        builder = Gtk::Builder::create_from_file(PACKAGE_DATA_DIR"/me-tv/glade/me-tv.ui");
189
 
        builder->add_from_file(PACKAGE_DATA_DIR"/me-tv/glade/me-tv-actions.ui");
190
 
        
 
88
        
 
89
        toggle_action_fullscreen = Glib::RefPtr<Gtk::ToggleAction>::cast_dynamic(builder->get_object("toggle_action_fullscreen"));
 
90
        toggle_action_mute = Glib::RefPtr<Gtk::ToggleAction>::cast_dynamic(builder->get_object("toggle_action_mute"));
 
91
        toggle_action_record = Glib::RefPtr<Gtk::ToggleAction>::cast_dynamic(builder->get_object("toggle_action_record"));
 
92
 
 
93
        action_about = Glib::RefPtr<Gtk::Action>::cast_dynamic(builder->get_object("action_about"));
 
94
        action_channels = Glib::RefPtr<Gtk::Action>::cast_dynamic(builder->get_object("action_channels"));
 
95
        action_change_view_mode = Glib::RefPtr<Gtk::Action>::cast_dynamic(builder->get_object("action_change_view_mode"));
 
96
        action_epg_event_search = Glib::RefPtr<Gtk::Action>::cast_dynamic(builder->get_object("action_epg_event_search"));
 
97
        action_next_channel = Glib::RefPtr<Gtk::Action>::cast_dynamic(builder->get_object("action_next_channel"));
 
98
        action_preferences = Glib::RefPtr<Gtk::Action>::cast_dynamic(builder->get_object("action_preferences"));
 
99
        action_previous_channel = Glib::RefPtr<Gtk::Action>::cast_dynamic(builder->get_object("action_previous_channel"));
 
100
        action_quit = Glib::RefPtr<Gtk::Action>::cast_dynamic(builder->get_object("action_quit"));
 
101
        action_scheduled_recordings = Glib::RefPtr<Gtk::Action>::cast_dynamic(builder->get_object("action_scheduled_recordings"));
 
102
 
 
103
        Glib::RefPtr<Gtk::ActionGroup> action_group = Gtk::ActionGroup::create();
 
104
        action_group->add(toggle_action_record, Gtk::AccelKey("R"));
 
105
        action_group->add(toggle_action_fullscreen, Gtk::AccelKey("F"));
 
106
        action_group->add(toggle_action_mute, Gtk::AccelKey("M"));
 
107
 
 
108
        action_group->add(action_about, Gtk::AccelKey("F1"));
 
109
        action_group->add(action_channels);
 
110
        action_group->add(action_change_view_mode, Gtk::AccelKey("V"));
 
111
        action_group->add(action_epg_event_search);
 
112
        action_group->add(action_next_channel, Gtk::AccelKey("<Ctrl>Down"));
 
113
        action_group->add(action_preferences);
 
114
        action_group->add(action_previous_channel, Gtk::AccelKey("<Ctrl>Up"));
 
115
        action_group->add(action_quit);
 
116
        action_group->add(action_scheduled_recordings);
 
117
 
 
118
        action_group->add(Gtk::Action::create("action_file", _("_File")));
 
119
        action_group->add(Gtk::Action::create("action_view", _("_View")));
 
120
        action_group->add(Gtk::Action::create("action_video", _("_Video")));
 
121
        action_group->add(Gtk::Action::create("action_audio", _("_Audio")));
 
122
        action_group->add(Gtk::Action::create("action_help", _("_Help")));
 
123
        
 
124
        action_group->add(Gtk::Action::create("action_subtitle_streams", _("Subtitles")));
 
125
        action_group->add(Gtk::Action::create("action_audio_streams", _("_Streams")));
 
126
        action_group->add(Gtk::Action::create("action_audio_channels", _("_Channels")));
 
127
 
 
128
        Gtk::RadioButtonGroup radio_button_group_audio_channel;
 
129
        action_group->add(Gtk::RadioAction::create(radio_button_group_audio_channel, "action_audio_channel_both", _("_Both")));
 
130
        action_group->add(Gtk::RadioAction::create(radio_button_group_audio_channel, "action_audio_channel_left", _("_Left")));
 
131
        action_group->add(Gtk::RadioAction::create(radio_button_group_audio_channel, "action_audio_channel_right", _("_Right")));
 
132
        
 
133
        action_quit->signal_activate().connect(sigc::ptr_fun(Gtk::Main::quit));
 
134
        toggle_action_record->signal_activate().connect(sigc::mem_fun(*this, &Application::on_record));
 
135
        action_next_channel->signal_activate().connect(sigc::mem_fun(*this, &Application::on_next_channel));
 
136
        action_previous_channel->signal_activate().connect(sigc::mem_fun(*this, &Application::on_previous_channel));
 
137
 
 
138
        ui_manager = Gtk::UIManager::create();
 
139
        ui_manager->insert_action_group(action_group);
 
140
 
191
141
        g_debug("Application constructed");
192
142
}
193
143
 
198
148
        {
199
149
                g_source_remove(timeout_source);
200
150
        }
 
151
        
 
152
        if (status_icon != NULL)
 
153
        {
 
154
                delete status_icon;
 
155
                status_icon = NULL;
 
156
        }
 
157
 
201
158
        if (main_window != NULL)
202
159
        {
203
160
                delete main_window;
213
170
        g_debug("Application destructor complete");
214
171
}
215
172
 
 
173
void Application::on_record()
 
174
{
 
175
        Glib::RecMutex::Lock lock(mutex);
 
176
 
 
177
        if (toggle_action_record->get_active())
 
178
        {
 
179
                try
 
180
                {
 
181
                        start_recording(stream_manager.get_display_channel());
 
182
                }
 
183
                catch (const Glib::Exception& exception)
 
184
                {
 
185
                        toggle_action_record->set_active(false);
 
186
                        throw Exception(exception.what());
 
187
                }
 
188
                catch (...)
 
189
                {
 
190
                        toggle_action_record->set_active(false);
 
191
                        throw Exception(_("Failed to start recording"));
 
192
                }
 
193
        }
 
194
        else
 
195
        {
 
196
                stream_manager.stop_recording(stream_manager.get_display_channel());                    
 
197
                g_debug("Recording stopped");
 
198
        }
 
199
 
 
200
        update();
 
201
}
 
202
 
 
203
void Application::on_previous_channel()
 
204
{
 
205
/*      Channel* channel = channel_manager.get_previous_channel();
 
206
        if (channel != NULL)
 
207
        {
 
208
                set_display_channel(*channel);
 
209
        }
 
210
*/
 
211
}
 
212
 
 
213
void Application::on_next_channel()
 
214
{
 
215
/*      Channel* channel = channel_manager.get_next_channel();
 
216
        if (channel != NULL)
 
217
        {
 
218
                set_display_channel(*channel);
 
219
        }*/
 
220
}
 
221
 
 
222
void Application::on_quit()
 
223
{
 
224
        get_application().get_main_window().hide();
 
225
        Gtk::Main::quit();
 
226
}
 
227
 
216
228
void Application::make_directory_with_parents(const Glib::ustring& path)
217
229
{
218
230
        Glib::RefPtr<Gio::File> file = Gio::File::create_for_path(path);
219
231
        if (!file->query_exists())
220
232
        {
221
233
                Glib::RefPtr<Gio::File> parent = file->get_parent();
222
 
                if (parent->query_exists())
223
 
                {
224
 
                        g_debug("Creating directory '%s'", path.c_str());
225
 
                        file->make_directory();
226
 
                }
227
 
                else
 
234
                if (!parent->query_exists())
228
235
                {
229
236
                        make_directory_with_parents(parent->get_path());
230
237
                }
 
238
 
 
239
                g_debug("Creating directory '%s'", path.c_str());
 
240
                file->make_directory();
231
241
        }
232
242
}
233
243
 
301
311
        table_scheduled_recording.name = "scheduled_recording";
302
312
        table_scheduled_recording.columns.add("scheduled_recording_id", Data::DATA_TYPE_INTEGER, 0, false);
303
313
        table_scheduled_recording.columns.add("description",                    Data::DATA_TYPE_STRING, 200, false);
304
 
        table_scheduled_recording.columns.add("type",                                   Data::DATA_TYPE_INTEGER, 0, false);
 
314
        table_scheduled_recording.columns.add("recurring_type",                 Data::DATA_TYPE_INTEGER, 0, false);
 
315
        table_scheduled_recording.columns.add("action_after",                   Data::DATA_TYPE_INTEGER, 0, false);
305
316
        table_scheduled_recording.columns.add("channel_id",                             Data::DATA_TYPE_INTEGER, 0, false);
306
317
        table_scheduled_recording.columns.add("start_time",                             Data::DATA_TYPE_INTEGER, 0, false);
307
318
        table_scheduled_recording.columns.add("duration",                               Data::DATA_TYPE_INTEGER, 0, false);
391
402
void Application::set_string_configuration_default(const Glib::ustring& key, const Glib::ustring& value)
392
403
{
393
404
        Glib::ustring path = get_configuration_path(key);
394
 
        Gnome::Conf::Value v = client->get(path);
 
405
        Gnome::Conf::Value v = gconf_client->get(path);
395
406
        if (v.get_type() == Gnome::Conf::VALUE_INVALID)
396
407
        {
397
408
                g_debug("Setting string configuration value '%s' = '%s'", key.c_str(), value.c_str());
398
 
                client->set(path, value);
 
409
                gconf_client->set(path, value);
399
410
        }
400
411
}
401
412
 
402
413
void Application::set_int_configuration_default(const Glib::ustring& key, gint value)
403
414
{
404
415
        Glib::ustring path = get_configuration_path(key);
405
 
        Gnome::Conf::Value v = client->get(path);
 
416
        Gnome::Conf::Value v = gconf_client->get(path);
406
417
        if (v.get_type() == Gnome::Conf::VALUE_INVALID)
407
418
        {
408
419
                g_debug("Setting int configuration value '%s' = '%d'", path.c_str(), value);
409
 
                client->set(path, value);
 
420
                gconf_client->set(path, value);
410
421
        }
411
422
}
412
423
 
413
424
void Application::set_boolean_configuration_default(const Glib::ustring& key, gboolean value)
414
425
{
415
426
        Glib::ustring path = get_configuration_path(key);
416
 
        Gnome::Conf::Value v = client->get(path);
 
427
        Gnome::Conf::Value v = gconf_client->get(path);
417
428
        if (v.get_type() == Gnome::Conf::VALUE_INVALID)
418
429
        {
419
430
                g_debug("Setting int configuration value '%s' = '%s'", path.c_str(), value ? "true" : "false");
420
 
                client->set(path, (bool)value);
 
431
                gconf_client->set(path, (bool)value);
421
432
        }
422
433
}
423
434
 
 
435
StringList Application::get_string_list_configuration_value(const Glib::ustring& key)
 
436
{
 
437
        return gconf_client->get_string_list(get_configuration_path(key));
 
438
}
 
439
 
424
440
Glib::ustring Application::get_string_configuration_value(const Glib::ustring& key)
425
441
{
426
 
        return client->get_string(get_configuration_path(key));
 
442
        return gconf_client->get_string(get_configuration_path(key));
427
443
}
428
444
 
429
445
gint Application::get_int_configuration_value(const Glib::ustring& key)
430
446
{
431
 
        return client->get_int(get_configuration_path(key));
 
447
        return gconf_client->get_int(get_configuration_path(key));
432
448
}
433
449
 
434
450
gint Application::get_boolean_configuration_value(const Glib::ustring& key)
435
451
{
436
 
        return client->get_bool(get_configuration_path(key));
 
452
        return gconf_client->get_bool(get_configuration_path(key));
 
453
}
 
454
 
 
455
void Application::set_string_list_configuration_value(const Glib::ustring& key, const StringList& value)
 
456
{
 
457
        gconf_client->set_string_list(get_configuration_path(key), value);
437
458
}
438
459
 
439
460
void Application::set_string_configuration_value(const Glib::ustring& key, const Glib::ustring& value)
440
461
{
441
 
        client->set(get_configuration_path(key), value);
 
462
        gconf_client->set(get_configuration_path(key), value);
442
463
}
443
464
 
444
465
void Application::set_int_configuration_value(const Glib::ustring& key, gint value)
445
466
{
446
 
        client->set(get_configuration_path(key), (gint)value);
 
467
        gconf_client->set(get_configuration_path(key), (gint)value);
447
468
}
448
469
 
449
470
void Application::set_boolean_configuration_value(const Glib::ustring& key, gboolean value)
450
471
{
451
 
        client->set(get_configuration_path(key), (bool)value);
 
472
        gconf_client->set(get_configuration_path(key), (bool)value);
452
473
}
453
474
 
454
475
void Application::select_channel_to_play()
455
476
{
456
 
        const ChannelArray& channels = channel_manager.get_channels();
 
477
        ChannelArray& channels = channel_manager.get_channels();
457
478
        if (channels.size() > 0)
458
479
        {
459
480
                gint last_channel_id = get_application().get_int_configuration_value("last_channel");
466
487
                else
467
488
                {
468
489
                        g_debug("Last channel '%d' not found", last_channel_id);
469
 
                        channel_manager.select_display_channel();
 
490
                        set_display_channel(channels[0]);
470
491
                }
471
492
        }
472
493
}
473
494
 
474
495
void Application::run()
475
496
{
476
 
        TRY
477
497
        GdkLock gdk_lock;
478
498
 
479
 
        if (initialise_database())
 
499
        if (!initialise_database())
480
500
        {
481
 
                g_debug("Me TV database initialised successfully");
482
 
                                
483
 
                const FrontendList& frontends = device_manager.get_frontends();
484
 
                
485
 
                if (!default_device.empty())
486
 
                {
487
 
                        Dvb::Frontend* default_frontend = device_manager.find_frontend_by_path(default_device);
488
 
                        
489
 
                        if (default_frontend == NULL)
490
 
                        {
491
 
                                Glib::ustring message = Glib::ustring::compose(
492
 
                                        _("Failed to load default device '%1'"), default_device);
493
 
                                throw Exception(message);
494
 
                        }
495
 
                        
496
 
                        device_manager.set_frontend(*default_frontend);
497
 
                }
498
 
                else
499
 
                {
500
 
                        if (frontends.size() > 0)
501
 
                        {
502
 
                                device_manager.set_frontend(**frontends.begin());
503
 
                        }
504
 
                }
505
 
 
 
501
                throw Exception(_("Failed to initialise database"));
 
502
        }
 
503
 
 
504
        g_debug("Me TV database initialised");
 
505
 
 
506
        status_icon = new StatusIcon();
 
507
        main_window = MainWindow::create(builder);
 
508
 
 
509
        try
 
510
        {       
506
511
                channel_manager.load(connection);
507
 
 
508
 
                status_icon = new StatusIcon();
509
 
                main_window = MainWindow::create(builder);
510
 
 
511
 
                timeout_source = gdk_threads_add_timeout(1000, &Application::on_timeout, this);
512
 
 
513
 
                TRY
514
 
                
515
 
                if (!device_manager.get_frontends().empty())
516
 
                {
517
 
                        scheduled_recording_manager.load(connection);
518
 
                }
519
 
                
520
 
                if (!minimised_mode)
521
 
                {
522
 
                        main_window->show();
523
 
                
524
 
                        if (safe_mode)
525
 
                        {
526
 
                                main_window->show_preferences_dialog();
 
512
                        
 
513
                stream_manager.load();
 
514
                stream_manager.start();
 
515
 
 
516
                ChannelArray& channels = channel_manager.get_channels();        
 
517
 
 
518
                const FrontendList& frontends = device_manager.get_frontends(); 
 
519
                if (!frontends.empty()) 
 
520
                {
 
521
                        scheduled_recording_manager.load(connection);   
 
522
 
 
523
                        if (!channels.empty())
 
524
                        {       
 
525
                                select_channel_to_play();       
527
526
                        }
 
527
                }       
 
528
 
 
529
                if (!minimised_mode)    
 
530
                {       
 
531
                        main_window->show();    
 
532
        
 
533
                        if (safe_mode)  
 
534
                        {       
 
535
                                main_window->show_preferences_dialog(); 
 
536
                        }       
528
537
                }
529
538
 
530
 
                ChannelArray& channels = channel_manager.get_channels();
 
539
                // Check that there's a device
 
540
                device_manager.check_frontend();
 
541
                
531
542
                if (channels.empty())
532
543
                {
533
 
                        main_window->show_channels_dialog();
534
 
                }
535
 
 
536
 
                select_channel_to_play();
537
 
                CATCH
538
 
 
539
 
                if (channel_manager.has_display_channel())
540
 
                {
541
 
                        stream_manager.start();
542
 
                }
543
 
                
544
 
                Gtk::Main::run();
545
 
                        
546
 
                if (status_icon != NULL)
547
 
                {
548
 
                        delete status_icon;
549
 
                        status_icon = NULL;
550
 
                }
551
 
                
552
 
                if (main_window != NULL)
553
 
                {
554
 
                        delete main_window;
555
 
                        main_window = NULL;
556
 
                }
557
 
        }
558
 
        
559
 
        CATCH
 
544
                        main_window->show_channels_dialog();    
 
545
                }
 
546
        }
 
547
        catch(...)
 
548
        {
 
549
                main_window->on_exception();
 
550
        }
 
551
 
 
552
        timeout_source = gdk_threads_add_timeout(1000, &Application::on_timeout, this);
 
553
        Gtk::Main::run();
560
554
}
561
555
 
562
556
Application& Application::get_current()
573
567
{
574
568
        preferred_language = get_string_configuration_value("preferred_language");      
575
569
 
 
570
        if (stream_manager.has_display_stream())
 
571
        {
 
572
                toggle_action_record->set_active(stream_manager.is_recording(stream_manager.get_display_channel()));
 
573
        }
 
574
        
576
575
        if (main_window != NULL)
577
576
        {
578
577
                main_window->update();
584
583
        }
585
584
}
586
585
 
587
 
void Application::previous_channel()
588
 
{
589
 
        Channel* channel = channel_manager.get_previous_channel();
590
 
        if (channel != NULL)
591
 
        {
592
 
                set_display_channel(*channel);
593
 
        }
594
 
}
595
 
 
596
 
void Application::next_channel()
597
 
{
598
 
        Channel* channel = channel_manager.get_next_channel();
599
 
        if (channel != NULL)
600
 
        {
601
 
                set_display_channel(*channel);
602
 
        }
603
 
}
604
 
 
605
586
void Application::set_display_channel_by_id(guint channel_id)
606
587
{
607
588
        set_display_channel(channel_manager.get_channel_by_id(channel_id));
612
593
        set_display_channel(channel_manager.get_channel_by_index(channel_index));
613
594
}
614
595
 
615
 
void Application::set_display_channel(const Channel& channel)
 
596
void Application::set_display_channel(Channel& channel)
616
597
{
617
598
        g_message(_("Changing channel to '%s'"), channel.name.c_str());
618
599
 
619
 
        if (channel_manager.has_display_channel())
620
 
        {
621
 
                Channel& current_channel = channel_manager.get_display_channel();
622
 
                if (current_channel.transponder == channel.transponder)
623
 
                {
624
 
                        g_message(_("Already tuned to correct frequency"));
625
 
                }
626
 
                else
627
 
                {
628
 
                        if (stream_manager.is_recording())
629
 
                        {
630
 
                                Glib::ustring message = Glib::ustring::compose(
631
 
                                        _("You cannot tune to channel '%1' because you are recording."),
632
 
                                        channel.name);
633
 
                                throw Exception(message);
634
 
                        }
635
 
                }
636
 
 
637
 
                if (current_channel != channel)
638
 
                {
639
 
                        main_window->stop_engine();
640
 
                }
641
 
        }
642
 
 
643
 
        channel_manager.set_display_channel(channel);
644
 
        stream_manager.set_display_stream(channel);
 
600
        main_window->stop_engine();
 
601
        try
 
602
        {
 
603
                stream_manager.start_display(channel);
 
604
        }
 
605
        catch (...)
 
606
        {
 
607
                main_window->on_exception();
 
608
        }
 
609
        toggle_action_record->set_active(stream_manager.is_recording(stream_manager.get_display_channel()));
 
610
 
645
611
        main_window->start_engine();
646
612
        
647
613
        set_int_configuration_value("last_channel", channel.channel_id);
670
636
                Channel* channel = channel_manager.find_channel(scheduled_recording.channel_id);
671
637
                if (channel != NULL)
672
638
                {
673
 
                        start_recording(*channel, scheduled_recording.description, true);
 
639
                        start_recording(*channel, scheduled_recording);
674
640
                }
675
641
        }
676
642
 
679
645
        {
680
646
                check = false;
681
647
 
682
 
                std::list<StreamManager::ChannelStream>& streams = stream_manager.get_streams();
683
 
                for (std::list<StreamManager::ChannelStream>::iterator i = streams.begin(); i != streams.end(); i++)
 
648
                FrontendThreadList& frontend_threads = stream_manager.get_frontend_threads();
 
649
                for (FrontendThreadList::iterator i = frontend_threads.begin(); i != frontend_threads.end(); i++)
684
650
                {
685
 
                        StreamManager::ChannelStream& channel_stream = *i;
686
 
                        if (
687
 
                            channel_stream.type == StreamManager::CHANNEL_STREAM_TYPE_SCHEDULED_RECORDING &&
688
 
                                !scheduled_recording_manager.is_recording(channel_stream.channel))
 
651
                        FrontendThread& frontend_thread = **i;
 
652
                        ChannelStreamList& streams = frontend_thread.get_streams();
 
653
                        for (ChannelStreamList::iterator j = streams.begin(); j != streams.end(); j++)
689
654
                        {
690
 
                                stream_manager.stop_recording(channel_stream.channel);
691
 
                                check = true;
692
 
                                break;
 
655
                                ChannelStream& channel_stream = **j;
 
656
                                guint scheduled_recording_id = scheduled_recording_manager.is_recording(channel_stream.channel);
 
657
                                if (
 
658
                                    channel_stream.type == CHANNEL_STREAM_TYPE_SCHEDULED_RECORDING &&
 
659
                                        (signed)scheduled_recording_id >= 0)
 
660
                                {
 
661
                                        stream_manager.stop_recording(channel_stream.channel);
 
662
                                        action_after(scheduled_recording_id);
 
663
                                        check = true;
 
664
                                        break;
 
665
                                }
693
666
                        }
694
667
                }
695
668
        }
696
669
}
697
670
 
 
671
void Application::action_after(guint action)
 
672
{
 
673
        if (action == SCHEDULED_RECORDING_ACTION_AFTER_CLOSE)
 
674
        {
 
675
                g_message("Me-TV closed by Scheduled Recording");
 
676
                action_quit->activate();
 
677
        }
 
678
        else if (action == SCHEDULED_RECORDING_ACTION_AFTER_SHUTDOWN)
 
679
        {               
 
680
                g_message("Computer Shutdown by Scheduled Recording");
 
681
 
 
682
                GError *error = NULL;
 
683
                DBusGConnection *connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
 
684
                if (connection == NULL)
 
685
                {
 
686
                        throw Exception("Failed to get DBus session");
 
687
                }
 
688
                
 
689
                DBusGProxy* proxy = dbus_g_proxy_new_for_name (connection,
 
690
                        "org.gnome.SessionManager",
 
691
                        "/org/gnome/SessionManager",
 
692
                        "org.gnome.SessionManager");
 
693
                if (proxy == NULL)
 
694
                {
 
695
                        throw Exception("Failed to get org.gnome.SessionManager proxy");
 
696
                }
 
697
                
 
698
                if (!dbus_g_proxy_call(proxy, "Shutdown", &error, G_TYPE_INVALID, G_TYPE_INVALID))
 
699
                {
 
700
                        throw Exception("Failed to call Shutdown method");
 
701
                }
 
702
 
 
703
                g_message("Shutdown requested");
 
704
        }
 
705
}
 
706
 
698
707
gboolean Application::on_timeout(gpointer data)
699
708
{
700
709
        return ((Application*)data)->on_timeout();
702
711
 
703
712
gboolean Application::on_timeout()
704
713
{
705
 
        TRY
706
714
        static guint last_seconds = 60;
707
715
        
708
716
        guint now = time(NULL);
718
726
        }
719
727
        last_seconds = seconds;
720
728
        
721
 
        CATCH
722
 
        
723
729
        return true;
724
730
}
725
731
 
726
 
Glib::ustring Application::make_recording_filename(Channel& channel, const Glib::ustring& description)
727
 
{
728
 
        Glib::ustring start_time = get_local_time_text("%c");
729
 
        Glib::ustring filename;
730
 
        Glib::ustring title = description;
731
 
 
732
 
        if (title.empty())
733
 
        {
734
 
                EpgEvent epg_event;
735
 
                if (channel.epg_events.get_current(epg_event))
736
 
                {
737
 
                        title = epg_event.get_title();
738
 
                }
739
 
        }
740
 
        
741
 
        if (title.empty())
742
 
        {
743
 
                filename = Glib::ustring::compose
744
 
                (
745
 
                        "%1 - %2.mpeg",
746
 
                        channel.name,
747
 
                        start_time
748
 
                );
749
 
        }
750
 
        else
751
 
        {
752
 
                filename = Glib::ustring::compose
753
 
                (
754
 
                        "%1 - %2 - %3.mpeg",
755
 
                        title,
756
 
                        channel.name,
757
 
                        start_time
758
 
                );
759
 
        }
760
 
 
761
 
        // Clean filename
762
 
        Glib::ustring::size_type position = Glib::ustring::npos;
763
 
        while ((position = filename.find('/')) != Glib::ustring::npos)
764
 
        {
765
 
                filename.replace(position, 1, "_");
766
 
        }
767
 
 
768
 
        if (get_boolean_configuration_value("remove_colon"))
769
 
        {
770
 
                while ((position = filename.find(':')) != Glib::ustring::npos )
771
 
                {
772
 
                        filename.replace(position, 1, "_");
773
 
                }
774
 
        }
775
 
 
776
 
        Glib::ustring fixed_filename = Glib::filename_from_utf8(filename);
777
 
        
778
 
        return Glib::build_filename(get_string_configuration_value("recording_directory"), fixed_filename);
779
 
}
780
 
 
781
732
Glib::StaticRecMutex& Application::get_mutex()
782
733
{
783
734
        return mutex;
784
735
}
785
736
 
786
 
void Application::on_error(const Glib::ustring& message)
 
737
void Application::start_recording(Channel& channel)
787
738
{
788
 
        g_debug("Error message: '%s'", message.c_str());
789
 
        if (main_window != NULL)
790
 
        {
791
 
                FullscreenBugWorkaround fullscreen_bug_workaround;
792
 
                Gtk::MessageDialog dialog(*main_window, message, false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
793
 
                dialog.set_title(_("Me TV - Error Message"));
794
 
                dialog.run();
795
 
        }
796
 
        else
797
 
        {
798
 
                Gtk::MessageDialog dialog(message, false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
799
 
                dialog.set_title(_("Me TV - Error Message"));
800
 
                dialog.run();
801
 
        }
 
739
        stream_manager.start_recording(channel);
 
740
        update();
802
741
}
803
742
 
804
 
void Application::start_recording(Channel& channel, const Glib::ustring& description, gboolean scheduled)
 
743
void Application::start_recording(Channel& channel, const ScheduledRecording& scheduled_recording)
805
744
{
806
 
        stream_manager.start_recording(channel, make_recording_filename(channel, description), scheduled);
 
745
        stream_manager.start_recording(channel, scheduled_recording);
807
746
        update();
808
 
 
809
 
        g_debug("Recording started");
810
747
}
811
748
 
812
749
void Application::stop_recording(Channel& channel)
814
751
        stream_manager.stop_recording(channel);
815
752
        update();
816
753
}
817
 
 
818
 
void Application::on_record()
819
 
{
820
 
        Glib::RecMutex::Lock lock(mutex);
821
 
 
822
 
        TRY
823
 
        if (Glib::RefPtr<Gtk::ToggleAction>::cast_dynamic(builder->get_object("record"))->get_active())
824
 
        {
825
 
                try
826
 
                {
827
 
                        start_recording(channel_manager.get_display_channel());
828
 
                }
829
 
                catch (const Glib::Exception& exception)
830
 
                {
831
 
                        Glib::RefPtr<Gtk::ToggleAction>::cast_dynamic(builder->get_object("record"))->set_active(false);
832
 
                        throw Exception(exception.what());
833
 
                }
834
 
                catch (...)
835
 
                {
836
 
                        Glib::RefPtr<Gtk::ToggleAction>::cast_dynamic(builder->get_object("record"))->set_active(false);
837
 
                        throw Exception(_("Failed to start recording"));
838
 
                }
839
 
        }
840
 
        else
841
 
        {
842
 
                stream_manager.stop_recording(channel_manager.get_display_channel());                   
843
 
                g_debug("Recording stopped");
844
 
        }
845
 
        CATCH
846
 
 
847
 
        update();
848
 
}