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 msg_Dbg(p_intf, KStdAction::stdName(KStdAction::Preferences));
62 ///////////////////////////////////////////////////////////////////
63 // call inits to invoke all other construction parts
64 // XXX could we move this up ?
68 // add certain calls to the popup menu
69 fileOpen->plug( fTitleMenu );
70 fileOpenRecent->plug( fTitleMenu );
71 diskOpen->plug( fTitleMenu );
72 streamOpen->plug( fTitleMenu );
73 play->plug( fTitleMenu );
74 pause->plug( fTitleMenu );
75 slow->plug( fTitleMenu );
76 fast->plug( fTitleMenu );
77 fileQuit->plug( fTitleMenu );
78 fTimer->start( 0, FALSE );
82 KInterface::~KInterface()
87 void KInterface::initActions()
89 languages = new KActionMenu( _( "Languages" ), actionCollection(),
91 languages->setEnabled( false );
92 languageCollection = new KActionCollection( this );
93 subtitleCollection = new KActionCollection( this );
94 subtitles = new KActionMenu( _( "Subtitles" ), actionCollection(),
96 subtitles->setEnabled( false );
98 KStdAction::open(this, SLOT(slotFileOpen()), actionCollection());
100 KStdAction::openRecent(this, SLOT(slotFileOpenRecent(const KURL&)),
102 preferences = KStdAction::preferences(this, SLOT(slotShowPreferences()),
104 fileQuit = KStdAction::quit(this, SLOT(slotFileQuit()),
106 viewToolBar = KStdAction::showToolbar(this, SLOT(slotViewToolBar()),
108 viewStatusBar = KStdAction::showStatusbar(this, SLOT(slotViewStatusBar()),
111 diskOpen = new KAction( i18n( "Open &Disk" ), 0, 0, this,
112 SLOT( slotOpenDisk() ), actionCollection(),
114 streamOpen = new KAction( i18n( "Open &Stream" ), 0, 0, this,
115 SLOT( slotOpenStream() ), actionCollection(),
117 backward = new KAction( i18n( "&Backward" ), 0, 0, this,
118 SLOT( slotBackward() ), actionCollection(),
120 stop = new KAction( i18n( "&Stop" ), 0, 0, this,
121 SLOT( slotStop() ), actionCollection(), "stop" );
122 play = new KAction( i18n( "&Play" ), 0, 0, this,
123 SLOT( slotPlay() ), actionCollection(), "play" );
124 pause = new KAction( i18n( "P&ause" ), 0, 0, this,
125 SLOT( slotPause() ), actionCollection(), "pause" );
126 slow = new KAction( i18n( "&Slow" ), 0, 0, this,
127 SLOT( slotSlow() ), actionCollection(), "slow" );
128 fast = new KAction( i18n( "Fas&t" ), 0, 0, this,
129 SLOT( slotFast() ), actionCollection(), "fast" );
130 prev = new KAction( i18n( "Prev" ), 0, 0, this,
131 SLOT( slotPrev() ), actionCollection(), "prev" );
132 next = new KAction( i18n( "Next" ), 0, 0, this,
133 SLOT( slotNext() ), actionCollection(), "next" );
134 messages = new KAction( _( "Messages..." ), 0, 0, this,
135 SLOT( slotShowMessages() ), actionCollection(),
138 info = new KAction( _( "Stream info..." ), 0, 0, this,
139 SLOT( slotShowInfo() ), actionCollection(),
142 info->setEnabled( false );
143 program = new KActionMenu( _( "Program" ), actionCollection(), "program" );
144 program->setEnabled( false );
145 title = new KActionMenu( _( "Title" ), actionCollection(), "title" );
146 title->setEnabled( false );
147 chapter = new KActionMenu( _( "Chapter" ), actionCollection(), "chapter" );
148 chapter->setEnabled( false );
149 fileOpen->setStatusText(i18n("Opens an existing document"));
150 fileOpenRecent->setStatusText(i18n("Opens a recently used file"));
151 fileQuit->setStatusText(i18n("Quits the application"));
152 viewToolBar->setStatusText(i18n("Enables/disables the toolbar"));
153 viewStatusBar->setStatusText(i18n("Enables/disables the statusbar"));
155 diskOpen->setStatusText( i18n( "Opens a disk") );
156 streamOpen->setStatusText( i18n( "Opens a network stream" ) );
157 backward->setStatusText( i18n( "Backward" ) );
158 stop->setStatusText( i18n( "Stops playback" ) );
159 play->setStatusText( i18n( "Starts playback" ) );
160 pause->setStatusText( i18n( "Pauses playback" ) );
161 slow->setStatusText( i18n( "Slow" ) );
162 fast->setStatusText( i18n( "Fast" ) );
163 prev->setStatusText( i18n( "Prev" ) );
164 next->setStatusText( i18n( "Next" ) );
165 // use the absolute path to your ktestui.rc file for testing purpose in createGUI();
166 char *uifile = config_GetPsz( p_intf, "kdeuirc" );
168 // createGUI( "./modules/gui/kde/ui.rc" );
171 void KInterface::initStatusBar()
173 ///////////////////////////////////////////////////////////////////
175 // TODO: add your own items you need for displaying current application status.
176 statusBar()->insertItem(i18n("Ready."), ID_STATUS_MSG, 1, false);
177 statusBar()->setItemAlignment( ID_STATUS_MSG, AlignLeft | AlignVCenter );
178 statusBar()->insertItem( "0:00:00", ID_DATE, 0, true );
181 /////////////////////////////////////////////////////////////////////
182 // SLOT IMPLEMENTATION
183 /////////////////////////////////////////////////////////////////////
184 void KInterface::slotShowMessages()
186 p_messagesWindow->show();
189 void KInterface::slotShowInfo()
191 if ( p_intf->p_sys->p_input )
193 new KInfoWindow(p_intf, p_intf->p_sys->p_input);
197 void KInterface::slotFileOpen()
199 playlist_t *p_playlist;
201 slotStatusMsg( i18n( "Opening file..." ) );
202 KURL url=KFileDialog::getOpenURL( QString::null,
203 i18n( "*|All files" ), this, i18n( "Open File..." ) );
207 p_playlist = (playlist_t *)
208 vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
211 fileOpenRecent->addURL( url );
212 playlist_Add( p_playlist, url.path(),
213 PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
214 vlc_object_release( p_playlist );
218 slotStatusMsg( i18n( "Ready." ) );
221 void KInterface::slotFileOpenRecent(const KURL& url)
223 slotStatusMsg(i18n("Opening file..."));
224 slotStatusMsg(i18n("Ready."));
227 void KInterface::slotFileQuit()
229 slotStatusMsg(i18n("Exiting..."));
230 p_intf->p_vlc->b_die = VLC_TRUE;
231 slotStatusMsg(i18n("Ready."));
234 void KInterface::slotViewToolBar()
236 slotStatusMsg(i18n("Toggling toolbar..."));
237 ///////////////////////////////////////////////////////////////////
238 // turn Toolbar on or off
239 if(!viewToolBar->isChecked())
241 toolBar("mainToolBar")->hide();
245 toolBar("mainToolBar")->show();
248 slotStatusMsg(i18n("Ready."));
251 void KInterface::slotViewStatusBar()
253 slotStatusMsg(i18n("Toggle the statusbar..."));
254 ///////////////////////////////////////////////////////////////////
255 //turn Statusbar on or off
256 if(!viewStatusBar->isChecked())
265 slotStatusMsg(i18n("Ready."));
268 void KInterface::slotShowPreferences()
271 KPreferences(this->p_intf, "main", this, "preferences");
274 void KInterface::slotStatusMsg(const QString &text)
276 ///////////////////////////////////////////////////////////////////
277 // change status message permanently
278 statusBar()->clear();
279 statusBar()->changeItem(text, ID_STATUS_MSG);
282 void KInterface::slotManage()
284 p_messagesWindow->update();
285 // p_intf->p_sys->p_app->processEvents();
286 vlc_mutex_lock( &p_intf->change_lock );
288 /* Update the input */
289 if( p_intf->p_sys->p_input == NULL )
291 p_intf->p_sys->p_input = (input_thread_t *)
292 vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_ANYWHERE );
294 else if( p_intf->p_sys->p_input->b_dead )
296 vlc_object_release( p_intf->p_sys->p_input );
297 p_intf->p_sys->p_input = NULL;
298 languages->setEnabled( false );
299 subtitles->setEnabled( false );
300 info->setEnabled( false );
303 /* If the "display popup" flag has changed */
304 if( p_intf->b_menu_change )
306 fTitleMenu->popup( ( QCursor::pos() ) );
307 p_intf->b_menu_change = 0;
310 if( p_intf->p_sys->p_input )
312 input_thread_t *p_input = p_intf->p_sys->p_input;
314 vlc_mutex_lock( &p_input->stream.stream_lock );
315 if( !p_input->b_die )
317 /* New input or stream map change */
318 if( p_input->stream.b_changed )
320 // E_(GtkModeManage)( p_intf );
321 //GtkSetupMenus( p_intf );
322 slotUpdateLanguages();
324 p_intf->p_sys->b_playing = 1;
325 p_input->stream.b_changed = 0;
328 /* Manage the slider. fSlider->setValue triggers
329 * slotSliderChanged which needs to grab the stream lock*/
330 #define p_area p_input->stream.p_selected_area
331 if( p_area->i_size ) {
332 vlc_mutex_unlock( &p_input->stream.stream_lock );
333 fSlider->setValue( ( 10000 * p_area->i_tell )
335 vlc_mutex_lock( &p_input->stream.stream_lock );
340 // if( p_intf->p_sys->i_part !=
341 // p_input->stream.p_selected_area->i_part )
343 // p_intf->p_sys->b_chapter_update = 1;
344 //GtkSetupMenus( p_intf );
347 vlc_mutex_unlock( &p_input->stream.stream_lock );
351 else if( p_intf->p_sys->b_playing && !p_intf->b_die )
353 //E_(GtkModeManage)( p_intf );
354 p_intf->p_sys->b_playing = 0;
359 p_intf->p_sys->p_app->quit();
362 vlc_mutex_unlock( &p_intf->change_lock );
367 void KInterface::slotSliderMoved( int position )
369 if( p_intf->p_sys->p_input )
371 // XXX is this locking really useful ?
372 vlc_mutex_lock( &p_intf->change_lock );
374 off_t i_seek = ( position * p_intf->p_sys->p_input->stream.p_selected_area->i_size ) / 10000;
375 input_Seek( p_intf->p_sys->p_input, i_seek, INPUT_SEEK_SET );
377 vlc_mutex_unlock( &p_intf->change_lock );
381 void KInterface::slotUpdateLanguages()
384 es_descriptor_t * p_spu_es;
385 es_descriptor_t * p_audio_es;
386 /* look for selected ES */
390 for( unsigned int i = 0 ;
391 i < p_intf->p_sys->p_input->stream.i_selected_es_number ;
395 if( p_intf->p_sys->p_input->stream.pp_selected_es[i]->i_cat
398 p_audio_es = p_intf->p_sys->p_input->stream.pp_selected_es[i];
401 if( p_intf->p_sys->p_input->stream.pp_selected_es[i]->i_cat == SPU_ES )
403 p_spu_es = p_intf->p_sys->p_input->stream.pp_selected_es[i];
406 languages->setEnabled( false );
407 subtitles->setEnabled( false );
408 languageCollection->clear();
409 subtitleCollection->clear();
410 languages->popupMenu()->clear();
411 subtitles->popupMenu()->clear();
413 /* find audio root menu */
414 languageMenus( languages, p_audio_es, AUDIO_ES );
416 /* sub picture menus */
417 /* find spu root menu */
418 languageMenus( subtitles, p_spu_es, SPU_ES );
424 * called with stream lock
426 void KInterface::languageMenus(KActionMenu *root, es_descriptor_t *p_es,
430 if ( i_cat != AUDIO_ES )
432 KLanguageMenuAction *p_item =
433 new KLanguageMenuAction( p_intf, _( "Off" ), 0, this );
434 subtitleCollection->insert( p_item );
435 root->insert( p_item );
436 root->insert( new KActionSeparator( this ) );
437 p_item->setExclusiveGroup( QString().sprintf( "%d", i_cat ) );
438 p_item->setChecked( p_es == 0 );
441 #define ES p_intf->p_sys->p_input->stream.pp_es[i]
442 /* create a set of language buttons and append them to the container */
443 for( unsigned int i = 0 ;
444 i < p_intf->p_sys->p_input->stream.i_es_number ;
447 if( ( ES->i_cat == i_cat ) &&
450 p_intf->p_sys->p_input->stream.p_selected_program ) )
453 QString name = p_intf->p_sys->p_input->stream.pp_es[i]->psz_desc;
456 name.sprintf( "Language %d", i_item );
458 KLanguageMenuAction *p_item;
459 if ( i_cat == AUDIO_ES )
461 p_item = new KLanguageMenuAction( p_intf, name, ES,
463 languageCollection->insert(p_item);
467 p_item = new KLanguageMenuAction( p_intf, name, ES,
469 subtitleCollection->insert(p_item);
471 p_item->setExclusiveGroup( QString().sprintf( "%d", i_cat ) );
472 root->insert( p_item );
474 if( p_es == p_intf->p_sys->p_input->stream.pp_es[i] )
476 /* don't lose p_item when we append into menu */
477 //p_item_active = p_item;
478 p_item->setChecked( true );
480 connect( p_item, SIGNAL( toggled( bool, es_descriptor_t * ) ),
481 this, SLOT( slotSetLanguage( bool, es_descriptor_t * ) ));
486 root->setEnabled( true );
490 void KInterface::slotSetLanguage( bool on, es_descriptor_t *p_es )
492 input_ToggleES( p_intf->p_sys->p_input, p_es, on );
495 void KInterface::slotSliderChanged( int position )
497 if( p_intf->p_sys->p_input != NULL )
499 char psz_time[ OFFSETTOTIME_MAX_SIZE ];
501 vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
503 #define p_area p_intf->p_sys->p_input->stream.p_selected_area
504 statusBar()->changeItem( input_OffsetToTime( p_intf->p_sys->p_input, psz_time, ( p_area->i_size * position ) / 10000 ), ID_DATE );
507 vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
511 void KInterface::slotOpenDisk()
513 playlist_t *p_playlist;
514 int r = fDiskDialog->exec();
519 source += fDiskDialog->type();
521 source += fDiskDialog->device();
524 source += fDiskDialog->title();
526 source += fDiskDialog->chapter();
528 p_playlist = (playlist_t *)
529 vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
532 // add it to playlist
533 playlist_Add( p_playlist, source.latin1(),
534 PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
535 vlc_object_release( p_playlist );
540 void KInterface::slotOpenStream()
542 playlist_t *p_playlist;
543 int r = fNetDialog->exec();
548 source += fNetDialog->protocol();
550 source += fNetDialog->server();
552 source += QString().setNum( fNetDialog->port() );
554 p_playlist = (playlist_t *)
555 vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
558 // add it to playlist
559 playlist_Add( p_playlist, source.latin1(),
560 PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
561 vlc_object_release( p_playlist );
566 void KInterface::slotPlay()
568 if( p_intf->p_sys->p_input )
570 input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
574 void KInterface::slotPause()
576 if ( p_intf->p_sys->p_input )
578 input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PAUSE );
582 void KInterface::slotStop()
584 playlist_t *p_playlist = (playlist_t *)
585 vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
588 playlist_Stop( p_playlist );
589 vlc_object_release( p_playlist );
593 void KInterface::slotBackward()
595 msg_Err( p_intf, "KInterface::slotBackward() - Unimplemented" );
598 void KInterface::slotPrev()
600 playlist_t *p_playlist = (playlist_t *)
601 vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
604 playlist_Prev( p_playlist );
605 vlc_object_release( p_playlist );
609 void KInterface::slotNext()
611 playlist_t *p_playlist = (playlist_t *)
612 vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
615 playlist_Next( p_playlist );
616 vlc_object_release( p_playlist );
620 void KInterface::slotSlow()
622 if( p_intf->p_sys->p_input != NULL )
624 input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_SLOWER );
628 void KInterface::slotFast()
630 if( p_intf->p_sys->p_input != NULL )
632 input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_FASTER );
636 void KInterface::dragEnterEvent( QDragEnterEvent *event )
638 event->accept( QUriDrag::canDecode( event ) );
641 void KInterface::dropEvent( QDropEvent *event )
645 playlist_t *p_playlist = (playlist_t *)
646 vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
647 if( p_playlist == NULL )
652 if ( KURLDrag::decode( event, urlList ) )
654 for ( KURL::List::ConstIterator i = urlList.begin(); i != urlList.end(); i++ )
656 // XXX add a private function to add a KURL with checking
657 // actually a whole class for core abstraction would be neat
658 if( !(*i).isEmpty() )
660 fileOpenRecent->addURL( *i );
661 playlist_Add( p_playlist, (*i).path(),
662 PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
667 vlc_object_release( p_playlist );