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

多媒体

开发平台:

MultiPlatform

  1. /***************************************************************************
  2.                           interface.cpp  -  description
  3.                              -------------------
  4.     begin                : Sun Mar 25 2001
  5.     copyright            : (C) 2001 by andres
  6.     email                : dae@chez.com
  7.  ***************************************************************************/
  8. #include "disc.h"
  9. #include "info.h"
  10. #include "interface.h"
  11. #include "net.h"
  12. #include "menu.h"
  13. #include "slider.h"
  14. #include "preferences.h"
  15. #include "languagemenu.h"
  16. #include <iostream>
  17. #include <kaction.h>
  18. #include <kfiledialog.h>
  19. #include <klocale.h>
  20. #include <kstdaction.h>
  21. #include <kurl.h>
  22. #include <kurldrag.h>
  23. #include <qcursor.h>
  24. #include <qdragobject.h>
  25. #include <qtimer.h>
  26. #include <kdialog.h>
  27. #include <kstatusbar.h>
  28. #define ID_STATUS_MSG       1
  29. #define ID_DATE             2
  30. #define ID_STREAM_SOURCE    3
  31. KInterface::KInterface( intf_thread_t *p_intf, QWidget *parent,
  32.         const char *name ) : KMainWindow(parent,name)
  33. {
  34.     setAcceptDrops(true);
  35.     this->p_intf = p_intf;
  36.     p_messagesWindow = new KMessagesWindow( p_intf, p_intf->p_sys->p_msg );
  37.     fDiskDialog = new KDiskDialog( this );
  38.     fNetDialog = new KNetDialog( this );
  39.     fTitleMenu = new KTitleMenu( p_intf, this );
  40.     fSlider = new KVLCSlider( QSlider::Horizontal, this );
  41.     fSlider->setMaxValue(10000);
  42.     connect( fSlider, SIGNAL( userChanged( int ) ), this,
  43.              SLOT( slotSliderMoved( int ) ) );
  44.     connect( fSlider, SIGNAL( valueChanged( int ) ), this,
  45.              SLOT( slotSliderChanged( int ) ) );
  46.     connect( fSlider, SIGNAL( sliderMoved( int ) ), this,
  47.              SLOT( slotSliderChanged( int ) ) );
  48.     setCentralWidget(fSlider);
  49.     fTimer = new QTimer( this );
  50.     connect( fTimer, SIGNAL( timeout() ), this, SLOT( slotManage() ) );
  51.     resize( 400, 30 );
  52.     ///////////////////////////////////////////////////////////////////
  53.     // call inits to invoke all other construction parts
  54.     // XXX could we move this up ?
  55.     initStatusBar();
  56.     initActions();
  57.     // add certain calls to the popup menu
  58.     fileOpen->plug( fTitleMenu );
  59.     fileOpenRecent->plug( fTitleMenu );
  60.     diskOpen->plug( fTitleMenu );
  61.     streamOpen->plug( fTitleMenu );
  62.     play->plug( fTitleMenu );
  63.     pause->plug( fTitleMenu );
  64.     slow->plug( fTitleMenu );
  65.     fast->plug( fTitleMenu );
  66.     fileQuit->plug( fTitleMenu );
  67.     fTimer->start( 0, FALSE );
  68. }
  69. KInterface::~KInterface()
  70. {
  71.     ;
  72. }
  73. void KInterface::initActions()
  74. {
  75.     languages = new KActionMenu( _( "Languages" ), actionCollection(),
  76.                                  _("language") );
  77.     languages->setEnabled( false );
  78.     languageCollection = new KActionCollection( this );
  79.     subtitleCollection = new KActionCollection( this );
  80.     subtitles = new KActionMenu( _( "Subtitles" ), actionCollection(),
  81.                                  "subtitles" );
  82.     subtitles->setEnabled( false );
  83.     fileOpen =
  84.         KStdAction::open(this, SLOT(slotFileOpen()), actionCollection());
  85.     fileOpenRecent =
  86.         KStdAction::openRecent(this, SLOT(slotFileOpenRecent(const KURL&)),
  87.                                actionCollection());
  88.     preferences = KStdAction::preferences(this, SLOT(slotShowPreferences()),
  89.                                           actionCollection());
  90.     fileQuit = KStdAction::quit(this, SLOT(slotFileQuit()),
  91.                                 actionCollection());
  92.     viewToolBar = KStdAction::showToolbar(this, SLOT(slotViewToolBar()),
  93.                                           actionCollection());
  94.     viewStatusBar = KStdAction::showStatusbar(this, SLOT(slotViewStatusBar()),
  95.                                               actionCollection());
  96.     diskOpen = new KAction( i18n( _("Open &Disk") ), 0, 0, this,
  97.                             SLOT( slotOpenDisk() ), actionCollection(),
  98.                             "open_disk" );
  99.     streamOpen = new KAction( i18n( _("Open &Stream") ), 0, 0, this,
  100.                               SLOT( slotOpenStream() ), actionCollection(),
  101.                               "open_stream" );
  102.     backward = new KAction( i18n( _("&Backward") ), 0, 0, this,
  103.                             SLOT( slotBackward() ), actionCollection(),
  104.                             "backward" );
  105.     stop = new KAction( i18n( _("&Stop") ), 0, 0, this,
  106.                         SLOT( slotStop() ), actionCollection(), "stop" );
  107.     play = new KAction( i18n( _("&Play") ), 0, 0, this,
  108.                         SLOT( slotPlay() ), actionCollection(), "play" );
  109.     pause = new KAction( i18n( _("P&ause") ), 0, 0, this,
  110.                          SLOT( slotPause() ), actionCollection(), "pause" );
  111.     slow = new KAction( i18n( _("&Slow") ), 0, 0, this,
  112.                         SLOT( slotSlow() ), actionCollection(), "slow" );
  113.     fast = new KAction( i18n( _("Fas&t") ), 0, 0, this,
  114.                         SLOT( slotFast() ), actionCollection(), "fast" );
  115.     prev = new KAction( i18n( _("Prev") ), 0, 0, this,
  116.                         SLOT( slotPrev() ), actionCollection(), "prev" );
  117.     next = new KAction( i18n( _("Next") ), 0, 0, this,
  118.                         SLOT( slotNext() ), actionCollection(), "next" );
  119.     messages = new KAction( _( "Messages..." ), 0, 0, this,
  120.                             SLOT( slotShowMessages() ), actionCollection(),
  121.                             "view_messages");
  122.     
  123.     info = new KAction( _( "Stream info..." ), 0, 0, this,
  124.                         SLOT( slotShowInfo() ), actionCollection(),
  125.                         "view_stream_info");
  126.     info->setEnabled( false );
  127.     program = new KActionMenu( _( "Program" ), actionCollection(), "program" );
  128.     program->setEnabled( false );
  129.     title = new KActionMenu( _( "Title" ), actionCollection(), "title" );
  130.     title->setEnabled( false );
  131.     chapter = new KActionMenu( _( "Chapter" ), actionCollection(), "chapter" );
  132.     chapter->setEnabled( false );
  133.     fileOpen->setStatusText(i18n(_("Opens an existing document")));
  134.     fileOpenRecent->setStatusText(i18n(_("Opens a recently used file")));
  135.     fileQuit->setStatusText(i18n(_("Quits the application")));
  136.     viewToolBar->setStatusText(i18n(_("Enables/disables the toolbar")));
  137.     viewStatusBar->setStatusText(i18n(_("Enables/disables the status bar")));
  138.     diskOpen->setStatusText( i18n( _("Opens a disk") ) );
  139.     streamOpen->setStatusText( i18n( _("Opens a network stream") ) );
  140.     backward->setStatusText( i18n( _("Backward") ) );
  141.     stop->setStatusText( i18n( _("Stops playback") ) );
  142.     play->setStatusText( i18n( _("Starts playback") ) );
  143.     pause->setStatusText( i18n( _("Pauses playback") ) );
  144.     slow->setStatusText( i18n( _("Slow") ) );
  145.     fast->setStatusText( i18n( _("Fast") ) );
  146.     prev->setStatusText( i18n( _("Prev") ) );
  147.     next->setStatusText( i18n( _("Next") ) );
  148.     // use the absolute path to your ktestui.rc file for testing purpose in createGUI();
  149.     char *psz_uifile = config_GetPsz( p_intf, "kde-uirc" );
  150.     createGUI( psz_uifile );
  151. //    createGUI( "./modules/gui/kde/ui.rc" );
  152. }
  153. void KInterface::initStatusBar()
  154. {
  155.   ///////////////////////////////////////////////////////////////////
  156.   // STATUSBAR
  157.   // TODO: add your own items you need for displaying current application status.
  158.     statusBar()->insertItem(i18n(_("Ready.")), ID_STATUS_MSG, 1, false);
  159.     statusBar()->setItemAlignment( ID_STATUS_MSG, AlignLeft | AlignVCenter );
  160.     statusBar()->insertItem( "0:00:00", ID_DATE, 0, true );
  161. }
  162. /////////////////////////////////////////////////////////////////////
  163. // SLOT IMPLEMENTATION
  164. /////////////////////////////////////////////////////////////////////
  165. void KInterface::slotShowMessages()
  166. {
  167.     p_messagesWindow->show();
  168. }
  169. void KInterface::slotShowInfo()
  170. {
  171.     if ( p_intf->p_sys->p_input )
  172.     {
  173.         new KInfoWindow(p_intf, p_intf->p_sys->p_input);
  174.     }
  175. }
  176. void KInterface::slotFileOpen()
  177. {
  178.     playlist_t *p_playlist;
  179.     slotStatusMsg( i18n( _("Opening file...") ) );
  180.     KURL url=KFileDialog::getOpenURL( QString::null,
  181.             i18n( "*|All files" ), this, i18n( _("Open File...") ) );
  182.     if( !url.isEmpty() )
  183.     {
  184.         p_playlist = (playlist_t *)
  185.             vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
  186.         if( p_playlist )
  187.         {
  188.             fileOpenRecent->addURL( url );
  189.             playlist_Add( p_playlist, url.path(), url.path(), 
  190.                           PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
  191.             vlc_object_release( p_playlist );
  192.         }
  193.     }
  194.     slotStatusMsg( i18n( _("Ready.") ) );
  195. }
  196. void KInterface::slotFileOpenRecent(const KURL& url)
  197. {
  198.   slotStatusMsg(i18n(_("Opening file...")));
  199.   slotStatusMsg(i18n(_("Ready.")));
  200. }
  201. void KInterface::slotFileQuit()
  202. {
  203.     slotStatusMsg(i18n(_("Exiting...")));
  204.     p_intf->p_vlc->b_die = VLC_TRUE;
  205.     slotStatusMsg(i18n(_("Ready.")));
  206. }
  207. void KInterface::slotViewToolBar()
  208. {
  209.   slotStatusMsg(i18n(_("Toggling toolbar...")));
  210.   ///////////////////////////////////////////////////////////////////
  211.   // turn Toolbar on or off
  212.   if(!viewToolBar->isChecked())
  213.   {
  214.     toolBar("mainToolBar")->hide();
  215.   }
  216.   else
  217.   {
  218.     toolBar("mainToolBar")->show();
  219.   }        
  220.   slotStatusMsg(i18n(_("Ready.")));
  221. }
  222. void KInterface::slotViewStatusBar()
  223. {
  224.   slotStatusMsg(i18n(_("Toggle the status bar...")));
  225.   ///////////////////////////////////////////////////////////////////
  226.   //turn Statusbar on or off
  227.   if(!viewStatusBar->isChecked())
  228.   {
  229.     statusBar()->hide();
  230.   }
  231.   else
  232.   {
  233.     statusBar()->show();
  234.   }
  235.   slotStatusMsg(i18n(_("Ready.")));
  236. }
  237. void KInterface::slotShowPreferences()
  238. {
  239.     // Do something
  240.     KPreferences(this->p_intf, "main", this, "preferences");
  241. }
  242. void KInterface::slotStatusMsg(const QString &text)
  243. {
  244.   ///////////////////////////////////////////////////////////////////
  245.   // change status message permanently
  246.   statusBar()->clear();
  247.   statusBar()->changeItem(text, ID_STATUS_MSG);
  248. }
  249. void KInterface::slotManage()
  250. {
  251.     p_messagesWindow->update();
  252. //    p_intf->p_sys->p_app->processEvents();
  253.     vlc_mutex_lock( &p_intf->change_lock );
  254.     /* Update the input */
  255.     if( p_intf->p_sys->p_input == NULL )
  256.     {
  257.         p_intf->p_sys->p_input = (input_thread_t *)
  258.                 vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_ANYWHERE );
  259.         if ( p_intf->p_sys->p_input )
  260.         {
  261.             languages->setEnabled( true );
  262.             subtitles->setEnabled( true );
  263.             info->setEnabled( true );
  264.         }
  265.             
  266.     }
  267.     else if( p_intf->p_sys->p_input->b_dead )
  268.     {
  269.         vlc_object_release( p_intf->p_sys->p_input );
  270.         p_intf->p_sys->p_input = NULL;
  271.         languages->setEnabled( false );
  272.         subtitles->setEnabled( false );
  273.         info->setEnabled( false );
  274.     }
  275.     /* If the "display popup" flag has changed */
  276.     if( p_intf->b_menu_change )
  277.     {
  278.         fTitleMenu->popup( ( QCursor::pos() ) );
  279.         p_intf->b_menu_change = 0;
  280.     }
  281.     if( p_intf->p_sys->p_input )
  282.     {
  283.         input_thread_t *p_input = p_intf->p_sys->p_input;
  284.                 
  285.         vlc_mutex_lock( &p_input->stream.stream_lock );
  286.         if( !p_input->b_die )
  287.         {
  288.             /* New input or stream map change */
  289.             if( p_input->stream.b_changed )
  290.             {
  291.                 //            E_(GtkModeManage)( p_intf );
  292.                 //GtkSetupMenus( p_intf );
  293.                 slotUpdateLanguages();
  294.                 p_intf->p_sys->b_playing = 1;
  295.                 p_input->stream.b_changed = 0;
  296.             }
  297.             /* Manage the slider. fSlider->setValue triggers
  298.              * slotSliderChanged which needs to grab the stream lock*/
  299. #define p_area p_input->stream.p_selected_area
  300.             if( p_area->i_size ) {
  301.                 vlc_mutex_unlock( &p_input->stream.stream_lock );
  302.                 fSlider->setValue( ( 10000 * p_area->i_tell )
  303.                                    / p_area->i_size );
  304.                 vlc_mutex_lock( &p_input->stream.stream_lock );
  305.             }
  306. #undef p_area
  307.             
  308.             //         if( p_intf->p_sys->i_part !=
  309.             //    p_input->stream.p_selected_area->i_part )
  310.             //{
  311.                 //      p_intf->p_sys->b_chapter_update = 1;
  312.                 //GtkSetupMenus( p_intf );
  313.             //}
  314.         }
  315.         vlc_mutex_unlock( &p_input->stream.stream_lock );
  316.     }
  317.     
  318.     else if( p_intf->p_sys->b_playing && !p_intf->b_die )
  319.     {
  320.         //E_(GtkModeManage)( p_intf );
  321.         p_intf->p_sys->b_playing = 0;
  322.     }
  323.     if( p_intf->b_die )
  324.     {
  325.         p_intf->p_sys->p_app->quit();
  326.     }
  327.     vlc_mutex_unlock( &p_intf->change_lock );
  328.     msleep( 100 );
  329. }
  330. void KInterface::slotSliderMoved( int position )
  331. {
  332.     if( p_intf->p_sys->p_input )
  333.     {
  334.         // XXX is this locking really useful ?
  335.         vlc_mutex_lock( &p_intf->change_lock );
  336.         var_SetFloat( p_intf->p_sys->p_input, "position",
  337.                        (double)position / 10000.0 );
  338.         vlc_mutex_unlock( &p_intf->change_lock );
  339.     }
  340. }
  341. void KInterface::slotUpdateLanguages()
  342. {
  343.     es_descriptor_t *   p_spu_es;
  344.     es_descriptor_t *   p_audio_es;
  345.     /* look for selected ES */
  346.     p_audio_es = NULL;
  347.     p_spu_es = NULL;
  348.     for( unsigned int i = 0 ;
  349.          i < p_intf->p_sys->p_input->stream.i_selected_es_number ;
  350.          i++
  351.         )
  352.     {
  353.         if( p_intf->p_sys->p_input->stream.pp_selected_es[i]->i_cat
  354.             == AUDIO_ES )
  355.         {
  356.             p_audio_es = p_intf->p_sys->p_input->stream.pp_selected_es[i];
  357.         }
  358.         if( p_intf->p_sys->p_input->stream.pp_selected_es[i]->i_cat == SPU_ES )
  359.         {
  360.             p_spu_es = p_intf->p_sys->p_input->stream.pp_selected_es[i];
  361.         }
  362.     }
  363.     languages->setEnabled( false );
  364.     subtitles->setEnabled( false );
  365.     languageCollection->clear();
  366.     subtitleCollection->clear();
  367.     languages->popupMenu()->clear();
  368.     subtitles->popupMenu()->clear();
  369.     /* audio menus */
  370.     /* find audio root menu */
  371.     languageMenus( languages, p_audio_es, AUDIO_ES );
  372.     /* sub picture menus */
  373.     /* find spu root menu */
  374.     languageMenus( subtitles, p_spu_es, SPU_ES );
  375. }
  376. /*
  377.  * called with stream lock
  378.  */
  379. void KInterface::languageMenus(KActionMenu *root, es_descriptor_t *p_es,
  380.                           int i_cat)
  381. {
  382.     int i_item = 0;
  383.     if ( i_cat != AUDIO_ES )
  384.     {
  385.         KLanguageMenuAction *p_item =
  386.             new KLanguageMenuAction( p_intf, _( "Off" ), 0, this );
  387.         subtitleCollection->insert( p_item );
  388.         root->insert( p_item );
  389.         root->insert( new KActionSeparator( this ) );
  390.         p_item->setExclusiveGroup( QString().sprintf( "%d", i_cat ) );
  391.         p_item->setChecked( p_es == 0 );
  392.     }
  393.     
  394. #define ES p_intf->p_sys->p_input->stream.pp_es[i]
  395.     /* create a set of language buttons and append them to the container */
  396.     for( unsigned int i = 0 ;
  397.          i < p_intf->p_sys->p_input->stream.i_es_number ;
  398.          i++ )
  399.     {
  400.         if( ( ES->i_cat == i_cat ) &&
  401.             ( !ES->p_pgrm ||
  402.               ES->p_pgrm ==
  403.                  p_intf->p_sys->p_input->stream.p_selected_program ) )
  404.         {
  405.             i_item++;
  406.             QString name = p_intf->p_sys->p_input->stream.pp_es[i]->psz_desc;
  407.             if( name.isEmpty() )
  408.             {
  409.                 name.sprintf( "Language %d", i_item );
  410.             }
  411.             KLanguageMenuAction *p_item;
  412.             if ( i_cat == AUDIO_ES )
  413.             {
  414.                 p_item = new KLanguageMenuAction( p_intf, name, ES,
  415.                                                   this );
  416.                 languageCollection->insert(p_item);
  417.             }
  418.             else
  419.             {
  420.                 p_item = new KLanguageMenuAction( p_intf, name, ES,
  421.                                                   this );
  422.                 subtitleCollection->insert(p_item);
  423.             }
  424.             p_item->setExclusiveGroup( QString().sprintf( "%d", i_cat ) );
  425.             root->insert( p_item );
  426.             
  427.             if( p_es == p_intf->p_sys->p_input->stream.pp_es[i] )
  428.             {
  429.                 /* don't lose p_item when we append into menu */
  430.                 //p_item_active = p_item;
  431.                 p_item->setChecked( true );
  432.             }
  433.             connect( p_item, SIGNAL( toggled( bool, es_descriptor_t * ) ),
  434.                      this, SLOT( slotSetLanguage( bool, es_descriptor_t * ) ));
  435.         }
  436.     }
  437.     root->setEnabled( true );
  438. }
  439. void KInterface::slotSetLanguage( bool on, es_descriptor_t *p_es )
  440. {
  441.     if( p_es )
  442.         var_SetInteger( p_intf->p_sys->p_input, "audio-es", p_es->i_id );
  443.     else
  444.         var_SetInteger( p_intf->p_sys->p_input, "audio-es", -1 );
  445. }
  446. void KInterface::slotSliderChanged( int position )
  447. {
  448.     if( p_intf->p_sys->p_input != NULL )
  449.     {
  450.         char psz_time[ MSTRTIME_MAX_SIZE ];
  451.         int64_t i_seconds;
  452.         i_seconds = var_GetTime( p_intf->p_sys->p_input, "time" ) / I64C(1000000 );
  453.         secstotimestr( psz_time, i_seconds );
  454.         statusBar()->changeItem( psz_time, ID_DATE );
  455.      }
  456. }
  457. void KInterface::slotOpenDisk()
  458. {
  459.     playlist_t *p_playlist;
  460.     int r = fDiskDialog->exec();
  461.     if ( r )
  462.     {
  463.         // Build source name
  464.         QString source;
  465.         source += fDiskDialog->type();
  466.         source += ':';
  467.         source += fDiskDialog->device();
  468.         source += '@';
  469.         source += fDiskDialog->title();
  470.         source += ',';
  471.         source += fDiskDialog->chapter();
  472.         p_playlist = (playlist_t *)
  473.             vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
  474.         if( p_playlist )
  475.         {
  476.             // add it to playlist
  477.             playlist_Add( p_playlist, source.latin1(), source.latin1(),
  478.                           PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
  479.             vlc_object_release( p_playlist );
  480.         }
  481.     }
  482. }
  483. void KInterface::slotOpenStream()
  484. {
  485.     playlist_t *p_playlist;
  486.     int r = fNetDialog->exec();
  487.     if ( r )
  488.     {
  489.         // Build source name
  490.         QString source;
  491.         source += fNetDialog->protocol();
  492.         source += "://";
  493.         source += fNetDialog->server();
  494.         source += ":";
  495.         source += QString().setNum( fNetDialog->port() );
  496.         p_playlist = (playlist_t *)
  497.             vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
  498.         if( p_playlist )
  499.         {
  500.             // add it to playlist
  501.             playlist_Add( p_playlist, source.latin1(), source.latin1(),
  502.                           PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
  503.             vlc_object_release( p_playlist );
  504.         }
  505.     }
  506. }
  507. void KInterface::slotPlay()
  508. {
  509.     if( p_intf->p_sys->p_input )
  510.     {
  511.         var_SetInteger( p_intf->p_sys->p_input, "state", PLAYING_S );
  512.     }
  513. }
  514. void KInterface::slotPause()
  515. {
  516.     if ( p_intf->p_sys->p_input )
  517.     {
  518.         var_SetInteger( p_intf->p_sys->p_input, "state", PAUSE_S );
  519.     }
  520. }
  521. void KInterface::slotStop()
  522. {
  523.     playlist_t *p_playlist = (playlist_t *)
  524.             vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
  525.     if( p_playlist )
  526.     {
  527.         playlist_Stop( p_playlist );
  528.         vlc_object_release( p_playlist );
  529.     }
  530. }
  531. void KInterface::slotBackward()
  532. {
  533.     msg_Err( p_intf, "KInterface::slotBackward() - Unimplemented" );
  534. }
  535. void KInterface::slotPrev()
  536. {
  537.     playlist_t *p_playlist = (playlist_t *)
  538.             vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
  539.     if( p_playlist )
  540.     {
  541.         playlist_Prev( p_playlist );
  542.         vlc_object_release( p_playlist );
  543.     }
  544. }
  545. void KInterface::slotNext()
  546. {
  547.     playlist_t *p_playlist = (playlist_t *)
  548.             vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
  549.     if( p_playlist )
  550.     {
  551.         playlist_Next( p_playlist );
  552.         vlc_object_release( p_playlist );
  553.     }
  554. }
  555. void KInterface::slotSlow()
  556. {
  557.     if( p_intf->p_sys->p_input != NULL )
  558.     {
  559.         var_SetVoid( p_intf->p_sys->p_input, "rate-slower" );
  560.     }
  561. }
  562. void KInterface::slotFast()
  563. {
  564.     if( p_intf->p_sys->p_input != NULL )
  565.     {
  566.         var_SetVoid( p_intf->p_sys->p_input, "rate-faster" );
  567.     }
  568. }
  569. void KInterface::dragEnterEvent( QDragEnterEvent *event )
  570. {
  571.     event->accept( QUriDrag::canDecode( event ) );
  572. }
  573. void KInterface::dropEvent( QDropEvent *event )
  574. {
  575.     KURL::List urlList;
  576.     playlist_t *p_playlist = (playlist_t *)
  577.             vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
  578.     if( p_playlist == NULL )
  579.     {
  580.         return;
  581.     }
  582.     if ( KURLDrag::decode( event, urlList ) )
  583.     {
  584.         for ( KURL::List::ConstIterator i = urlList.begin(); i != urlList.end(); i++ )
  585.         {
  586.             // XXX add a private function to add a KURL with checking
  587.             // actually a whole class for core abstraction would be neat
  588.             if( !(*i).isEmpty() )
  589.             {
  590.                 fileOpenRecent->addURL( *i );
  591.                 playlist_Add( p_playlist, (*i).path(), (*i).path(),
  592.                           PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
  593.             }
  594.         }
  595.     }
  596.     vlc_object_release( p_playlist );
  597. }