00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <stdlib.h>
00028 #include <errno.h>
00029 #include <string.h>
00030 #include <stdio.h>
00031
00032 #include <vlc/vlc.h>
00033 #include <vlc/intf.h>
00034
00035 #include "wxwidgets.h"
00036 #include <wx/dialog.h>
00037
00038
00039 static int PlaylistChanged( vlc_object_t *, const char *,
00040 vlc_value_t, vlc_value_t, void * );
00041
00042
00043
00044
00045
00046
00047 enum
00048 {
00049
00050 ButtonAdd_Event = wxID_HIGHEST + 1,
00051 ButtonDel_Event,
00052 ButtonClear_Event,
00053 ButtonExtract_Event,
00054 ButtonEdit_Event
00055 };
00056
00057 class BookmarksDialog: public wxFrame
00058 {
00059 public:
00060
00061 BookmarksDialog( intf_thread_t *p_intf, wxWindow *p_parent );
00062 virtual ~BookmarksDialog();
00063
00064 bool Show( bool );
00065
00066 private:
00067
00068 void Update();
00069
00070
00071 void OnClose( wxCloseEvent& event );
00072 void OnAdd( wxCommandEvent& event );
00073 void OnDel( wxCommandEvent& event );
00074 void OnClear( wxCommandEvent& event );
00075 void OnActivateItem( wxListEvent& event );
00076 void OnUpdate( wxCommandEvent &event );
00077 void OnEdit( wxCommandEvent& event );
00078 void OnExtract( wxCommandEvent& event );
00079
00080 DECLARE_EVENT_TABLE();
00081
00082 intf_thread_t *p_intf;
00083 wxWindow *p_parent;
00084
00085 wxListView *list_ctrl;
00086 };
00087
00088
00089
00090
00091
00092 DEFINE_LOCAL_EVENT_TYPE( wxEVT_BOOKMARKS );
00093
00094 BEGIN_EVENT_TABLE(BookmarksDialog, wxFrame)
00095
00096 EVT_CLOSE(BookmarksDialog::OnClose )
00097 EVT_BUTTON( ButtonAdd_Event, BookmarksDialog::OnAdd )
00098 EVT_BUTTON( ButtonDel_Event, BookmarksDialog::OnDel )
00099 EVT_BUTTON( ButtonClear_Event, BookmarksDialog::OnClear )
00100 EVT_BUTTON( ButtonExtract_Event, BookmarksDialog::OnExtract )
00101 EVT_BUTTON( ButtonEdit_Event, BookmarksDialog::OnEdit )
00102
00103 EVT_LIST_ITEM_ACTIVATED( -1, BookmarksDialog::OnActivateItem )
00104
00105 EVT_COMMAND( -1, wxEVT_BOOKMARKS, BookmarksDialog::OnUpdate )
00106 END_EVENT_TABLE()
00107
00108
00109 class BookmarkEditDialog : public wxDialog
00110 {
00111 public:
00112
00113 BookmarkEditDialog( intf_thread_t *p_intf, wxWindow *p_parent,
00114 seekpoint_t *p_seekpoint );
00115 virtual ~BookmarkEditDialog();
00116 seekpoint_t *p_seekpoint;
00117 private:
00118
00119 wxTextCtrl *name_text, *time_text, *bytes_text;
00120
00121 void OnOK( wxCommandEvent& event);
00122 void OnCancel( wxCommandEvent& event);
00123
00124 DECLARE_EVENT_TABLE();
00125
00126 intf_thread_t *p_intf;
00127 };
00128
00129 BEGIN_EVENT_TABLE( BookmarkEditDialog, wxDialog)
00130 EVT_BUTTON( wxID_OK, BookmarkEditDialog::OnOK)
00131 END_EVENT_TABLE()
00132
00133
00134
00135 BookmarkEditDialog::BookmarkEditDialog( intf_thread_t *_p_intf,
00136 wxWindow *_p_parent, seekpoint_t *_p_seekpoint ):wxDialog(
00137 _p_parent, -1, wxU(_("Edit bookmark")), wxDefaultPosition,
00138 wxDefaultSize, wxDEFAULT_FRAME_STYLE )
00139 {
00140
00141 p_intf = _p_intf;
00142 p_seekpoint = _p_seekpoint;
00143 SetIcon( *p_intf->p_sys->p_icon );
00144
00145
00146 wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL );
00147
00148 wxFlexGridSizer * sizer = new wxFlexGridSizer( 2 , 3 , 1 );
00149 name_text = new wxTextCtrl( this, -1, wxU( p_seekpoint->psz_name ?
00150 p_seekpoint->psz_name : "" ),
00151 wxDefaultPosition, wxSize( 100, 20) );
00152 time_text = new wxTextCtrl( this, -1, wxString::Format(wxT("%d"),
00153 (int)(p_seekpoint->i_time_offset / 1000000) ),
00154 wxDefaultPosition, wxSize( 100, 20) );
00155 bytes_text = new wxTextCtrl( this, -1, wxString::Format(wxT("%d"),
00156 (int)p_seekpoint->i_byte_offset ),
00157 wxDefaultPosition, wxSize( 100, 20) );
00158
00159 sizer->Add( new wxStaticText( this, -1, wxU(_("Name") ) ), 0, wxLEFT, 5 );
00160 sizer->Add( name_text, 0, wxEXPAND|wxRIGHT , 5 );
00161 sizer->Add( new wxStaticText( this, -1, wxU(_("Time") ) ), 0, wxLEFT, 5 );
00162 sizer->Add( time_text , 0, wxEXPAND|wxRIGHT , 5);
00163 sizer->Add( new wxStaticText( this, -1, wxU(_("Bytes") ) ), 0, wxLEFT, 5 );
00164 sizer->Add( bytes_text, 0, wxEXPAND|wxRIGHT, 5);
00165
00166 wxBoxSizer *button_sizer = new wxBoxSizer( wxHORIZONTAL );
00167 wxButton *ok_button = new wxButton( this, wxID_OK, wxU(_("OK") ) );
00168 ok_button->SetDefault();
00169 button_sizer->Add( ok_button );
00170 button_sizer->Add( new wxButton( this, wxID_CANCEL, wxU(_("Cancel") ) ) );
00171
00172 panel_sizer->Add( sizer, 0, wxEXPAND | wxTOP|wxBOTTOM, 5 );
00173 panel_sizer->Add( button_sizer, 0, wxEXPAND | wxBOTTOM, 5 );
00174 panel_sizer->Layout();
00175 SetSizerAndFit( panel_sizer );
00176 }
00177
00178 BookmarkEditDialog::~BookmarkEditDialog()
00179 {
00180 }
00181 void BookmarkEditDialog::OnOK( wxCommandEvent &event )
00182 {
00183 if( p_seekpoint->psz_name ) free( p_seekpoint->psz_name );
00184 p_seekpoint->psz_name = strdup( name_text->GetValue().mb_str() );
00185 p_seekpoint->i_byte_offset = atoi( bytes_text->GetValue().mb_str() );
00186 p_seekpoint->i_time_offset = 1000000 *
00187 atoll( time_text->GetValue().mb_str() ) ;
00188 EndModal( wxID_OK );
00189 }
00190
00191 void BookmarkEditDialog::OnCancel( wxCommandEvent &event )
00192 {
00193 EndModal( wxID_CANCEL );
00194 }
00195
00196
00197
00198
00199 BookmarksDialog::BookmarksDialog( intf_thread_t *_p_intf, wxWindow *p_parent )
00200 : wxFrame( p_parent->GetParent() ? p_parent->GetParent() : p_parent,
00201 -1, wxU(_("Bookmarks")),
00202 !p_parent->GetParent() ? wxDefaultPosition :
00203 wxPoint( p_parent->GetParent()->GetRect().GetX(),
00204 p_parent->GetParent()->GetRect().GetY() +
00205 p_parent->GetParent()->GetRect().GetHeight() + 40 ),
00206 wxSize( 500, -1 ),
00207 wxDEFAULT_FRAME_STYLE | wxFRAME_FLOAT_ON_PARENT )
00208 {
00209
00210 p_intf = _p_intf;
00211 SetIcon( *p_intf->p_sys->p_icon );
00212
00213 wxPanel *main_panel = new wxPanel( this, -1 );
00214 wxBoxSizer *main_sizer = new wxBoxSizer( wxHORIZONTAL );
00215
00216 wxBoxSizer *sizer = new wxBoxSizer( wxHORIZONTAL );
00217
00218 wxPanel *panel = new wxPanel( main_panel, -1 );
00219 wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL );
00220 wxButton *button_add =
00221 new wxButton( panel, ButtonAdd_Event, wxU(_("Add")) );
00222 wxButton *button_del =
00223 new wxButton( panel, ButtonDel_Event, wxU(_("Remove")) );
00224 wxButton *button_clear =
00225 new wxButton( panel, ButtonClear_Event, wxU(_("Clear")) );
00226 wxButton *button_edit =
00227 new wxButton( panel, ButtonEdit_Event, wxU(_("Edit")) );
00228 wxButton *button_extract =
00229 new wxButton( panel, ButtonExtract_Event, wxU(_("Extract")) );
00230
00231 #define ADD_TEXT "Adds a bookmark at the current position in the stream"
00232 #define REMOVE_TEXT "Removes the selected bookmarks"
00233 #define CLEAR_TEXT "Removes all the bookmarks for that stream"
00234 #define EDIT_TEXT "Edit the properties of a bookmark"
00235 #define EXTRACT_TEXT "If you select two or more bookmarks, this will " \
00236 "launch the streaming/transcoding wizard to allow you to " \
00237 "stream or save the part of the stream between these bookmarks"
00238 button_add->SetToolTip( wxU(_( ADD_TEXT ) ) );
00239 button_del->SetToolTip( wxU(_( REMOVE_TEXT ) ) );
00240 button_clear->SetToolTip( wxU(_( CLEAR_TEXT ) ) );
00241 button_edit->SetToolTip( wxU(_( EDIT_TEXT ) ) );
00242 button_extract->SetToolTip( wxU(_( EXTRACT_TEXT ) ) );
00243
00244 panel_sizer->Add( button_add, 0, wxEXPAND );
00245 panel_sizer->Add( button_del, 0, wxEXPAND );
00246 panel_sizer->Add( button_clear, 0, wxEXPAND );
00247
00248 panel_sizer->Add( button_edit, 0, wxEXPAND );
00249 panel_sizer->Add( 0, 0, 1 );
00250 panel_sizer->Add( button_extract, 0, wxEXPAND );
00251
00252 panel->SetSizerAndFit( panel_sizer );
00253
00254 list_ctrl = new wxListView( main_panel, -1,
00255 wxDefaultPosition, wxDefaultSize,
00256 wxLC_REPORT | wxSUNKEN_BORDER );
00257 list_ctrl->InsertColumn( 0, wxU(_("Description")) );
00258 list_ctrl->SetColumnWidth( 0, 240 );
00259 list_ctrl->InsertColumn( 1, wxU(_("Size offset")) );
00260 list_ctrl->InsertColumn( 2, wxU(_("Time offset")) );
00261
00262 sizer->Add( panel, 0, wxEXPAND | wxALL, 1 );
00263 sizer->Add( list_ctrl, 1, wxEXPAND | wxALL, 1 );
00264 main_panel->SetSizer( sizer );
00265
00266 main_sizer->Add( main_panel, 1, wxEXPAND );
00267 SetSizer( main_sizer );
00268
00269 playlist_t *p_playlist =
00270 (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
00271 FIND_ANYWHERE );
00272 if( p_playlist )
00273 {
00274
00275 var_AddCallback( p_playlist, "playlist-current",
00276 PlaylistChanged, this );
00277 vlc_object_release( p_playlist );
00278 }
00279 }
00280
00281 BookmarksDialog::~BookmarksDialog()
00282 {
00283 playlist_t *p_playlist =
00284 (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
00285 FIND_ANYWHERE );
00286 if( p_playlist )
00287 {
00288 var_DelCallback( p_playlist, "playlist-current",
00289 PlaylistChanged, this );
00290 vlc_object_release( p_playlist );
00291 }
00292 }
00293
00294
00295
00296
00297 wxFrame *BookmarksDialog( intf_thread_t *p_intf, wxWindow *p_parent )
00298 {
00299 return new class BookmarksDialog( p_intf, p_parent );
00300 }
00301
00302 void BookmarksDialog::Update()
00303 {
00304 input_thread_t *p_input =
00305 (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
00306 FIND_ANYWHERE );
00307 if( !p_input ) return;
00308
00309 seekpoint_t **pp_bookmarks;
00310 int i_bookmarks;
00311
00312 list_ctrl->DeleteAllItems();
00313 if( input_Control( p_input, INPUT_GET_BOOKMARKS, &pp_bookmarks,
00314 &i_bookmarks ) != VLC_SUCCESS )
00315 {
00316 vlc_object_release( p_input );
00317 return;
00318 }
00319
00320 for( int i = 0; i < i_bookmarks; i++ )
00321 {
00322 list_ctrl->InsertItem( i, wxL2U( pp_bookmarks[i]->psz_name ) );
00323
00324 list_ctrl->SetItem( i, 1, wxString::Format(wxT("%d"),
00325 (int)(pp_bookmarks[i]->i_byte_offset) ) );
00326 list_ctrl->SetItem( i, 2, wxString::Format(wxT("%d"),
00327 (int)(pp_bookmarks[i]->i_time_offset / 1000000) ) );
00328 }
00329
00330 vlc_object_release( p_input );
00331 }
00332
00333 bool BookmarksDialog::Show( bool show )
00334 {
00335 Update();
00336 return wxFrame::Show( show );
00337 }
00338
00339 void BookmarksDialog::OnClose( wxCloseEvent& event )
00340 {
00341 Hide();
00342 }
00343
00344 void BookmarksDialog::OnAdd( wxCommandEvent& event )
00345 {
00346 input_thread_t *p_input =
00347 (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
00348 FIND_ANYWHERE );
00349 if( !p_input ) return;
00350
00351 seekpoint_t bookmark;
00352 vlc_value_t pos;
00353 bookmark.psz_name = NULL;
00354 bookmark.i_byte_offset = 0;
00355 bookmark.i_time_offset = 0;
00356
00357 var_Get( p_input, "position", &pos );
00358 bookmark.psz_name = NULL;
00359 input_Control( p_input, INPUT_GET_BYTE_POSITION, &bookmark.i_byte_offset );
00360 var_Get( p_input, "time", &pos );
00361 bookmark.i_time_offset = pos.i_time;
00362 input_Control( p_input, INPUT_ADD_BOOKMARK, &bookmark );
00363 vlc_object_release( p_input );
00364
00365 Update();
00366 }
00367
00368 void BookmarksDialog::OnDel( wxCommandEvent& event )
00369 {
00370 input_thread_t *p_input =
00371 (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
00372 FIND_ANYWHERE );
00373 if( !p_input ) return;
00374
00375 int i_focused = list_ctrl->GetFocusedItem();
00376 if( i_focused >= 0 )
00377 {
00378 input_Control( p_input, INPUT_DEL_BOOKMARK, i_focused );
00379 }
00380
00381 vlc_object_release( p_input );
00382
00383 Update();
00384 }
00385
00386 void BookmarksDialog::OnClear( wxCommandEvent& event )
00387 {
00388 input_thread_t *p_input =
00389 (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
00390 FIND_ANYWHERE );
00391 if( !p_input ) return;
00392
00393 input_Control( p_input, INPUT_CLEAR_BOOKMARKS );
00394
00395 vlc_object_release( p_input );
00396
00397 Update();
00398 }
00399
00400 void BookmarksDialog::OnExtract( wxCommandEvent& event )
00401 {
00402 long i_first = list_ctrl->GetNextItem( -1, wxLIST_NEXT_ALL,
00403 wxLIST_STATE_SELECTED );
00404 long i_second = list_ctrl->GetNextItem( i_first, wxLIST_NEXT_ALL,
00405 wxLIST_STATE_SELECTED );
00406
00407 if( i_first == -1 || i_second == -1 )
00408 {
00409 wxMessageBox( wxU(_("You must select two bookmarks") ),
00410 wxU(_("Invalid selection") ), wxICON_WARNING | wxOK,
00411 this );
00412 return;
00413 }
00414 input_thread_t *p_input =
00415 (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
00416 FIND_ANYWHERE );
00417 if( !p_input )
00418 {
00419 wxMessageBox( wxU(_("The stream must be playing or paused for "
00420 "bookmarks to work" ) ), wxU(_("No input found")),
00421 wxICON_WARNING | wxOK,
00422 this );
00423 return;
00424 }
00425
00426 seekpoint_t **pp_bookmarks;
00427 int i_bookmarks ;
00428
00429 if( input_Control( p_input, INPUT_GET_BOOKMARKS, &pp_bookmarks,
00430 &i_bookmarks ) != VLC_SUCCESS )
00431 {
00432 vlc_object_release( p_input );
00433 return;
00434 }
00435
00436 if( i_first < i_bookmarks && i_second <= i_bookmarks )
00437 {
00438 WizardDialog *p_wizard_dialog = new WizardDialog( p_intf, this,
00439 p_input->input.p_item->psz_uri,
00440 pp_bookmarks[i_first]->i_time_offset/1000000,
00441 pp_bookmarks[i_second]->i_time_offset/1000000 );
00442 vlc_object_release( p_input );
00443 if( p_wizard_dialog )
00444 {
00445 p_wizard_dialog->Run();
00446 delete p_wizard_dialog;
00447 }
00448 }
00449 else
00450 {
00451 vlc_object_release( p_input );
00452 }
00453 }
00454
00455 void BookmarksDialog::OnActivateItem( wxListEvent& event )
00456 {
00457 input_thread_t *p_input =
00458 (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
00459 FIND_ANYWHERE );
00460 if( !p_input ) return;
00461
00462 input_Control( p_input, INPUT_SET_BOOKMARK, event.GetIndex() );
00463
00464 vlc_object_release( p_input );
00465 }
00466
00467 void BookmarksDialog::OnEdit( wxCommandEvent& event )
00468 {
00469 input_thread_t *p_old_input;
00470 input_thread_t *p_input =
00471 (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
00472 FIND_ANYWHERE );
00473 if( !p_input ) return;
00474
00475
00476 seekpoint_t **pp_bookmarks;
00477 int i_bookmarks;
00478
00479 if( input_Control( p_input, INPUT_GET_BOOKMARKS, &pp_bookmarks,
00480 &i_bookmarks ) != VLC_SUCCESS )
00481 {
00482 vlc_object_release( p_input );
00483 return;
00484 }
00485 p_old_input = p_input;
00486 vlc_object_release( p_input );
00487
00488 long i_first = list_ctrl->GetNextItem( -1, wxLIST_NEXT_ALL,
00489 wxLIST_STATE_SELECTED );
00490
00491 if( i_first > -1 && i_first <= i_bookmarks )
00492 {
00493 BookmarkEditDialog *p_bmk_edit;
00494 p_bmk_edit = new BookmarkEditDialog( p_intf, this,
00495 pp_bookmarks[i_first]);
00496
00497 if( p_bmk_edit->ShowModal() == wxID_OK )
00498 {
00499 p_input =(input_thread_t *)vlc_object_find( p_intf,
00500 VLC_OBJECT_INPUT, FIND_ANYWHERE );
00501 if( !p_input )
00502 {
00503 wxMessageBox( wxU( _("No input found. The stream must be "
00504 "playing or paused for bookmarks to work.") ),
00505 wxU( _("No input") ), wxICON_WARNING | wxOK,
00506 this );
00507 return;
00508 }
00509 if( p_old_input != p_input )
00510 {
00511 wxMessageBox( wxU( _("Input has changed, unable to save "
00512 "bookmark. Use \"pause\" while editing "
00513 "bookmarks to keep the same input.") ),
00514 wxU( _("Input has changed ") ),
00515 wxICON_WARNING | wxOK, this );
00516 vlc_object_release( p_input );
00517 return;
00518
00519 }
00520 if( input_Control( p_input, INPUT_CHANGE_BOOKMARK,
00521 p_bmk_edit->p_seekpoint, i_first ) !=
00522 VLC_SUCCESS )
00523 {
00524 vlc_object_release( p_input );
00525 return;
00526 }
00527 Update();
00528 vlc_object_release( p_input );
00529 }
00530 }
00531 }
00532
00533
00534 void BookmarksDialog::OnUpdate( wxCommandEvent &event )
00535 {
00536 Update();
00537 }
00538
00539
00540
00541
00542
00543
00544 static int PlaylistChanged( vlc_object_t *p_this, const char *psz_variable,
00545 vlc_value_t oval, vlc_value_t nval, void *param )
00546 {
00547 class BookmarksDialog *p_dialog = (class BookmarksDialog *)param;
00548
00549 wxCommandEvent bookmarks_event( wxEVT_BOOKMARKS, 0 );
00550 p_dialog->AddPendingEvent( bookmarks_event );
00551
00552 return VLC_SUCCESS;
00553 }