main_interface.cpp 28.7 KB
Newer Older
zorglub's avatar
zorglub committed
1
/*****************************************************************************
zorglub's avatar
Wtf ?    
zorglub committed
2
 * main_interface.cpp : Main interface
zorglub's avatar
zorglub committed
3
 ****************************************************************************
4
 * Copyright (C) 2006-2007 the VideoLAN team
5
 * $Id$
zorglub's avatar
zorglub committed
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 *
 * Authors: Clément Stenac <zorglub@videolan.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
21
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22
 *****************************************************************************/
zorglub's avatar
zorglub committed
23

24
#include "qt4.hpp"
zorglub's avatar
zorglub committed
25
#include "main_interface.hpp"
zorglub's avatar
zorglub committed
26
#include "input_manager.hpp"
27
#include "util/input_slider.hpp"
zorglub's avatar
zorglub committed
28
#include "util/qvlcframe.hpp"
29
#include "util/customwidgets.hpp"
zorglub's avatar
zorglub committed
30
#include "dialogs_provider.hpp"
31
#include "components/interface_widgets.hpp"
32
33
34
#include "dialogs/playlist.hpp"
#include "menus.hpp"

zorglub's avatar
zorglub committed
35
#include <QMenuBar>
zorglub's avatar
zorglub committed
36
#include <QCloseEvent>
zorglub's avatar
zorglub committed
37
#include <QPushButton>
zorglub's avatar
zorglub committed
38
#include <QStatusBar>
39
#include <QKeyEvent>
zorglub's avatar
zorglub committed
40
#include <QUrl>
41
#include <QSystemTrayIcon>
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
42
43
#include <QSize>
#include <QMenu>
44
45

#include <assert.h>
46
#include <vlc_keys.h>
zorglub's avatar
zorglub committed
47
#include <vlc_vout.h>
zorglub's avatar
zorglub committed
48

zorglub's avatar
zorglub committed
49
#ifdef WIN32
zorglub's avatar
zorglub committed
50
    #define PREF_W 410
zorglub's avatar
zorglub committed
51
52
    #define PREF_H 121
#else
zorglub's avatar
zorglub committed
53
    #define PREF_W 450
zorglub's avatar
zorglub committed
54
55
    #define PREF_H 125
#endif
zorglub's avatar
zorglub committed
56

57
58
59
60
61
62
63
64
#define VISIBLE(i) (i && i->isVisible())

#define SET_WIDTH(i,j) i->widgetSize.setWidth(j)
#define SET_HEIGHT(i,j) i->widgetSize.setHeight(j)
#define SET_WH( i,j,k) i->widgetSize.setWidth(j); i->widgetSize.setHeight(k);

#define DS(i) i.width(),i.height()

65
66
67
68
69
/* Callback prototypes */
static int PopupMenuCB( vlc_object_t *p_this, const char *psz_variable,
                        vlc_value_t old_val, vlc_value_t new_val, void *param );
static int IntfShowCB( vlc_object_t *p_this, const char *psz_variable,
                       vlc_value_t old_val, vlc_value_t new_val, void *param );
zorglub's avatar
zorglub committed
70
71
static int InteractCallback( vlc_object_t *, const char *, vlc_value_t,
                             vlc_value_t, void *);
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/* Video handling */
static void *DoRequest( intf_thread_t *p_intf, vout_thread_t *p_vout,
                        int *pi1, int *pi2, unsigned int*pi3,unsigned int*pi4)
{
    return p_intf->p_sys->p_mi->requestVideo( p_vout, pi1, pi2, pi3, pi4 );
}
static void DoRelease( intf_thread_t *p_intf, void *p_win )
{
    return p_intf->p_sys->p_mi->releaseVideo( p_win );
}
static int DoControl( intf_thread_t *p_intf, void *p_win, int i_q, va_list a )
{
    return p_intf->p_sys->p_mi->controlVideo( p_win, i_q, a );
}
zorglub's avatar
zorglub committed
86

zorglub's avatar
zorglub committed
87
MainInterface::MainInterface( intf_thread_t *_p_intf ) : QVLCMW( _p_intf )
zorglub's avatar
zorglub committed
88
{
89
    /* Configuration */
90
91
92
    settings = new QSettings( "VideoLAN", "VLC" );
    settings->beginGroup( "MainWindow" );

93
94
    setWindowIcon( QApplication::windowIcon() );

95
    need_components_update = false;
96
    bgWidget = NULL; videoWidget = NULL; playlistWidget = NULL;
zorglub's avatar
zorglub committed
97
    embeddedPlaylistWasActive = videoIsActive = false;
98

99
    input_name = "";
100

zorglub's avatar
zorglub committed
101
    videoEmbeddedFlag = false;
102
    if( config_GetInt( p_intf, "embedded-video" ) ) videoEmbeddedFlag = true;
zorglub's avatar
zorglub committed
103
104
105
106
107

    alwaysVideoFlag = false;
    if( videoEmbeddedFlag && config_GetInt( p_intf, "qt-always-video" ))
        alwaysVideoFlag = true;

108
    playlistEmbeddedFlag = settings->value("playlist-embedded", true).toBool();
zorglub's avatar
zorglub committed
109
    advControlsEnabled= settings->value( "adv-controls", false ).toBool();
110
    visualSelectorEnabled= settings->value( "visual-selector", false ).toBool();
zorglub's avatar
zorglub committed
111

112
    /* UI */
113
    setVLCWindowsTitle();
114
    handleMainUi( settings );
zorglub's avatar
zorglub committed
115
    QVLCMenu::createMenuBar( this, p_intf, playlistEmbeddedFlag,
116
                             advControlsEnabled, visualSelectorEnabled );
117
118
119
120
    timeLabel = new QLabel( 0 );
    nameLabel = new QLabel( 0 );
    statusBar()->addWidget( nameLabel, 4 );
    statusBar()->addPermanentWidget( timeLabel, 1 );
zorglub's avatar
Icons    
zorglub committed
121

122
    setFocusPolicy( Qt::StrongFocus );
123
    setAcceptDrops(true);
124

125
126
127
128
129
130
131
132
133
134
135
136
    /* Systray */
    systray = NULL;
    if( QSystemTrayIcon::isSystemTrayAvailable() &&
                  ( config_GetInt( p_intf, "qt-start-mininimized") == 1) )
    {
        hide();
        createSystrayMenu();
    }
    if( QSystemTrayIcon::isSystemTrayAvailable() &&
                  ( config_GetInt( p_intf, "qt-system-tray") == 1) )
            createSystrayMenu();

137
138
139
140
141
142
    /* Init input manager */
    MainInputManager::getInstance( p_intf );
    ON_TIMEOUT( updateOnTimer() );

    /* Volume control */
    CONNECT( ui.volumeSlider, valueChanged(int), this, updateVolume(int) );
143

144
145
146
147
148
    /* Connect the input manager to the GUI elements it manages */
    CONNECT( THEMIM->getIM(), positionUpdated( float, int, int ),
             slider, setPosition( float,int, int ) );
    CONNECT( THEMIM->getIM(), positionUpdated( float, int, int ),
             this, setDisplay( float, int, int ) );
149
150

    /* Naming in the controller */
151
152
    CONNECT( THEMIM->getIM(), nameChanged( QString ), this,
             setName( QString ) );
153
    if( config_GetInt( p_intf, "qt-system-tray" ) && systray )
154
155
    {
        CONNECT( THEMIM->getIM(), nameChanged( QString ), this,
156
                 updateSystrayTooltipName( QString ) );
157
    }
158
159
160
161
162
163
164
    if( config_GetInt( p_intf, "qt-name-in-title" ) )
    {
        CONNECT( THEMIM->getIM(), nameChanged( QString ), this,
             setVLCWindowsTitle( QString ) );
    }

    /* PLAY_STATUS */
165
    CONNECT( THEMIM->getIM(), statusChanged( int ), this, setStatus( int ) );
166
    CONNECT( THEMIM->getIM(), navigationChanged( int ),
167
             this, setNavigation(int) );
168
    if( config_GetInt( p_intf, "qt-system-tray" ) && systray )
169
170
    {
        CONNECT( THEMIM->getIM(), statusChanged( int ), this,
171
                 updateSystrayTooltipStatus( int ) );
172
    }
173
174
175
    CONNECT( slider, sliderDragged( float ),
             THEMIM->getIM(), sliderUpdate( float ) );

176
    /* Buttons */
177
178
179
180
181
182
183
    CONNECT( ui.prevSectionButton, clicked(), THEMIM->getIM(),
             sectionPrev() );
    CONNECT( ui.nextSectionButton, clicked(), THEMIM->getIM(),
             sectionNext() );
    CONNECT( ui.menuButton, clicked(), THEMIM->getIM(),
             sectionMenu() );

184
185
186
    var_Create( p_intf, "interaction", VLC_VAR_ADDRESS );
    var_AddCallback( p_intf, "interaction", InteractCallback, this );
    p_intf->b_interaction = VLC_TRUE;
187
188

    /* Register callback for the intf-popupmenu variable */
189
190
    playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_intf,
                                        VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
191
192
193
194
195
196
    if( p_playlist != NULL )
    {
        var_AddCallback( p_playlist, "intf-popupmenu", PopupMenuCB, p_intf );
        var_AddCallback( p_playlist, "intf-show", IntfShowCB, p_intf );
        vlc_object_release( p_playlist );
    }
197

198
199
200
201
}

MainInterface::~MainInterface()
{
202
    /* Unregister callback for the intf-popupmenu variable */
203
204
    playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_intf,
                                        VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
205
206
207
208
209
210
211
    if( p_playlist != NULL )
    {
        var_DelCallback( p_playlist, "intf-popupmenu", PopupMenuCB, p_intf );
        var_DelCallback( p_playlist, "intf-show", IntfShowCB, p_intf );
        vlc_object_release( p_playlist );
    }

zorglub's avatar
zorglub committed
212
213
214
215
216
    settings->setValue( "playlist-embedded", playlistEmbeddedFlag );
    settings->setValue( "adv-controls", advControlsEnabled );
    settings->setValue( "pos", pos() );
    settings->endGroup();
    delete settings;
217
218
    p_intf->b_interaction = VLC_FALSE;
    var_DelCallback( p_intf, "interaction", InteractCallback, this );
219
220
221
222

    p_intf->pf_request_window = NULL;
    p_intf->pf_release_window = NULL;
    p_intf->pf_control_window = NULL;
223
224
}

225
226
227
/*****************************
 *   Main UI handling        *
 *****************************/
228
229
230
231
232
233
234
235
236
237
238
239
void MainInterface::setVLCWindowsTitle( QString aTitle )
{
    if( aTitle.isEmpty() )
    {
        this->setWindowTitle( qtr( "VLC media player" ) );
    }
    else
    {
        this->setWindowTitle( aTitle + " - " + qtr( "VLC media player" ) );
    }
}

240
241
242
243
244
245
void MainInterface::handleMainUi( QSettings *settings )
{
    QWidget *main = new QWidget( this );
    setCentralWidget( main );
    ui.setupUi( centralWidget() );

zorglub's avatar
zorglub committed
246
    slider = new InputSlider( Qt::Horizontal, NULL );
247
    ui.vboxLayout->insertWidget( 0, slider );
248
249
250
251
    ui.discFrame->hide();
    BUTTON_SET_IMG( ui.prevSectionButton, "", previous.png, "" );
    BUTTON_SET_IMG( ui.nextSectionButton, "", next.png, "" );
    BUTTON_SET_IMG( ui.menuButton, "", previous.png, "" );
252

zorglub's avatar
zorglub committed
253
254
255
256
257
    BUTTON_SET_ACT_I( ui.prevButton, "" , previous.png,
                      qtr("Previous"), prev() );
    BUTTON_SET_ACT_I( ui.nextButton, "", next.png, qtr("Next"), next() );
    BUTTON_SET_ACT_I( ui.playButton, "", play.png, qtr("Play"), play() );
    BUTTON_SET_ACT_I( ui.stopButton, "", stop.png, qtr("Stop"), stop() );
258
259

    /* Volume */
260
    ui.volMuteLabel->setPixmap( QPixmap( ":/pixmaps/volume-low.png" ) );
zorglub's avatar
zorglub committed
261
    ui.volumeSlider->setMaximum( 100 );
262
263
264
    ui.volMuteLabel->setToolTip( qtr( "Mute" ) );
    VolumeClickHandler *h = new VolumeClickHandler( p_intf, this );
    ui.volMuteLabel->installEventFilter(h);
zorglub's avatar
zorglub committed
265
266
    ui.volumeSlider->setFocusPolicy( Qt::NoFocus );

267
    BUTTON_SET_IMG( ui.playlistButton, "" , playlist_icon.png,
zorglub's avatar
zorglub committed
268
                        playlistEmbeddedFlag ?  qtr( "Show playlist" ) :
zorglub's avatar
Cleanup    
zorglub committed
269
                                                qtr( "Open playlist" ) );
270
    BUTTONACT( ui.playlistButton, playlist() );
zorglub's avatar
zorglub committed
271

zorglub's avatar
zorglub committed
272
    /* Set initial size */
zorglub's avatar
zorglub committed
273
    resize ( PREF_W, PREF_H );
274

275
    addSize = QSize( ui.vboxLayout->margin() * 2, PREF_H );
276

zorglub's avatar
zorglub committed
277
278
279
280
281
282
    advControls = new ControlsWidget( p_intf );
    ui.vboxLayout->insertWidget( 0, advControls );
    advControls->updateGeometry();
    if( !advControlsEnabled ) advControls->hide();
    need_components_update = true;

283
284
285
286
287
288
289
290
291
292
293
294
295
296
    visualSelector = new VisualSelector( p_intf );
    ui.vboxLayout->insertWidget( 0, visualSelector );
    visualSelector->hide();

    if( alwaysVideoFlag )
    {
        bgWidget = new BackgroundWidget( p_intf );
        bgWidget->widgetSize = settings->value( "backgroundSize",
                                                QSize( 200, 200 ) ).toSize();
        bgWidget->resize( bgWidget->widgetSize );
        bgWidget->updateGeometry();
        ui.vboxLayout->insertWidget( 0, bgWidget );
    }

297
    if( videoEmbeddedFlag )
298
    {
299
        videoWidget = new VideoWidget( p_intf );
300
        videoWidget->widgetSize = QSize( 1, 1 );
301
        //videoWidget->resize( videoWidget->widgetSize );
302
303
        ui.vboxLayout->insertWidget( 0, videoWidget );

304
305
306
        p_intf->pf_request_window  = ::DoRequest;
        p_intf->pf_release_window  = ::DoRelease;
        p_intf->pf_control_window  = ::DoControl;
307
    }
zorglub's avatar
zorglub committed
308
    setMinimumSize( PREF_W, addSize.height() );
zorglub's avatar
zorglub committed
309
310
}

311
312
313
314
/*****************************************************************************
 * Systray Icon and Systray Menu
 *****************************************************************************/

315
316
317
318
319
/**
 * Create a SystemTray icon and a menu that would go with it.
 * Connects to a click handler on the icon.
 **/
void MainInterface::createSystray()
320
{
321
    QIcon iconVLC =  QIcon( QPixmap( ":/vlc128.png" ) );
322
    sysTray = new QSystemTrayIcon( iconVLC, this );
323
324
    sysTray->setToolTip( qtr( "VLC media player" ));

325
    systrayMenu = new QMenu( qtr( "VLC media player" ), this );
326
    systrayMenu->setIcon( iconVLC );
327

328
    QVLCMenu::updateSystrayMenu( this, p_intf, true );
329
    sysTray->show();
330

331
332
    CONNECT( sysTray, activated(  QSystemTrayIcon::ActivationReason ),
            this, handleSystrayClick( QSystemTrayIcon::ActivationReason ) );
333
334
}

335
336
337
/**
 * Update the menu of the Systray Icon.
 * May be unneedded, since it just calls QVLCMenu::update
338
 * FIXME !!!
339
 **/
340
341
342
343
344
void MainInterface::updateSystrayMenu( int status )
{
    QVLCMenu::updateSystrayMenu( this, p_intf ) ;
}

345
346
347
/**
 * Updates the Systray Icon's menu and toggle the main interface
 */
348
349
350
void MainInterface::toggleUpdateSystrayMenu()
{
    toggleVisible();
351
    QVLCMenu::updateSystrayMenu( this, p_intf );
352
353
}

354
355
void MainInterface::handleSystrayClick(
                                    QSystemTrayIcon::ActivationReason reason )
356
357
358
359
{
    switch( reason )
    {
        case QSystemTrayIcon::Trigger:
360
361
            toggleUpdateSystrayMenu();
            break;
362
363
        case QSystemTrayIcon::MiddleClick:
            sysTray->showMessage( qtr( "VLC media player" ),
364
                    qtr( "Control menu for the player" ),
365
366
367
368
369
                    QSystemTrayIcon::Information, 4000 );
            break;
    }
}

370
371
372
/**
 * Updates the name of the systray Icon tooltip.
 * Doesn't check if the systray exists, check before you call it.
373
 * FIXME !!! Fusion with next function ?
374
 **/
375
376
377
378
379
380
381
382
383
384
385
386
void MainInterface::updateSystrayTooltipName( QString name )
{
    if( name.isEmpty() )
    {
        sysTray->setToolTip( qtr( "VLC media player" ) );
    }
    else
    {
        sysTray->setToolTip( name );
    }
}

387
388
389
390
/**
 * Updates the status of the systray Icon tooltip.
 * Doesn't check if the systray exists, check before you call it.
 **/
391
392
393
void MainInterface::updateSystrayTooltipStatus( int i_status )
{
    switch( i_status )
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
    {
        case  0:
            {
                sysTray->setToolTip( qtr( "VLC media player" ) );
                break;
            }
        case PLAYING_S:
            {
                sysTray->setToolTip( input_name );
                //+ " - " + qtr( "Playing" ) );
                break;
            }
        case PAUSE_S:
            {
                sysTray->setToolTip( input_name + " - "
                        + qtr( "Paused") );
                break;
            }
    }
413
}
414

415
416
417
/**********************************************************************
 * Handling of the components
 **********************************************************************/
418
void MainInterface::calculateInterfaceSize()
zorglub's avatar
zorglub committed
419
{
420
    int width = 0, height = 0;
421
    if( VISIBLE( bgWidget ) )
zorglub's avatar
zorglub committed
422
    {
423
424
        width = bgWidget->widgetSize.width();
        height = bgWidget->widgetSize.height();
zorglub's avatar
zorglub committed
425
        assert( !(playlistWidget && playlistWidget->isVisible() ) );
zorglub's avatar
zorglub committed
426
    }
427
    else if( VISIBLE( playlistWidget ) )
428
    {
429
430
        width = playlistWidget->widgetSize.width();
        height = playlistWidget->widgetSize.height();
431
    }
432
433
434
435
436
    else if( videoIsActive )
    {
        width =  videoWidget->widgetSize.width() ;
        height = videoWidget->widgetSize.height();
    }
zorglub's avatar
Cleanup    
zorglub committed
437
438
439
440
441
    else
    {
        width = PREF_W - addSize.width();
        height = PREF_H - addSize.height();
    }
442
443
    if( VISIBLE( visualSelector ) )
        height += visualSelector->height();
zorglub's avatar
zorglub committed
444
445
446
447
    if( VISIBLE( advControls) )
    {
        height += advControls->sizeHint().height();
    }
448
    mainSize = QSize( width + addSize.width(), height + addSize.height() );
zorglub's avatar
zorglub committed
449
}
zorglub's avatar
zorglub committed
450

zorglub's avatar
zorglub committed
451
void MainInterface::resizeEvent( QResizeEvent *e )
452
{
453
454
    videoWidget->widgetSize.setWidth(  e->size().width() - addSize.width() );
    if( videoWidget && videoIsActive && videoWidget->widgetSize.height() > 1 )
455
    {
456
457
458
        SET_WH( videoWidget, e->size().width() - addSize.width(),
                             e->size().height()  - addSize.height() );
        videoWidget->updateGeometry();
459
    }
460
    if( VISIBLE( playlistWidget ) )
461
    {
462
463
464
        SET_WH( playlistWidget , e->size().width() - addSize.width(),
                                 e->size().height() - addSize.height() );
        playlistWidget->updateGeometry();
465
    }
466
467
}

468
469
470
471
472
void *MainInterface::requestVideo( vout_thread_t *p_nvout, int *pi_x,
                                   int *pi_y, unsigned int *pi_width,
                                   unsigned int *pi_height )
{
    void *ret = videoWidget->request( p_nvout,pi_x, pi_y, pi_width, pi_height );
473
474
475
    if( ret )
    {
        videoIsActive = true;
476
        if( VISIBLE( playlistWidget ) )
477
478
        {
            embeddedPlaylistWasActive = true;
479
//            playlistWidget->hide();
480
        }
481
482
        bool bgWasVisible = false;
        if( VISIBLE( bgWidget) )
zorglub's avatar
zorglub committed
483
        {
484
            bgWasVisible = true;
485
//            bgWidget->hide();
zorglub's avatar
zorglub committed
486
        }
487
488
489
490
491
492
493
494
495
496
497
        if( THEMIM->getIM()->hasVideo() || !bgWasVisible )
        {
            videoWidget->widgetSize = QSize( *pi_width, *pi_height );
        }
        else /* Background widget available, use its size */
        {
            /* Ok, our visualizations are bad, so don't do this for the moment
             * use the requested size anyway */
            // videoWidget->widgetSize = bgWidget->widgeTSize;
            videoWidget->widgetSize = QSize( *pi_width, *pi_height );
        }
498
//        videoWidget->updateGeometry(); /// FIXME: Needed ?
499
500
        need_components_update = true;
    }
501
502
503
504
505
506
    return ret;
}

void MainInterface::releaseVideo( void *p_win )
{
    videoWidget->release( p_win );
507
508
    videoWidget->widgetSize = QSize( 0, 0 );
    videoWidget->resize( videoWidget->widgetSize );
zorglub's avatar
zorglub committed
509

510
    if( embeddedPlaylistWasActive )
511
        ;//playlistWidget->show();
zorglub's avatar
zorglub committed
512
    else if( bgWidget )
513
        ;//bgWidget->show();
zorglub's avatar
zorglub committed
514

515
    videoIsActive = false;
516
    need_components_update = true;
517
518
}

519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
class SetVideoOnTopQtEvent : public QEvent
{
public:
    SetVideoOnTopQtEvent( bool _onTop ) :
      QEvent( (QEvent::Type)SetVideoOnTopEvent_Type ), onTop( _onTop)
    {
    }

    bool OnTop() const
    {
        return onTop;
    }

private:
    bool onTop;
};

536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
int MainInterface::controlVideo( void *p_window, int i_query, va_list args )
{
    int i_ret = VLC_EGENERIC;
    switch( i_query )
    {
        case VOUT_GET_SIZE:
        {
            unsigned int *pi_width  = va_arg( args, unsigned int * );
            unsigned int *pi_height = va_arg( args, unsigned int * );
            *pi_width = videoWidget->widgetSize.width();
            *pi_height = videoWidget->widgetSize.height();
            i_ret = VLC_SUCCESS;
            break;
        }
        case VOUT_SET_SIZE:
        {
            unsigned int i_width  = va_arg( args, unsigned int );
            unsigned int i_height = va_arg( args, unsigned int );
            videoWidget->widgetSize = QSize( i_width, i_height );
555
            // videoWidget->updateGeometry();
556
557
558
559
560
            need_components_update = true;
            i_ret = VLC_SUCCESS;
            break;
        }
        case VOUT_SET_STAY_ON_TOP:
561
562
563
564
565
566
        {
            int i_arg = va_arg( args, int );
            QApplication::postEvent( this, new SetVideoOnTopQtEvent( i_arg ) );
            i_ret = VLC_SUCCESS;
            break;
        }
567
568
569
570
571
572
573
        default:
            msg_Warn( p_intf, "unsupported control query" );
            break;
    }
    return i_ret;
}

zorglub's avatar
zorglub committed
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
void MainInterface::advanced()
{
    if( !VISIBLE( advControls ) )
    {
        advControls->show();
        advControlsEnabled = true;
    }
    else
    {
        advControls->hide();
        advControlsEnabled = false;
    }
    doComponentsUpdate();
}

589
590
591
592
593
594
595
596
597
void MainInterface::visual()
{
    if( !VISIBLE( visualSelector) )
    {
        visualSelector->show();
        if( !THEMIM->getIM()->hasVideo() )
        {
            /* Show the background widget */
        }
598
        visualSelectorEnabled = true;
599
600
601
602
603
    }
    else
    {
        /* Stop any currently running visualization */
        visualSelector->hide();
604
        visualSelectorEnabled = false;
605
    }
606
    doComponentsUpdate();
607
608
}

609
610
611
612
613
614
615
void MainInterface::playlist()
{
    // Toggle the playlist dialog
    if( !playlistEmbeddedFlag )
    {
        if( playlistWidget )
        {
616
            /// \todo Destroy it
617
618
619
620
621
622
623
624
625
626
627
        }
        THEDP->playlistDialog();
        return;
    }

    if( !playlistWidget )
    {
        PlaylistDialog::killInstance();
        playlistWidget = new PlaylistWidget( p_intf );
        ui.vboxLayout->insertWidget( 0, playlistWidget );
        playlistWidget->widgetSize = settings->value( "playlistSize",
zorglub's avatar
zorglub committed
628
                                               QSize( 650, 310 ) ).toSize();
629
        playlistWidget->hide();
630
    }
631
    if( VISIBLE( playlistWidget ) )
632
633
634
635
    {
        playlistWidget->hide();
        if( videoIsActive )
        {
636
637
638
            videoWidget->widgetSize = savedVideoSize;
            videoWidget->resize( videoWidget->widgetSize );
            videoWidget->updateGeometry();
639
640
641
642
643
644
        }
    }
    else
    {
        playlistWidget->show();
        if( videoIsActive )
645
646
647
648
649
650
        {
            savedVideoSize = videoWidget->widgetSize;
            videoWidget->widgetSize.setHeight( 0 );
            videoWidget->resize( videoWidget->widgetSize );
            videoWidget->updateGeometry();
        }
651
        if( VISIBLE( bgWidget ) ) bgWidget->hide();
652
    }
653
    doComponentsUpdate();
654
655
}

zorglub's avatar
zorglub committed
656
657
/* Video widget cannot do this synchronously as it runs in another thread */
/* Well, could it, actually ? Probably dangerous ... */
658
659
void MainInterface::doComponentsUpdate()
{
660
661
    calculateInterfaceSize();
    resize( mainSize );
662
663
}

zorglub's avatar
zorglub committed
664
void MainInterface::undockPlaylist()
665
{
zorglub's avatar
zorglub committed
666
    if( playlistWidget )
667
    {
zorglub's avatar
zorglub committed
668
669
        playlistWidget->hide();
        playlistWidget->deleteLater();
670
671
672
        ui.vboxLayout->removeWidget( playlistWidget );
        playlistWidget = NULL;
        playlistEmbeddedFlag = false;
zorglub's avatar
zorglub committed
673

zorglub's avatar
zorglub committed
674
        menuBar()->clear();
675
676
        QVLCMenu::createMenuBar( this, p_intf, false, advControlsEnabled,
                                 visualSelectorEnabled);
zorglub's avatar
zorglub committed
677
678
679
680
681
682
683
684
685
686

        if( videoIsActive )
        {
            videoWidget->widgetSize = savedVideoSize;
            videoWidget->resize( videoWidget->widgetSize );
            videoWidget->updateGeometry();
        }

        doComponentsUpdate();
        THEDP->playlistDialog();
687
    }
zorglub's avatar
zorglub committed
688
689
690
691
692
}

void MainInterface::customEvent( QEvent *event )
{
    if( event->type() == PLDockEvent_Type )
693
694
695
    {
        PlaylistDialog::killInstance();
        playlistEmbeddedFlag = true;
zorglub's avatar
zorglub committed
696
        menuBar()->clear();
697
698
        QVLCMenu::createMenuBar(this, p_intf, true, advControlsEnabled,
                                visualSelectorEnabled);
699
700
        playlist();
    }
701
702
703
704
705
706
    else if ( event->type() == SetVideoOnTopEvent_Type )
    {
        SetVideoOnTopQtEvent* p_event = (SetVideoOnTopQtEvent*)event;
        if( p_event->OnTop() )
            setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
        else
707
            setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint);
708
709
        show(); /* necessary to apply window flags?? */
    }
710
711
}

712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737

/************************************************************************
 * D&D
 ************************************************************************/
void MainInterface::dropEvent(QDropEvent *event)
{
     const QMimeData *mimeData = event->mimeData();

     /* D&D of a subtitles file, add it on the fly */
     if( mimeData->urls().size() == 1 )
     {
        if( THEMIM->getIM()->hasInput() )
        {
            if( input_AddSubtitles( THEMIM->getInput(),
                                    qtu( mimeData->urls()[0].toString() ),
                                    VLC_TRUE ) )
            {
                event->acceptProposedAction();
                return;
            }
        }
     }
     bool first = true;
     foreach( QUrl url, mimeData->urls() ) {
        QString s = url.toString();
        if( s.length() > 0 ) {
738
739
            playlist_Add( THEPL, qtu(s), NULL,
                          PLAYLIST_APPEND | (first ? PLAYLIST_GO:0),
740
                          PLAYLIST_END, VLC_TRUE, VLC_FALSE );
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
            first = false;
        }
     }
     event->acceptProposedAction();
}
void MainInterface::dragEnterEvent(QDragEnterEvent *event)
{
     event->acceptProposedAction();
}
void MainInterface::dragMoveEvent(QDragMoveEvent *event)
{
     event->acceptProposedAction();
}
void MainInterface::dragLeaveEvent(QDragLeaveEvent *event)
{
     event->accept();
}

759
760
761
/************************************************************************
 * Other stuff
 ************************************************************************/
762
763
void MainInterface::keyPressEvent( QKeyEvent *e )
{
764
    int i_vlck = qtEventToVLCKey( e );
765
766
    if( i_vlck >= 0 )
    {
767
        var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlck );
768
769
770
771
772
773
        e->accept();
    }
    else
        e->ignore();
}

774
775
void MainInterface::wheelEvent( QWheelEvent *e )
{
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
776
    int i_vlckey = qtWheelEventToVLCKey( e );
777
778
779
780
    var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlckey );
    e->accept();
}

zorglub's avatar
zorglub committed
781
782
void MainInterface::stop()
{
783
    THEMIM->stop();
zorglub's avatar
zorglub committed
784
}
785

zorglub's avatar
zorglub committed
786
787
void MainInterface::play()
{
zorglub's avatar
zorglub committed
788
    if( playlist_IsEmpty(THEPL) )
789
790
    {
        /* The playlist is empty, open a file requester */
zorglub's avatar
Wtf ?    
zorglub committed
791
        THEDP->openFileDialog();
792
793
794
795
        setStatus( 0 );
        return;
    }
    THEMIM->togglePlayPause();
zorglub's avatar
zorglub committed
796
}
797

zorglub's avatar
zorglub committed
798
799
void MainInterface::prev()
{
800
    THEMIM->prev();
zorglub's avatar
zorglub committed
801
}
802

zorglub's avatar
zorglub committed
803
804
void MainInterface::next()
{
805
    THEMIM->next();
zorglub's avatar
zorglub committed
806
807
808
809
810
811
812
813
814
}

void MainInterface::setDisplay( float pos, int time, int length )
{
    char psz_length[MSTRTIME_MAX_SIZE], psz_time[MSTRTIME_MAX_SIZE];
    secstotimestr( psz_length, length );
    secstotimestr( psz_time, time );
    QString title;
    title.sprintf( "%s/%s", psz_time, psz_length );
815
    timeLabel->setText( " "+title+" " );
zorglub's avatar
zorglub committed
816
817
818
819
}

void MainInterface::setName( QString name )
{
820
    input_name = name;
821
    nameLabel->setText( " " + name+" " );
zorglub's avatar
zorglub committed
822
823
}

824
825
void MainInterface::setStatus( int status )
{
zorglub's avatar
zorglub committed
826
    if( status == 1 ) // Playing
827
828
829
        ui.playButton->setIcon( QIcon( ":/pixmaps/pause.png" ) );
    else
        ui.playButton->setIcon( QIcon( ":/pixmaps/play.png" ) );
830
831
    if( systrayMenu )
        updateSystrayMenu( status );
832
833
}

834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
#define HELP_MENU N_("Menu")
#define HELP_PCH N_("Previous chapter")
#define HELP_NCH N_("Next chapter")
#define HELP_PTR N_("Previous track")
#define HELP_NTR N_("Next track")

void MainInterface::setNavigation( int navigation )
{
    // 1 = chapter, 2 = title, 0 = no
    if( navigation == 0 )
    {
        ui.discFrame->hide();
    } else if( navigation == 1 ) {
        ui.prevSectionButton->show();
        ui.prevSectionButton->setToolTip( qfu(HELP_PCH) );
        ui.nextSectionButton->show();
        ui.nextSectionButton->setToolTip( qfu(HELP_NCH) );
        ui.menuButton->show();
        ui.discFrame->show();
    } else {
        ui.prevSectionButton->show();
        ui.prevSectionButton->setToolTip( qfu(HELP_PCH) );
        ui.nextSectionButton->show();
        ui.nextSectionButton->setToolTip( qfu(HELP_NCH) );
        ui.menuButton->hide();
        ui.discFrame->show();
    }
}

zorglub's avatar
zorglub committed
863
864
static bool b_my_volume;

zorglub's avatar
zorglub committed
865
866
void MainInterface::updateOnTimer()
{
867
    /* \todo Make this event-driven */
zorglub's avatar
zorglub committed
868
869
870
    advControls->enableInput( THEMIM->getIM()->hasInput() );
    advControls->enableVideo( THEMIM->getIM()->hasVideo() );

871
    if( intf_ShouldDie( p_intf ) )
zorglub's avatar
zorglub committed
872
    {
zorglub's avatar
zorglub committed
873
        QApplication::closeAllWindows();
zorglub's avatar
zorglub committed
874
875
        QApplication::quit();
    }
876
877
878
879
880
881
    if( need_components_update )
    {
        doComponentsUpdate();
        need_components_update = false;
    }

zorglub's avatar
zorglub committed
882
883
884
885
886
887
888
889
890
891
892
    audio_volume_t i_volume;
    aout_VolumeGet( p_intf, &i_volume );
    i_volume = (i_volume *  200 )/ AOUT_VOLUME_MAX ;
    int i_gauge = ui.volumeSlider->value();
    b_my_volume = false;
    if( i_volume - i_gauge > 1 || i_gauge - i_volume > 1 )
    {
        b_my_volume = true;
        ui.volumeSlider->setValue( i_volume );
        b_my_volume = false;
    }
zorglub's avatar
zorglub committed
893
894
895
896
897
}

void MainInterface::closeEvent( QCloseEvent *e )
{
    hide();
898
    vlc_object_kill( p_intf );
zorglub's avatar
zorglub committed
899
}
zorglub's avatar
zorglub committed
900

zorglub's avatar
zorglub committed
901
902
903
904
905
906
907
908
909
910
void MainInterface::updateVolume( int sliderVolume )
{
    if( !b_my_volume )
    {
        int i_res = sliderVolume * AOUT_VOLUME_MAX /
                            (2*ui.volumeSlider->maximum() );
        aout_VolumeSet( p_intf, i_res );
    }
}

zorglub's avatar
zorglub committed
911
912
913
914
915
916
917
static int InteractCallback( vlc_object_t *p_this,
                             const char *psz_var, vlc_value_t old_val,
                             vlc_value_t new_val, void *param )
{
    intf_dialog_args_t *p_arg = new intf_dialog_args_t;
    p_arg->p_dialog = (interaction_dialog_t *)(new_val.p_address);
    DialogEvent *event = new DialogEvent( INTF_DIALOG_INTERACTION, 0, p_arg );
918
    QApplication::postEvent( THEDP, static_cast<QEvent*>(event) );
zorglub's avatar
zorglub committed
919
920
    return VLC_SUCCESS;
}
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951

/*****************************************************************************
 * PopupMenuCB: callback triggered by the intf-popupmenu playlist variable.
 *  We don't show the menu directly here because we don't want the
 *  caller to block for a too long time.
 *****************************************************************************/
static int PopupMenuCB( vlc_object_t *p_this, const char *psz_variable,
                        vlc_value_t old_val, vlc_value_t new_val, void *param )
{
    intf_thread_t *p_intf = (intf_thread_t *)param;

    if( p_intf->pf_show_dialog )
    {
        p_intf->pf_show_dialog( p_intf, INTF_DIALOG_POPUPMENU,
                                new_val.b_bool, 0 );
    }

    return VLC_SUCCESS;
}

/*****************************************************************************
 * IntfShowCB: callback triggered by the intf-show playlist variable.
 *****************************************************************************/
static int IntfShowCB( vlc_object_t *p_this, const char *psz_variable,
                       vlc_value_t old_val, vlc_value_t new_val, void *param )
{
    intf_thread_t *p_intf = (intf_thread_t *)param;
    //p_intf->p_sys->b_intf_show = VLC_TRUE;

    return VLC_SUCCESS;
}