Various little tweaks.
[dcpomatic.git] / src / wx / ffmpeg_content_dialog.cc
1 /* -*- c-basic-offset: 8; default-tab-width: 8; -*- */
2
3 /*
4     Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
5
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
20 */
21
22 #include <boost/lexical_cast.hpp>
23 #include "lib/ffmpeg_content.h"
24 #include "lib/playlist.h"
25 #include "ffmpeg_content_dialog.h"
26 #include "wx_util.h"
27 #include "audio_mapping_view.h"
28
29 using std::vector;
30 using std::string;
31 using std::cout;
32 using boost::shared_ptr;
33 using boost::lexical_cast;
34 using boost::dynamic_pointer_cast;
35
36 FFmpegContentDialog::FFmpegContentDialog (wxWindow* parent, shared_ptr<FFmpegContent> content)
37         : wxDialog (parent, wxID_ANY, _("Video"))
38         , _content (content)
39 {
40         wxFlexGridSizer* grid = new wxFlexGridSizer (3, 6, 6);
41         grid->AddGrowableCol (1, 1);
42
43         add_label_to_sizer (grid, this, _("Audio stream"));
44         _audio_stream = new wxChoice (this, wxID_ANY);
45         grid->Add (_audio_stream, 1, wxEXPAND | wxALL, 6);
46         _audio_description = new wxStaticText (this, wxID_ANY, wxT (""));
47         grid->Add (_audio_description, 1, wxALIGN_CENTER_VERTICAL | wxLEFT, 8);
48         
49         add_label_to_sizer (grid, this, _("Subtitle stream"));
50         _subtitle_stream = new wxChoice (this, wxID_ANY);
51         grid->Add (_subtitle_stream, 1, wxEXPAND | wxALL, 6);
52         grid->AddSpacer (0);
53
54         _audio_stream->Clear ();
55         vector<shared_ptr<FFmpegAudioStream> > a = content->audio_streams ();
56         for (vector<shared_ptr<FFmpegAudioStream> >::iterator i = a.begin(); i != a.end(); ++i) {
57                 _audio_stream->Append (std_to_wx ((*i)->name), new wxStringClientData (std_to_wx (lexical_cast<string> ((*i)->id))));
58         }
59         
60         if (content->audio_stream()) {
61                 checked_set (_audio_stream, lexical_cast<string> (content->audio_stream()->id));
62         }
63
64         _subtitle_stream->Clear ();
65         vector<shared_ptr<FFmpegSubtitleStream> > s = content->subtitle_streams ();
66         if (s.empty ()) {
67                 _subtitle_stream->Enable (false);
68         }
69         for (vector<shared_ptr<FFmpegSubtitleStream> >::iterator i = s.begin(); i != s.end(); ++i) {
70                 _subtitle_stream->Append (std_to_wx ((*i)->name), new wxStringClientData (std_to_wx (lexical_cast<string> ((*i)->id))));
71         }
72         
73         if (content->subtitle_stream()) {
74                 checked_set (_subtitle_stream, lexical_cast<string> (content->subtitle_stream()->id));
75         } else {
76                 _subtitle_stream->SetSelection (wxNOT_FOUND);
77         }
78
79         wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL);
80
81         overall_sizer->Add (grid, 1, wxEXPAND | wxALL, 6);
82
83         _audio_mapping = new AudioMappingView (this);
84         _audio_mapping->set_mapping (content->audio_mapping ());
85         overall_sizer->Add (_audio_mapping, 1, wxEXPAND | wxALL, 6);
86
87         wxSizer* buttons = CreateSeparatedButtonSizer (wxOK);
88         if (buttons) {
89                 overall_sizer->Add (buttons, wxSizerFlags().Expand().DoubleBorder());
90         }
91
92         SetSizer (overall_sizer);
93         overall_sizer->Layout ();
94         overall_sizer->SetSizeHints (this);
95
96         _audio_stream->Connect    (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FFmpegContentDialog::audio_stream_changed), 0, this);
97         _subtitle_stream->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (FFmpegContentDialog::subtitle_stream_changed), 0, this);
98         _audio_mapping->Changed.connect (bind (&FFmpegContentDialog::audio_mapping_changed, this, _1));
99 }
100
101 void
102 FFmpegContentDialog::audio_stream_changed (wxCommandEvent &)
103 {
104         shared_ptr<FFmpegContent> c = _content.lock ();
105         if (!c) {
106                 return;
107         }
108         
109         vector<shared_ptr<FFmpegAudioStream> > a = c->audio_streams ();
110         vector<shared_ptr<FFmpegAudioStream> >::iterator i = a.begin ();
111         string const s = string_client_data (_audio_stream->GetClientObject (_audio_stream->GetSelection ()));
112         while (i != a.end() && lexical_cast<string> ((*i)->id) != s) {
113                 ++i;
114         }
115
116         if (i != a.end ()) {
117                 c->set_audio_stream (*i);
118         }
119
120         if (!c->audio_stream ()) {
121                 _audio_description->SetLabel (wxT (""));
122         } else {
123                 wxString s;
124                 if (c->audio_channels() == 1) {
125                         s << _("1 channel");
126                 } else {
127                         s << c->audio_channels() << wxT (" ") << _("channels");
128                 }
129                 s << wxT (", ") << c->content_audio_frame_rate() << _("Hz");
130                 _audio_description->SetLabel (s);
131         }
132 }
133
134
135
136 void
137 FFmpegContentDialog::subtitle_stream_changed (wxCommandEvent &)
138 {
139         shared_ptr<FFmpegContent> c = _content.lock ();
140         if (!c) {
141                 return;
142         }
143         
144         vector<shared_ptr<FFmpegSubtitleStream> > a = c->subtitle_streams ();
145         vector<shared_ptr<FFmpegSubtitleStream> >::iterator i = a.begin ();
146         string const s = string_client_data (_subtitle_stream->GetClientObject (_subtitle_stream->GetSelection ()));
147         while (i != a.end() && lexical_cast<string> ((*i)->id) != s) {
148                 ++i;
149         }
150
151         if (i != a.end ()) {
152                 c->set_subtitle_stream (*i);
153         }
154 }
155
156 void
157 FFmpegContentDialog::audio_mapping_changed (AudioMapping m)
158 {
159         shared_ptr<FFmpegContent> content = _content.lock ();
160
161         if (!content || !content->audio_stream()) {
162                 return;
163         }
164
165         content->audio_stream()->mapping = m;
166 }
167