bookmarks.cpp
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:19k
源码类别:

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * bookmarks.cpp : wxWindows plugin for vlc
  3.  *****************************************************************************
  4.  * Copyright (C) 2000-2004 VideoLAN
  5.  * $Id: bookmarks.cpp 8644 2004-09-05 16:53:04Z fkuehne $
  6.  *
  7.  * Authors: Gildas Bazin <gbazin@videolan.org>
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2 of the License, or
  12.  * (at your option) any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  22.  *****************************************************************************/
  23. /*****************************************************************************
  24.  * Preamble
  25.  *****************************************************************************/
  26. #include <stdlib.h>                                      /* malloc(), free() */
  27. #include <errno.h>                                                 /* ENOMEM */
  28. #include <string.h>                                            /* strerror() */
  29. #include <stdio.h>
  30. #include <vlc/vlc.h>
  31. #include <vlc/intf.h>
  32. #include "wxwindows.h"
  33. #include <wx/dialog.h>
  34. /* Callback prototype */
  35. static int PlaylistChanged( vlc_object_t *, const char *,
  36.                             vlc_value_t, vlc_value_t, void * );
  37. /*****************************************************************************
  38.  * Class declaration.
  39.  *****************************************************************************/
  40. /* IDs for the controls and the menu commands */
  41. enum
  42. {
  43.     /* menu items */
  44.     ButtonAdd_Event = wxID_HIGHEST + 1,
  45.     ButtonDel_Event,
  46.     ButtonClear_Event,
  47.     ButtonExtract_Event,
  48.     ButtonEdit_Event
  49. };
  50. class BookmarksDialog: public wxFrame
  51. {
  52. public:
  53.     /* Constructor */
  54.     BookmarksDialog( intf_thread_t *p_intf, wxWindow *p_parent );
  55.     virtual ~BookmarksDialog();
  56.     bool Show( bool );
  57. private:
  58.     void Update();
  59.     /* Event handlers (these functions should _not_ be virtual) */
  60.     void OnClose( wxCommandEvent& event );
  61.     void OnAdd( wxCommandEvent& event );
  62.     void OnDel( wxCommandEvent& event );
  63.     void OnClear( wxCommandEvent& event );
  64.     void OnActivateItem( wxListEvent& event );
  65.     void OnUpdate( wxCommandEvent &event );
  66.     void OnEdit( wxCommandEvent& event );
  67.     void OnExtract( wxCommandEvent& event );
  68.     DECLARE_EVENT_TABLE();
  69.     intf_thread_t *p_intf;
  70.     wxWindow *p_parent;
  71.     wxListView *list_ctrl;
  72. };
  73. /*****************************************************************************
  74.  * Event Table.
  75.  *****************************************************************************/
  76. DEFINE_LOCAL_EVENT_TYPE( wxEVT_BOOKMARKS );
  77. BEGIN_EVENT_TABLE(BookmarksDialog, wxFrame)
  78.     /* Hide the window when the user closes the window */
  79.     EVT_CLOSE(BookmarksDialog::OnClose )
  80.     EVT_BUTTON( ButtonAdd_Event, BookmarksDialog::OnAdd )
  81.     EVT_BUTTON( ButtonDel_Event, BookmarksDialog::OnDel )
  82.     EVT_BUTTON( ButtonClear_Event, BookmarksDialog::OnClear )
  83.     EVT_BUTTON( ButtonExtract_Event, BookmarksDialog::OnExtract )
  84.     EVT_BUTTON( ButtonEdit_Event, BookmarksDialog::OnEdit )
  85.     EVT_LIST_ITEM_ACTIVATED( -1, BookmarksDialog::OnActivateItem )
  86.     EVT_COMMAND( -1, wxEVT_BOOKMARKS, BookmarksDialog::OnUpdate )
  87. END_EVENT_TABLE()
  88. /* Declaration of class BookmarkEditDialog */
  89. class BookmarkEditDialog : public wxDialog
  90. {
  91. public:
  92.     /* Constructor */
  93.     BookmarkEditDialog( intf_thread_t *p_intf, wxWindow *p_parent,
  94.                   seekpoint_t *p_seekpoint );
  95.     virtual ~BookmarkEditDialog();
  96.     seekpoint_t *p_seekpoint;
  97. private:
  98.     wxTextCtrl *name_text, *time_text, *bytes_text;
  99.     void OnOK( wxCommandEvent& event);
  100.     void OnCancel( wxCommandEvent& event);
  101.     DECLARE_EVENT_TABLE();
  102.     intf_thread_t *p_intf;
  103. };
  104. BEGIN_EVENT_TABLE( BookmarkEditDialog, wxDialog)
  105.             EVT_BUTTON( wxID_OK, BookmarkEditDialog::OnOK)
  106. END_EVENT_TABLE()
  107. /****************************************************************************
  108.  * BookmarkEditDialog
  109.  ***************************************************************************/
  110. BookmarkEditDialog::BookmarkEditDialog( intf_thread_t *_p_intf,
  111.            wxWindow *_p_parent, seekpoint_t *_p_seekpoint ):wxDialog(
  112.             _p_parent, -1, wxU(_("Edit bookmark")), wxDefaultPosition,
  113.             wxDefaultSize, wxDEFAULT_FRAME_STYLE )
  114. {
  115.     /* Initializations */
  116.     p_intf = _p_intf;
  117.     p_seekpoint = _p_seekpoint;
  118.     SetIcon( *p_intf->p_sys->p_icon );
  119.     /* Create a panel to put everything in*/
  120.     wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL );
  121.     wxFlexGridSizer * sizer = new wxFlexGridSizer( 2 , 3 , 1 );
  122.     name_text = new wxTextCtrl( this, -1, wxU( p_seekpoint->psz_name ?
  123.                                                p_seekpoint->psz_name : "" ),
  124.                                 wxDefaultPosition, wxSize( 100, 20) );
  125.     time_text = new wxTextCtrl( this, -1, wxString::Format(wxT("%d"),
  126.                                 (int)(p_seekpoint->i_time_offset / 1000000) ),
  127.                                 wxDefaultPosition, wxSize( 100, 20) );
  128.     bytes_text = new wxTextCtrl( this, -1, wxString::Format(wxT("%d"),
  129.                                 (int)p_seekpoint->i_byte_offset ),
  130.                                 wxDefaultPosition, wxSize( 100, 20) );
  131.     sizer->Add( new wxStaticText( this, -1, wxU(_("Name") ) ), 0, wxLEFT, 5 );
  132.     sizer->Add( name_text, 0, wxEXPAND|wxRIGHT , 5 );
  133.     sizer->Add( new wxStaticText( this, -1, wxU(_("Time") ) ), 0, wxLEFT, 5 );
  134.     sizer->Add( time_text , 0, wxEXPAND|wxRIGHT , 5);
  135.     sizer->Add( new wxStaticText( this, -1, wxU(_("Bytes") ) ), 0, wxLEFT, 5 );
  136.     sizer->Add( bytes_text, 0, wxEXPAND|wxRIGHT, 5);
  137.     wxBoxSizer *button_sizer = new wxBoxSizer( wxHORIZONTAL );
  138.     button_sizer->Add( new wxButton( this, wxID_OK, wxU(_("OK") ) ) );
  139.     button_sizer->Add( new wxButton( this, wxID_CANCEL, wxU(_("Cancel") ) ) );
  140.     panel_sizer->Add( sizer, 0, wxEXPAND | wxTOP|wxBOTTOM, 5 );
  141.     panel_sizer->Add( button_sizer, 0, wxEXPAND | wxBOTTOM, 5 );
  142.     panel_sizer->Layout();
  143.     SetSizerAndFit( panel_sizer );
  144. }
  145. BookmarkEditDialog::~BookmarkEditDialog()
  146. {
  147. }
  148. void BookmarkEditDialog::OnOK( wxCommandEvent &event )
  149. {
  150.     if( p_seekpoint->psz_name ) free( p_seekpoint->psz_name );
  151.     p_seekpoint->psz_name = strdup( name_text->GetValue().mb_str() );
  152.     p_seekpoint->i_byte_offset = atoi( bytes_text->GetValue().mb_str() );
  153.     p_seekpoint->i_time_offset =  1000000 *
  154.                                   atoll( time_text->GetValue().mb_str() ) ;
  155.     EndModal( wxID_OK );
  156. }
  157. void BookmarkEditDialog::OnCancel( wxCommandEvent &event )
  158. {
  159.     EndModal( wxID_CANCEL );
  160. }
  161. /*****************************************************************************
  162.  * Constructor.
  163.  *****************************************************************************/
  164. BookmarksDialog::BookmarksDialog( intf_thread_t *_p_intf, wxWindow *p_parent )
  165.   : wxFrame( p_parent->GetParent() ? p_parent->GetParent() : p_parent,
  166.              -1, wxU(_("Bookmarks")),
  167.              !p_parent->GetParent() ? wxDefaultPosition :
  168.                wxPoint( p_parent->GetParent()->GetRect().GetX(),
  169.                         p_parent->GetParent()->GetRect().GetY() +
  170.                         p_parent->GetParent()->GetRect().GetHeight() + 40 ),
  171.              wxSize( 500, -1 ),
  172.              wxDEFAULT_FRAME_STYLE | wxFRAME_FLOAT_ON_PARENT )
  173. {
  174.     /* Initializations */
  175.     p_intf = _p_intf;
  176.     SetIcon( *p_intf->p_sys->p_icon );
  177.     wxPanel *main_panel = new wxPanel( this, -1 );
  178.     wxBoxSizer *main_sizer = new wxBoxSizer( wxHORIZONTAL );
  179.     wxBoxSizer *sizer = new wxBoxSizer( wxHORIZONTAL );
  180.     wxPanel *panel = new wxPanel( main_panel, -1 );
  181.     wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL );
  182.     wxButton *button_add =
  183.         new wxButton( panel, ButtonAdd_Event, wxU(_("Add")) );
  184.     wxButton *button_del =
  185.         new wxButton( panel, ButtonDel_Event, wxU(_("Remove")) );
  186.     wxButton *button_clear =
  187.         new wxButton( panel, ButtonClear_Event, wxU(_("Clear")) );
  188.     wxButton *button_edit =
  189.         new wxButton( panel, ButtonEdit_Event, wxU(_("Edit")) );
  190.     wxButton *button_extract =
  191.         new wxButton( panel, ButtonExtract_Event, wxU(_("Extract")) );
  192. #define ADD_TEXT "Adds a bookmark at the current position in the stream"
  193. #define REMOVE_TEXT "Removes the selected bookmarks"
  194. #define CLEAR_TEXT "Removes all the bookmarks for that stream"
  195. #define EDIT_TEXT "Edit the properties of a bookmark"
  196. #define EXTRACT_TEXT "If you select two or more bookmarks, this will " 
  197.                "launch the streaming/transcoding wizard to allow you to " 
  198.               "stream or save the part of the stream between these bookmarks"
  199.     button_add->SetToolTip(  wxU(_( ADD_TEXT ) ) );
  200.     button_del->SetToolTip(  wxU(_( REMOVE_TEXT ) ) );
  201.     button_clear->SetToolTip(  wxU(_( CLEAR_TEXT ) ) );
  202.     button_edit->SetToolTip(  wxU(_( EDIT_TEXT ) ) );
  203.     button_extract->SetToolTip( wxU(_( EXTRACT_TEXT ) ) );
  204.     panel_sizer->Add( button_add, 0, wxEXPAND );
  205.     panel_sizer->Add( button_del, 0, wxEXPAND );
  206.     panel_sizer->Add( button_clear, 0, wxEXPAND );
  207.     panel_sizer->Add( button_edit, 0, wxEXPAND );
  208.     panel_sizer->Add( 0, 0, 1 );
  209.     panel_sizer->Add( button_extract, 0, wxEXPAND );
  210.     panel->SetSizerAndFit( panel_sizer );
  211.     list_ctrl = new wxListView( main_panel, -1,
  212.                                 wxDefaultPosition, wxDefaultSize,
  213.                                 wxLC_REPORT | wxSUNKEN_BORDER );
  214.     list_ctrl->InsertColumn( 0, wxU(_("Description")) );
  215.     list_ctrl->SetColumnWidth( 0, 240 );
  216.     list_ctrl->InsertColumn( 1, wxU(_("Size offset")) );
  217.     list_ctrl->InsertColumn( 2, wxU(_("Time offset")) );
  218.     sizer->Add( panel, 0, wxEXPAND | wxALL, 1 );
  219.     sizer->Add( list_ctrl, 1, wxEXPAND | wxALL, 1 );
  220.     main_panel->SetSizer( sizer );
  221.     main_sizer->Add( main_panel, 1, wxEXPAND );
  222.     SetSizer( main_sizer );
  223.     playlist_t *p_playlist =
  224.         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
  225.                                        FIND_ANYWHERE );
  226.     if( p_playlist )
  227.     {
  228.        /* Some global changes happened -> Rebuild all */
  229.        var_AddCallback( p_playlist, "playlist-current",
  230.                         PlaylistChanged, this );
  231.        vlc_object_release( p_playlist );
  232.     }
  233. }
  234. BookmarksDialog::~BookmarksDialog()
  235. {
  236.     playlist_t *p_playlist =
  237.         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
  238.                                        FIND_ANYWHERE );
  239.     if( p_playlist )
  240.     {
  241.        var_DelCallback( p_playlist, "playlist-current",
  242.                         PlaylistChanged, this );
  243.        vlc_object_release( p_playlist );
  244.     }
  245. }
  246. /*****************************************************************************
  247.  * Private methods.
  248.  *****************************************************************************/
  249. wxWindow *BookmarksDialog( intf_thread_t *p_intf, wxWindow *p_parent )
  250. {
  251.     return new BookmarksDialog::BookmarksDialog( p_intf, p_parent );
  252. }
  253. void BookmarksDialog::Update()
  254. {
  255.     input_thread_t *p_input =
  256.         (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
  257.                                            FIND_ANYWHERE );
  258.     if( !p_input ) return;
  259.     seekpoint_t **pp_bookmarks;
  260.     int i_bookmarks;
  261.     list_ctrl->DeleteAllItems();
  262.     if( input_Control( p_input, INPUT_GET_BOOKMARKS, &pp_bookmarks,
  263.                        &i_bookmarks ) != VLC_SUCCESS )
  264.     {
  265.         vlc_object_release( p_input );
  266.         return;
  267.     }
  268.     for( int i = 0; i < i_bookmarks; i++ )
  269.     {
  270.         list_ctrl->InsertItem( i, wxL2U( pp_bookmarks[i]->psz_name ) );
  271.         /* FIXME: see if we can use the 64 bits integer format string */
  272.         list_ctrl->SetItem( i, 1, wxString::Format(wxT("%d"),
  273.                             (int)(pp_bookmarks[i]->i_byte_offset) ) );
  274.         list_ctrl->SetItem( i, 2, wxString::Format(wxT("%d"),
  275.                             (int)(pp_bookmarks[i]->i_time_offset / 1000000) ) );
  276.     }
  277.     vlc_object_release( p_input );
  278. }
  279. bool BookmarksDialog::Show( bool show )
  280. {
  281.     Update();
  282.     return wxFrame::Show( show );
  283. }
  284. void BookmarksDialog::OnClose( wxCommandEvent& event )
  285. {
  286.     Hide();
  287. }
  288. void BookmarksDialog::OnAdd( wxCommandEvent& event )
  289. {
  290.     input_thread_t *p_input =
  291.         (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
  292.                                            FIND_ANYWHERE );
  293.     if( !p_input ) return;
  294.     seekpoint_t bookmark;
  295.     vlc_value_t pos;
  296.     bookmark.psz_name = NULL;
  297.     bookmark.i_byte_offset = 0;
  298.     bookmark.i_time_offset = 0;
  299.     var_Get( p_input, "position", &pos );
  300.     bookmark.psz_name = NULL;
  301.     input_Control( p_input, INPUT_GET_BYTE_POSITION, &bookmark.i_byte_offset );
  302.     var_Get( p_input, "time", &pos );
  303.     bookmark.i_time_offset = pos.i_time;
  304.     input_Control( p_input, INPUT_ADD_BOOKMARK, &bookmark );
  305.     vlc_object_release( p_input );
  306.     Update();
  307. }
  308. void BookmarksDialog::OnDel( wxCommandEvent& event )
  309. {
  310.     input_thread_t *p_input =
  311.         (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
  312.                                            FIND_ANYWHERE );
  313.     if( !p_input ) return;
  314.     int i_focused = list_ctrl->GetFocusedItem();
  315.     if( i_focused >= 0 )
  316.     {
  317.         input_Control( p_input, INPUT_DEL_BOOKMARK, i_focused );
  318.     }
  319.     vlc_object_release( p_input );
  320.     Update();
  321. }
  322. void BookmarksDialog::OnClear( wxCommandEvent& event )
  323. {
  324.     input_thread_t *p_input =
  325.         (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
  326.                                            FIND_ANYWHERE );
  327.     if( !p_input ) return;
  328.     input_Control( p_input, INPUT_CLEAR_BOOKMARKS );
  329.     vlc_object_release( p_input );
  330.     Update();
  331. }
  332. void BookmarksDialog::OnExtract( wxCommandEvent& event )
  333. {
  334.     long i_first = list_ctrl->GetNextItem( -1, wxLIST_NEXT_ALL,
  335.                                           wxLIST_STATE_SELECTED );
  336.     long i_second = list_ctrl->GetNextItem( i_first, wxLIST_NEXT_ALL,
  337.                                           wxLIST_STATE_SELECTED );
  338.     if( i_first == -1 || i_second == -1 )
  339.     {
  340.         wxMessageBox( wxU(_("You must select two bookmarks") ),
  341.                       wxU(_("Invalid selection") ), wxICON_WARNING | wxOK,
  342.                       this );
  343.         return;
  344.     }
  345.     input_thread_t *p_input =
  346.         (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
  347.                                            FIND_ANYWHERE );
  348.     if( !p_input )
  349.     {
  350.         wxMessageBox( wxU(_("The stream must be playing or paused for "
  351.                             "bookmarks to work" ) ), wxU(_("No input found")),
  352.                             wxICON_WARNING | wxOK,
  353.                             this );
  354.         return;
  355.     }
  356.     seekpoint_t **pp_bookmarks;
  357.     int i_bookmarks ;
  358.     if( input_Control( p_input, INPUT_GET_BOOKMARKS, &pp_bookmarks,
  359.                        &i_bookmarks ) != VLC_SUCCESS )
  360.     {
  361.         vlc_object_release( p_input );
  362.         return;
  363.     }
  364.     if( i_first < i_bookmarks && i_second <= i_bookmarks )
  365.     {
  366.         WizardDialog *p_wizard_dialog = new WizardDialog( p_intf, this,
  367.                                p_input->input.p_item->psz_uri,
  368.                                pp_bookmarks[i_first]->i_time_offset/1000000,
  369.                                pp_bookmarks[i_second]->i_time_offset/1000000 );
  370.         vlc_object_release( p_input );
  371.         if( p_wizard_dialog )
  372.         {
  373.             p_wizard_dialog->Run();
  374.             delete p_wizard_dialog;
  375.         }
  376.     }
  377.     else
  378.     {
  379.         vlc_object_release( p_input );
  380.     }
  381. }
  382. void BookmarksDialog::OnActivateItem( wxListEvent& event )
  383. {
  384.     input_thread_t *p_input =
  385.         (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
  386.                                            FIND_ANYWHERE );
  387.     if( !p_input ) return;
  388.     input_Control( p_input, INPUT_SET_BOOKMARK, event.GetIndex() );
  389.     vlc_object_release( p_input );
  390. }
  391. void BookmarksDialog::OnEdit( wxCommandEvent& event )
  392. {
  393.     input_thread_t *p_old_input;
  394.     input_thread_t *p_input =
  395.             (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
  396.                                                    FIND_ANYWHERE );
  397.     if( !p_input ) return;
  398.     seekpoint_t **pp_bookmarks;
  399.     int i_bookmarks;
  400.     if( input_Control( p_input, INPUT_GET_BOOKMARKS, &pp_bookmarks,
  401.                        &i_bookmarks ) != VLC_SUCCESS )
  402.     {
  403.         vlc_object_release( p_input );
  404.         return;
  405.     }
  406.     p_old_input = p_input;
  407.     vlc_object_release( p_input );
  408.     long i_first = list_ctrl->GetNextItem( -1, wxLIST_NEXT_ALL,
  409.                                                wxLIST_STATE_SELECTED );
  410.     if( i_first > -1 && i_first <= i_bookmarks )
  411.     {
  412.         BookmarkEditDialog *p_bmk_edit;
  413.         p_bmk_edit = new BookmarkEditDialog( p_intf, this,
  414.                                pp_bookmarks[i_first]);
  415.         if( p_bmk_edit->ShowModal() == wxID_OK )
  416.         {
  417.             p_input =(input_thread_t *)vlc_object_find( p_intf,
  418.                             VLC_OBJECT_INPUT, FIND_ANYWHERE );
  419.            if( !p_input )
  420.            {
  421.                 wxMessageBox( wxU( _("No input found. The stream must be "
  422.                                   "playing or paused for bookmarks to work.") ),
  423.                                wxU( _("No input") ), wxICON_WARNING | wxOK,
  424.                                this );
  425.                 return;
  426.            }
  427.            if( p_old_input != p_input )
  428.            {
  429.                 wxMessageBox( wxU( _("Input has changed, unable to save "
  430.                                   "bookmark. Use "pause" while editing "
  431.                                   "bookmarks to keep the same input.") ),
  432.                                wxU( _("Input has changed ") ),
  433.                                wxICON_WARNING | wxOK, this );
  434.                 vlc_object_release( p_input );
  435.                 return;
  436.            }
  437.            fprintf(stderr,"Changing %in",i_first );
  438.            if( input_Control(  p_input, INPUT_CHANGE_BOOKMARK,
  439.                                 p_bmk_edit->p_seekpoint, i_first ) !=
  440.                VLC_SUCCESS )
  441.            {
  442.                vlc_object_release( p_input );
  443.                return;
  444.            }
  445.            Update();
  446.            vlc_object_release( p_input );
  447.         }
  448.     }
  449. }
  450. void BookmarksDialog::OnUpdate( wxCommandEvent &event )
  451. {
  452.     Update();
  453. }
  454. /*****************************************************************************
  455.  * PlaylistChanged: callback triggered by the intf-change playlist variable
  456.  *  We don't rebuild the playlist directly here because we don't want the
  457.  *  caller to block for a too long time.
  458.  *****************************************************************************/
  459. static int PlaylistChanged( vlc_object_t *p_this, const char *psz_variable,
  460.                             vlc_value_t oval, vlc_value_t nval, void *param )
  461. {
  462.     BookmarksDialog::BookmarksDialog *p_dialog =
  463.         (BookmarksDialog::BookmarksDialog *)param;
  464.     wxCommandEvent bookmarks_event( wxEVT_BOOKMARKS, 0 );
  465.     p_dialog->AddPendingEvent( bookmarks_event );
  466.     return VLC_SUCCESS;
  467. }