1 /***************************************************************************
2 interface.cpp - description
4 begin : Sun Mar 25 2001
5 copyright : (C) 2001 by andres
7 ***************************************************************************/
11 #include "interface.h"
15 #include "preferences.h"
16 #include "languagemenu.h"
21 #include <kfiledialog.h>
23 #include <kstdaction.h>
27 #include <qdragobject.h>
30 #include <kstatusbar.h>
32 #define ID_STATUS_MSG 1
34 #define ID_STREAM_SOURCE 3
36 KInterface::KInterface( intf_thread_t *p_intf, QWidget *parent,
37 const char *name ) : KMainWindow(parent,name)
41 this->p_intf = p_intf;
42 p_messagesWindow = new KMessagesWindow( p_intf, p_intf->p_sys->p_msg );
43 fDiskDialog = new KDiskDialog( this );
44 fNetDialog = new KNetDialog( this );
45 fTitleMenu = new KTitleMenu( p_intf, this );
47 fSlider = new KVLCSlider( QSlider::Horizontal, this );
48 fSlider->setMaxValue(10000);
49 connect( fSlider, SIGNAL( userChanged( int ) ), this,
50 SLOT( slotSliderMoved( int ) ) );
51 connect( fSlider, SIGNAL( valueChanged( int ) ), this,
52 SLOT( slotSliderChanged( int ) ) );
53 connect( fSlider, SIGNAL( sliderMoved( int ) ), this,
54 SLOT( slotSliderChanged( int ) ) );
55 setCentralWidget(fSlider);
57 fTimer = new QTimer( this );
58 connect( fTimer, SIGNAL( timeout() ), this, SLOT( slotManage() ) );
61 ///////////////////////////////////////////////////////////////////
62 // call inits to invoke all other construction parts
63 // XXX could we move this up ?
67 // add certain calls to the popup menu
68 fileOpen->plug( fTitleMenu );
69 fileOpenRecent->plug( fTitleMenu );
70 diskOpen->plug( fTitleMenu );
71 streamOpen->plug( fTitleMenu );
72 play->plug( fTitleMenu );
73 pause->plug( fTitleMenu );
74 slow->plug( fTitleMenu );
75 fast->plug( fTitleMenu );
76 fileQuit->plug( fTitleMenu );
77 fTimer->start( 0, FALSE );
81 KInterface::~KInterface()
86 void KInterface::initActions()
88 languages = new KActionMenu( _( "Languages" ), actionCollection(),
90 languages->setEnabled( false );
91 languageCollection = new KActionCollection( this );
92 subtitleCollection = new KActionCollection( this );
93 subtitles = new KActionMenu( _( "Subtitles" ), actionCollection(),
95 subtitles->setEnabled( false );
97 KStdAction::open(this, SLOT(slotFileOpen()), actionCollection());
99 KStdAction::openRecent(this, SLOT(slotFileOpenRecent(const KURL&)),
101 preferences = KStdAction::preferences(this, SLOT(slotShowPreferences()),
103 fileQuit = KStdAction::quit(this, SLOT(slotFileQuit()),
105 viewToolBar = KStdAction::showToolbar(this, SLOT(slotViewToolBar()),
107 viewStatusBar = KStdAction::showStatusbar(this, SLOT(slotViewStatusBar()),
110 diskOpen = new KAction( i18n( _("Open &Disk") ), 0, 0, this,
111 SLOT( slotOpenDisk() ), actionCollection(),
113 streamOpen = new KAction( i18n( _("Open &Stream") ), 0, 0, this,
114 SLOT( slotOpenStream() ), actionCollection(),
116 backward = new KAction( i18n( _("&Backward") ), 0, 0, this,
117 SLOT( slotBackward() ), actionCollection(),
119 stop = new KAction( i18n( _("&Stop") ), 0, 0, this,
120 SLOT( slotStop() ), actionCollection(), "stop" );
121 play = new KAction( i18n( _("&Play") ), 0, 0, this,
122 SLOT( slotPlay() ), actionCollection(), "play" );
123 pause = new KAction( i18n( _("P&ause") ), 0, 0, this,
124 SLOT( slotPause() ), actionCollection(), "pause" );
125 slow = new KAction( i18n( _("&Slow") ), 0, 0, this,
126 SLOT( slotSlow() ), actionCollection(), "slow" );
127 fast = new KAction( i18n( _("Fas&t") ), 0, 0, this,
128 SLOT( slotFast() ), actionCollection(), "fast" );
129 prev = new KAction( i18n( _("Prev") ), 0, 0, this,
130 SLOT( slotPrev() ), actionCollection(), "prev" );
131 next = new KAction( i18n( _("Next") ), 0, 0, this,
132 SLOT( slotNext() ), actionCollection(), "next" );
133 messages = new KAction( _( "Messages..." ), 0, 0, this,
134 SLOT( slotShowMessages() ), actionCollection(),
137 info = new KAction( _( "Stream info..." ), 0, 0, this,
138 SLOT( slotShowInfo() ), actionCollection(),
141 info->setEnabled( false );
142 program = new KActionMenu( _( "Program" ), actionCollection(), "program" );
143 program->setEnabled( false );
144 title = new KActionMenu( _( "Title" ), actionCollection(), "title" );
145 title->setEnabled( false );
146 chapter = new KActionMenu( _( "Chapter" ), actionCollection(), "chapter" );
147 chapter->setEnabled( false );
148 fileOpen->setStatusText(i18n(_("Opens an existing document")));
149 fileOpenRecent->setStatusText(i18n(_("Opens a recently used file")));
150 fileQuit->setStatusText(i18n(_("Quits the application")));
151 viewToolBar->setStatusText(i18n(_("Enables/disables the toolbar")));
152 viewStatusBar->setStatusText(i18n(_("Enables/disables the status bar")));
154 diskOpen->setStatusText( i18n( _("Opens a disk") ) );
155 streamOpen->setStatusText( i18n( _("Opens a network stream") ) );
156 backward->setStatusText( i18n( _("Backward") ) );
157 stop->setStatusText( i18n( _("Stops playback") ) );
158 play->setStatusText( i18n( _("Starts playback") ) );
159 pause->setStatusText( i18n( _("Pauses playback") ) );
160 slow->setStatusText( i18n( _("Slow") ) );
161 fast->setStatusText( i18n( _("Fast") ) );
162 prev->setStatusText( i18n( _("Prev") ) );
163 next->setStatusText( i18n( _("Next") ) );
164 // use the absolute path to your ktestui.rc file for testing purpose in createGUI();
165 char *psz_uifile = config_GetPsz( p_intf, "kde-uirc" );
166 createGUI( psz_uifile );
167 // createGUI( "./modules/gui/kde/ui.rc" );
170 void KInterface::initStatusBar()
172 ///////////////////////////////////////////////////////////////////
174 // TODO: add your own items you need for displaying current application status.
175 statusBar()->insertItem(i18n(_("Ready.")), ID_STATUS_MSG, 1, false);
176 statusBar()->setItemAlignment( ID_STATUS_MSG, AlignLeft | AlignVCenter );
177 statusBar()->insertItem( "0:00:00", ID_DATE, 0, true );
180 /////////////////////////////////////////////////////////////////////
181 // SLOT IMPLEMENTATION
182 /////////////////////////////////////////////////////////////////////
183 void KInterface::slotShowMessages()
185 p_messagesWindow->show();
188 void KInterface::slotShowInfo()
190 if ( p_intf->p_sys->p_input )
192 new KInfoWindow(p_intf, p_intf->p_sys->p_input);
196 void KInterface::slotFileOpen()
198 playlist_t *p_playlist;
200 slotStatusMsg( i18n( _("Opening file...") ) );
201 KURL url=KFileDialog::getOpenURL( QString::null,
202 i18n( "*|All files" ), this, i18n( _("Open File...") ) );
206 p_playlist = (playlist_t *)
207 vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
210 fileOpenRecent->addURL( url );
211 playlist_Add( p_playlist, url.path(), url.path(),
212 PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
213 vlc_object_release( p_playlist );
217 slotStatusMsg( i18n( _("Ready.") ) );
220 void KInterface::slotFileOpenRecent(const KURL& url)
222 slotStatusMsg(i18n(_("Opening file...")));
223 slotStatusMsg(i18n(_("Ready.")));
226 void KInterface::slotFileQuit()
228 slotStatusMsg(i18n(_("Exiting...")));
229 p_intf->p_vlc->b_die = VLC_TRUE;
230 slotStatusMsg(i18n(_("Ready.")));
233 void KInterface::slotViewToolBar()
235 slotStatusMsg(i18n(_("Toggling toolbar...")));
236 ///////////////////////////////////////////////////////////////////
237 // turn Toolbar on or off
238 if(!viewToolBar->isChecked())
240 toolBar("mainToolBar")->hide();
244 toolBar("mainToolBar")->show();
247 slotStatusMsg(i18n(_("Ready.")));
250 void KInterface::slotViewStatusBar()
252 slotStatusMsg(i18n(_("Toggle the status bar...")));
253 ///////////////////////////////////////////////////////////////////
254 //turn Statusbar on or off
255 if(!viewStatusBar->isChecked())
264 slotStatusMsg(i18n(_("Ready.")));
267 void KInterface::slotShowPreferences()
270 KPreferences(this->p_intf, "main", this, "preferences");
273 void KInterface::slotStatusMsg(const QString &text)
275 ///////////////////////////////////////////////////////////////////
276 // change status message permanently
277 statusBar()->clear();
278 statusBar()->changeItem(text, ID_STATUS_MSG);
281 void KInterface::slotManage()
283 p_messagesWindow->update();
284 // p_intf->p_sys->p_app->processEvents();
285 vlc_mutex_lock( &p_intf->change_lock );
287 /* Update the input */
288 if( p_intf->p_sys->p_input == NULL )
290 p_intf->p_sys->p_input = (input_thread_t *)
291 vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_ANYWHERE );
292 if ( p_intf->p_sys->p_input )
294 languages->setEnabled( true );
295 subtitles->setEnabled( true );
296 info->setEnabled( true );
300 else if( p_intf->p_sys->p_input->b_dead )
302 vlc_object_release( p_intf->p_sys->p_input );
303 p_intf->p_sys->p_input = NULL;
304 languages->setEnabled( false );
305 subtitles->setEnabled( false );
306 info->setEnabled( false );
309 /* If the "display popup" flag has changed */
310 if( p_intf->b_menu_change )
312 fTitleMenu->popup( ( QCursor::pos() ) );
313 p_intf->b_menu_change = 0;
316 if( p_intf->p_sys->p_input )
318 input_thread_t *p_input = p_intf->p_sys->p_input;
320 vlc_mutex_lock( &p_input->stream.stream_lock );
321 if( !p_input->b_die )
323 /* New input or stream map change */
324 if( p_input->stream.b_changed )
326 // E_(GtkModeManage)( p_intf );
327 //GtkSetupMenus( p_intf );
328 slotUpdateLanguages();
330 p_intf->p_sys->b_playing = 1;
331 p_input->stream.b_changed = 0;
334 /* Manage the slider. fSlider->setValue triggers
335 * slotSliderChanged which needs to grab the stream lock*/
336 #define p_area p_input->stream.p_selected_area
337 if( p_area->i_size ) {
338 vlc_mutex_unlock( &p_input->stream.stream_lock );
339 fSlider->setValue( ( 10000 * p_area->i_tell )
341 vlc_mutex_lock( &p_input->stream.stream_lock );
346 // if( p_intf->p_sys->i_part !=
347 // p_input->stream.p_selected_area->i_part )
349 // p_intf->p_sys->b_chapter_update = 1;
350 //GtkSetupMenus( p_intf );
353 vlc_mutex_unlock( &p_input->stream.stream_lock );
357 else if( p_intf->p_sys->b_playing && !p_intf->b_die )
359 //E_(GtkModeManage)( p_intf );
360 p_intf->p_sys->b_playing = 0;
365 p_intf->p_sys->p_app->quit();
368 vlc_mutex_unlock( &p_intf->change_lock );
373 void KInterface::slotSliderMoved( int position )
375 if( p_intf->p_sys->p_input )
377 // XXX is this locking really useful ?
378 vlc_mutex_lock( &p_intf->change_lock );
380 var_SetFloat( p_intf->p_sys->p_input, "position",
381 (double)position / 10000.0 );
382 vlc_mutex_unlock( &p_intf->change_lock );
386 void KInterface::slotUpdateLanguages()
389 es_descriptor_t * p_spu_es;
390 es_descriptor_t * p_audio_es;
391 /* look for selected ES */
395 for( unsigned int i = 0 ;
396 i < p_intf->p_sys->p_input->stream.i_selected_es_number ;
400 if( p_intf->p_sys->p_input->stream.pp_selected_es[i]->i_cat
403 p_audio_es = p_intf->p_sys->p_input->stream.pp_selected_es[i];
406 if( p_intf->p_sys->p_input->stream.pp_selected_es[i]->i_cat == SPU_ES )
408 p_spu_es = p_intf->p_sys->p_input->stream.pp_selected_es[i];
411 languages->setEnabled( false );
412 subtitles->setEnabled( false );
413 languageCollection->clear();
414 subtitleCollection->clear();
415 languages->popupMenu()->clear();
416 subtitles->popupMenu()->clear();
418 /* find audio root menu */
419 languageMenus( languages, p_audio_es, AUDIO_ES );
421 /* sub picture menus */
422 /* find spu root menu */
423 languageMenus( subtitles, p_spu_es, SPU_ES );
429 * called with stream lock
431 void KInterface::languageMenus(KActionMenu *root, es_descriptor_t *p_es,
435 if ( i_cat != AUDIO_ES )
437 KLanguageMenuAction *p_item =
438 new KLanguageMenuAction( p_intf, _( "Off" ), 0, this );
439 subtitleCollection->insert( p_item );
440 root->insert( p_item );
441 root->insert( new KActionSeparator( this ) );
442 p_item->setExclusiveGroup( QString().sprintf( "%d", i_cat ) );
443 p_item->setChecked( p_es == 0 );
446 #define ES p_intf->p_sys->p_input->stream.pp_es[i]
447 /* create a set of language buttons and append them to the container */
448 for( unsigned int i = 0 ;
449 i < p_intf->p_sys->p_input->stream.i_es_number ;
452 if( ( ES->i_cat == i_cat ) &&
455 p_intf->p_sys->p_input->stream.p_selected_program ) )
458 QString name = p_intf->p_sys->p_input->stream.pp_es[i]->psz_desc;
461 name.sprintf( "Language %d", i_item );
463 KLanguageMenuAction *p_item;
464 if ( i_cat == AUDIO_ES )
466 p_item = new KLanguageMenuAction( p_intf, name, ES,
468 languageCollection->insert(p_item);
472 p_item = new KLanguageMenuAction( p_intf, name, ES,
474 subtitleCollection->insert(p_item);
476 p_item->setExclusiveGroup( QString().sprintf( "%d", i_cat ) );
477 root->insert( p_item );
479 if( p_es == p_intf->p_sys->p_input->stream.pp_es[i] )
481 /* don't lose p_item when we append into menu */
482 //p_item_active = p_item;
483 p_item->setChecked( true );
485 connect( p_item, SIGNAL( toggled( bool, es_descriptor_t * ) ),
486 this, SLOT( slotSetLanguage( bool, es_descriptor_t * ) ));
491 root->setEnabled( true );
495 void KInterface::slotSetLanguage( bool on, es_descriptor_t *p_es )
497 input_ToggleES( p_intf->p_sys->p_input, p_es, on );
500 void KInterface::slotSliderChanged( int position )
502 if( p_intf->p_sys->p_input != NULL )
504 char psz_time[ MSTRTIME_MAX_SIZE ];
507 i_seconds = var_GetTime( p_intf->p_sys->p_input, "time" ) / I64C(1000000 );
508 secstotimestr( psz_time, i_seconds );
510 statusBar()->changeItem( psz_time, ID_DATE );
514 void KInterface::slotOpenDisk()
516 playlist_t *p_playlist;
517 int r = fDiskDialog->exec();
522 source += fDiskDialog->type();
524 source += fDiskDialog->device();
527 source += fDiskDialog->title();
529 source += fDiskDialog->chapter();
531 p_playlist = (playlist_t *)
532 vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
535 // add it to playlist
536 playlist_Add( p_playlist, source.latin1(), source.latin1(),
537 PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
538 vlc_object_release( p_playlist );
543 void KInterface::slotOpenStream()
545 playlist_t *p_playlist;
546 int r = fNetDialog->exec();
551 source += fNetDialog->protocol();
553 source += fNetDialog->server();
555 source += QString().setNum( fNetDialog->port() );
557 p_playlist = (playlist_t *)
558 vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
561 // add it to playlist
562 playlist_Add( p_playlist, source.latin1(), source.latin1(),
563 PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
564 vlc_object_release( p_playlist );
569 void KInterface::slotPlay()
571 if( p_intf->p_sys->p_input )
573 var_SetInteger( p_intf->p_sys->p_input, "state", PLAYING_S );
577 void KInterface::slotPause()
579 if ( p_intf->p_sys->p_input )
581 var_SetInteger( p_intf->p_sys->p_input, "state", PAUSE_S );
585 void KInterface::slotStop()
587 playlist_t *p_playlist = (playlist_t *)
588 vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
591 playlist_Stop( p_playlist );
592 vlc_object_release( p_playlist );
596 void KInterface::slotBackward()
598 msg_Err( p_intf, "KInterface::slotBackward() - Unimplemented" );
601 void KInterface::slotPrev()
603 playlist_t *p_playlist = (playlist_t *)
604 vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
607 playlist_Prev( p_playlist );
608 vlc_object_release( p_playlist );
612 void KInterface::slotNext()
614 playlist_t *p_playlist = (playlist_t *)
615 vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
618 playlist_Next( p_playlist );
619 vlc_object_release( p_playlist );
623 void KInterface::slotSlow()
625 if( p_intf->p_sys->p_input != NULL )
627 var_SetVoid( p_intf->p_sys->p_input, "rate-slower" );
631 void KInterface::slotFast()
633 if( p_intf->p_sys->p_input != NULL )
635 var_SetVoid( p_intf->p_sys->p_input, "rate-faster" );
639 void KInterface::dragEnterEvent( QDragEnterEvent *event )
641 event->accept( QUriDrag::canDecode( event ) );
644 void KInterface::dropEvent( QDropEvent *event )
648 playlist_t *p_playlist = (playlist_t *)
649 vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
650 if( p_playlist == NULL )
655 if ( KURLDrag::decode( event, urlList ) )
657 for ( KURL::List::ConstIterator i = urlList.begin(); i != urlList.end(); i++ )
659 // XXX add a private function to add a KURL with checking
660 // actually a whole class for core abstraction would be neat
661 if( !(*i).isEmpty() )
663 fileOpenRecent->addURL( *i );
664 playlist_Add( p_playlist, (*i).path(), (*i).path(),
665 PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
670 vlc_object_release( p_playlist );