011e2ba41ac8bbd217235d9719b37403c86fae7c
[vlc.git] / modules / gui / kde / interface.cpp
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
9 #include "disc.h"
10 #include "interface.h"
11 #include "net.h"
12 #include "menu.h"
13 #include "slider.h"
14 #include "preferences.h"
15
16 #include <iostream.h>
17
18 #include <kaction.h>
19 #include <kfiledialog.h>
20 #include <klocale.h>
21 #include <kstdaction.h>
22 #include <kurl.h>
23 #include <kurldrag.h>
24 #include <qcursor.h>
25 #include <qdragobject.h>
26 #include <qtimer.h>
27 #include <kdialog.h>
28
29 #define ID_STATUS_MSG       1
30 #define ID_DATE             2
31 #define ID_STREAM_SOURCE    3
32
33 KInterface::KInterface( intf_thread_t *p_intf, QWidget *parent,
34         const char *name ) : KMainWindow(parent,name)
35 {
36     setAcceptDrops(true);
37
38     this->p_intf = p_intf;
39
40     fDiskDialog = new KDiskDialog( this );
41     fNetDialog = new KNetDialog( this );
42     fTitleMenu = new KTitleMenu( p_intf, this );
43
44     fSlider = new KVLCSlider( QSlider::Horizontal, this );
45     fSlider->setMaxValue(10000);
46     connect( fSlider, SIGNAL( userChanged( int ) ), this, SLOT( slotSliderMoved( int ) ) );
47     connect( fSlider, SIGNAL( valueChanged( int ) ), this, SLOT( slotSliderChanged( int ) ) );
48     setCentralWidget(fSlider);
49
50     fTimer = new QTimer( this );
51     connect( fTimer, SIGNAL( timeout() ), this, SLOT( slotManage() ) );
52     fTimer->start( 100 );
53
54     resize( 400, 30 );
55
56     ///////////////////////////////////////////////////////////////////
57     // call inits to invoke all other construction parts
58     // XXX could we move this up ?
59     initStatusBar();
60     initActions();
61
62     // add certain calls to the popup menu
63     fileOpen->plug( fTitleMenu );
64     fileOpenRecent->plug( fTitleMenu );
65     diskOpen->plug( fTitleMenu );
66     streamOpen->plug( fTitleMenu );
67     play->plug( fTitleMenu );
68     pause->plug( fTitleMenu );
69     slow->plug( fTitleMenu );
70     fast->plug( fTitleMenu );
71     fileClose->plug( fTitleMenu );
72     fileQuit->plug( fTitleMenu );
73 }
74
75 KInterface::~KInterface()
76 {
77     ;
78 }
79
80 void KInterface::initActions()
81 {
82     fileOpen = KStdAction::open(this, SLOT(slotFileOpen()), actionCollection());
83     fileOpenRecent = KStdAction::openRecent(this, SLOT(slotFileOpenRecent(const KURL&)), actionCollection());
84     fileClose = KStdAction::close(this, SLOT(slotFileClose()), actionCollection());
85     preferences = KStdAction::preferences(this, SLOT(slotShowPreferences()), actionCollection());
86     fileQuit = KStdAction::quit(this, SLOT(slotFileQuit()), actionCollection());
87     viewToolBar = KStdAction::showToolbar(this, SLOT(slotViewToolBar()), actionCollection());
88     viewStatusBar = KStdAction::showStatusbar(this, SLOT(slotViewStatusBar()), actionCollection());
89
90     diskOpen = new KAction( i18n( "Open &Disk" ), 0, 0, this, SLOT( slotOpenDisk() ), actionCollection(), "open_disk" );
91     streamOpen = new KAction( i18n( "Open &Stream" ), 0, 0, this, SLOT( slotOpenStream() ), actionCollection(), "open_stream" );
92     backward = new KAction( i18n( "&Backward" ), 0, 0, this, SLOT( slotBackward() ), actionCollection(), "backward" );
93     stop = new KAction( i18n( "&Stop" ), 0, 0, this, SLOT( slotStop() ), actionCollection(), "stop" );
94     play = new KAction( i18n( "&Play" ), 0, 0, this, SLOT( slotPlay() ), actionCollection(), "play" );
95     pause = new KAction( i18n( "P&ause" ), 0, 0, this, SLOT( slotPause() ), actionCollection(), "pause" );
96     slow = new KAction( i18n( "&Slow" ), 0, 0, this, SLOT( slotSlow() ), actionCollection(), "slow" );
97     fast = new KAction( i18n( "Fas&t" ), 0, 0, this, SLOT( slotFast() ), actionCollection(), "fast" );
98     prev = new KAction( i18n( "Prev" ), 0, 0, this, SLOT( slotPrev() ), actionCollection(), "prev" );
99     next = new KAction( i18n( "Next" ), 0, 0, this, SLOT( slotNext() ), actionCollection(), "next" );
100     
101     fileOpen->setStatusText(i18n("Opens an existing document"));
102     fileOpenRecent->setStatusText(i18n("Opens a recently used file"));
103     fileClose->setStatusText(i18n("Closes the actual document"));
104     fileQuit->setStatusText(i18n("Quits the application"));
105     viewToolBar->setStatusText(i18n("Enables/disables the toolbar"));
106     viewStatusBar->setStatusText(i18n("Enables/disables the statusbar"));
107
108     diskOpen->setStatusText( i18n( "Opens a disk") );
109     streamOpen->setStatusText( i18n( "Opens a network stream" ) );
110     backward->setStatusText( i18n( "Backward" ) );
111     stop->setStatusText( i18n( "Stops playback" ) );
112     play->setStatusText( i18n( "Starts playback" ) );
113     pause->setStatusText( i18n( "Pauses playback" ) );
114     slow->setStatusText( i18n( "Slow" ) );
115     fast->setStatusText( i18n( "Fast" ) );
116     prev->setStatusText( i18n( "Prev" ) );
117     next->setStatusText( i18n( "Next" ) );
118     // use the absolute path to your ktestui.rc file for testing purpose in createGUI();
119
120     createGUI("modules/gui/kde/ui.rc");
121 }
122
123 void KInterface::initStatusBar()
124 {
125   ///////////////////////////////////////////////////////////////////
126   // STATUSBAR
127   // TODO: add your own items you need for displaying current application status.
128     statusBar()->insertItem(i18n("Ready."), ID_STATUS_MSG, 1, false);
129     statusBar()->setItemAlignment( ID_STATUS_MSG, AlignLeft | AlignVCenter );
130     statusBar()->insertItem( "0:00:00", ID_DATE, 0, true );
131 }
132
133 /////////////////////////////////////////////////////////////////////
134 // SLOT IMPLEMENTATION
135 /////////////////////////////////////////////////////////////////////
136
137 void KInterface::slotFileOpen()
138 {
139     playlist_t *p_playlist;
140
141     slotStatusMsg( i18n( "Opening file..." ) );
142     KURL url=KFileDialog::getOpenURL( QString::null,
143             i18n( "*|All files" ), this, i18n( "Open File..." ) );
144
145     if( !url.isEmpty() )
146     {
147         p_playlist = (playlist_t *)
148             vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
149         if( p_playlist )
150         {
151             fileOpenRecent->addURL( url );
152             playlist_Add( p_playlist, url.path(),
153                           PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
154             vlc_object_release( p_playlist );
155         }
156     }
157
158     slotStatusMsg( i18n( "Ready." ) );
159 }
160
161 void KInterface::slotFileOpenRecent(const KURL& url)
162 {
163   slotStatusMsg(i18n("Opening file..."));
164   slotStatusMsg(i18n("Ready."));
165 }
166
167 void KInterface::slotFileClose()
168 {
169   slotStatusMsg(i18n("Closing file..."));
170     
171   close();
172
173   slotStatusMsg(i18n("Ready."));
174 }
175
176 void KInterface::slotFileQuit()
177 {
178     slotStatusMsg(i18n("Exiting..."));
179     p_intf->p_vlc->b_die = VLC_TRUE;
180     slotStatusMsg(i18n("Ready."));
181 }
182
183 void KInterface::slotViewToolBar()
184 {
185   slotStatusMsg(i18n("Toggling toolbar..."));
186   ///////////////////////////////////////////////////////////////////
187   // turn Toolbar on or off
188   if(!viewToolBar->isChecked())
189   {
190     toolBar("mainToolBar")->hide();
191   }
192   else
193   {
194     toolBar("mainToolBar")->show();
195   }        
196
197   slotStatusMsg(i18n("Ready."));
198 }
199
200 void KInterface::slotViewStatusBar()
201 {
202   slotStatusMsg(i18n("Toggle the statusbar..."));
203   ///////////////////////////////////////////////////////////////////
204   //turn Statusbar on or off
205   if(!viewStatusBar->isChecked())
206   {
207     statusBar()->hide();
208   }
209   else
210   {
211     statusBar()->show();
212   }
213
214   slotStatusMsg(i18n("Ready."));
215 }
216
217 void KInterface::slotShowPreferences()
218 {
219     // Do something
220     KPreferences(this->p_intf, "main", this, "preferences");
221 }
222
223 void KInterface::slotStatusMsg(const QString &text)
224 {
225   ///////////////////////////////////////////////////////////////////
226   // change status message permanently
227   statusBar()->clear();
228   statusBar()->changeItem(text, ID_STATUS_MSG);
229 }
230
231 void KInterface::slotManage()
232 {
233     vlc_mutex_lock( &p_intf->change_lock );
234
235     /* Update the input */
236     if( p_intf->p_sys->p_input == NULL )
237     {
238         p_intf->p_sys->p_input = (input_thread_t *)
239                 vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_ANYWHERE );
240     }
241     else if( p_intf->p_sys->p_input->b_dead )
242     {
243         vlc_object_release( p_intf->p_sys->p_input );
244         p_intf->p_sys->p_input = NULL;
245     }
246
247     /* If the "display popup" flag has changed */
248     if( p_intf->b_menu_change )
249     {
250         fTitleMenu->popup( ( QCursor::pos() ) );
251         p_intf->b_menu_change = 0;
252     }
253
254     /* Update language/chapter menus after user request */
255 #if 0
256     if( p_intf->p_sys->p_input != NULL && p_intf->p_sys->p_window != NULL &&
257         p_intf->p_sys->b_menus_update )
258     {
259 //        GnomeSetupMenu( p_intf );
260     }
261 #endif
262
263     /* Manage the slider */
264 #define p_area p_intf->p_sys->p_input->stream.p_selected_area
265     if( p_intf->p_sys->p_input && p_area->i_size )
266     {
267         fSlider->setValue( ( 10000. * p_area->i_tell ) / p_area->i_size );
268     }
269 #undef p_area
270
271     if( p_intf->b_die )
272     {
273         p_intf->p_sys->p_app->quit();
274     }
275
276     vlc_mutex_unlock( &p_intf->change_lock );
277 }
278
279 void KInterface::slotSliderMoved( int position )
280 {
281     if( p_intf->p_sys->p_input )
282     {
283         // XXX is this locking really useful ?
284         vlc_mutex_lock( &p_intf->change_lock );
285
286         off_t i_seek = ( position * p_intf->p_sys->p_input->stream.p_selected_area->i_size ) / 10000;
287         input_Seek( p_intf->p_sys->p_input, i_seek, INPUT_SEEK_SET );
288
289         vlc_mutex_unlock( &p_intf->change_lock );
290     }
291 }
292
293 void KInterface::slotSliderChanged( int position )
294 {
295     if( p_intf->p_sys->p_input != NULL )
296     {
297         char psz_time[ OFFSETTOTIME_MAX_SIZE ];
298
299         vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
300
301 #define p_area p_intf->p_sys->p_input->stream.p_selected_area
302         statusBar()->changeItem( input_OffsetToTime( p_intf->p_sys->p_input, psz_time, ( p_area->i_size * position ) / 10000 ), ID_DATE );
303 #undef p_area
304
305         vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
306      }
307 }
308
309 void KInterface::slotOpenDisk()
310 {
311     playlist_t *p_playlist;
312     int r = fDiskDialog->exec();
313     if ( r )
314     {
315         // Build source name
316         QString source;
317         source += fDiskDialog->type();
318         source += ':';
319         source += fDiskDialog->device();
320
321         source += '@';
322         source += fDiskDialog->title();
323         source += ',';
324         source += fDiskDialog->chapter();
325
326         p_playlist = (playlist_t *)
327             vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
328         if( p_playlist )
329         {
330             // add it to playlist
331             playlist_Add( p_playlist, source.latin1(),
332                           PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
333             vlc_object_release( p_playlist );
334         }
335     }
336 }
337
338 void KInterface::slotOpenStream()
339 {
340     playlist_t *p_playlist;
341     int r = fNetDialog->exec();
342     if ( r )
343     {
344         // Build source name
345         QString source;
346         source += fNetDialog->protocol();
347         source += "://";
348         source += fNetDialog->server();
349         source += ":";
350         source += QString().setNum( fNetDialog->port() );
351
352         p_playlist = (playlist_t *)
353             vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
354         if( p_playlist )
355         {
356             // add it to playlist
357             playlist_Add( p_playlist, source.latin1(),
358                           PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
359             vlc_object_release( p_playlist );
360         }
361     }
362 }
363
364 void KInterface::slotPlay()
365 {
366     if( p_intf->p_sys->p_input )
367     {
368         input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
369     }
370 }
371
372 void KInterface::slotPause()
373 {
374     if ( p_intf->p_sys->p_input )
375     {
376         input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PAUSE );
377     }
378 }
379
380 void KInterface::slotStop()
381 {
382     playlist_t *p_playlist = (playlist_t *)
383             vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
384     if( p_playlist )
385     {
386         playlist_Stop( p_playlist );
387         vlc_object_release( p_playlist );
388     }
389 }
390
391 void KInterface::slotBackward()
392 {
393     msg_Err( p_intf, "KInterface::slotBackward() - Unimplemented" );
394 }
395
396 void KInterface::slotPrev()
397 {
398     playlist_t *p_playlist = (playlist_t *)
399             vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
400     if( p_playlist )
401     {
402         playlist_Prev( p_playlist );
403         vlc_object_release( p_playlist );
404     }
405 }
406
407 void KInterface::slotNext()
408 {
409     playlist_t *p_playlist = (playlist_t *)
410             vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
411     if( p_playlist )
412     {
413         playlist_Next( p_playlist );
414         vlc_object_release( p_playlist );
415     }
416 }
417
418 void KInterface::slotSlow()
419 {
420     if( p_intf->p_sys->p_input != NULL )
421     {
422         input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_SLOWER );
423     }
424 }
425
426 void KInterface::slotFast()
427 {
428     if( p_intf->p_sys->p_input != NULL )
429     {
430         input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_FASTER );
431     }
432 }
433
434 void KInterface::dragEnterEvent( QDragEnterEvent *event )
435 {
436     event->accept( QUriDrag::canDecode( event ) );
437 }
438
439 void KInterface::dropEvent( QDropEvent *event )
440 {
441     KURL::List urlList;
442
443     playlist_t *p_playlist = (playlist_t *)
444             vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
445     if( p_playlist == NULL )
446     {
447         return;
448     }
449
450     if ( KURLDrag::decode( event, urlList ) )
451     {
452         for ( KURL::List::ConstIterator i = urlList.begin(); i != urlList.end(); i++ )
453         {
454             // XXX add a private function to add a KURL with checking
455             // actually a whole class for core abstraction would be neat
456             if( !(*i).isEmpty() )
457             {
458                 fileOpenRecent->addURL( *i );
459                 playlist_Add( p_playlist, (*i).path(),
460                           PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
461             }
462         }
463     }
464
465     vlc_object_release( p_playlist );
466 }