main_interface.cpp 30 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
#define DEBUG_COLOR 0

67
68
69
70
71
/* 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
72
73
static int InteractCallback( vlc_object_t *, const char *, vlc_value_t,
                             vlc_value_t, void *);
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/* 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
88

zorglub's avatar
zorglub committed
89
MainInterface::MainInterface( intf_thread_t *_p_intf ) : QVLCMW( _p_intf )
zorglub's avatar
zorglub committed
90
{
91
    /* Variables initialisation */
92
    need_components_update = false;
93
    bgWidget = NULL; videoWidget = NULL; playlistWidget = NULL;
zorglub's avatar
zorglub committed
94
    embeddedPlaylistWasActive = videoIsActive = false;
95

96
    bool b_createSystray = false;
97
    input_name = "";
98

99
    /**
100
     *  Configuration and settings
101
102
103
104
     **/
    settings = new QSettings( "VideoLAN", "VLC" );
    settings->beginGroup( "MainWindow" );

105
106
107
    /* Main settings */
    setFocusPolicy( Qt::StrongFocus );
    setAcceptDrops(true);
108
109
110
    setWindowIcon( QApplication::windowIcon() );

    /* Set The Video In emebedded Mode or not */
zorglub's avatar
zorglub committed
111
    videoEmbeddedFlag = false;
112
113
    if( config_GetInt( p_intf, "embedded-video" ) )
        videoEmbeddedFlag = true;
zorglub's avatar
zorglub committed
114
115

    alwaysVideoFlag = false;
116
    if( videoEmbeddedFlag && config_GetInt( p_intf, "qt-always-video" ) )
zorglub's avatar
zorglub committed
117
118
        alwaysVideoFlag = true;

119
    /* Set the other interface settings */
120
    playlistEmbeddedFlag = settings->value("playlist-embedded", true).toBool();
zorglub's avatar
zorglub committed
121
    advControlsEnabled= settings->value( "adv-controls", false ).toBool();
122
    visualSelectorEnabled= settings->value( "visual-selector", false ).toBool();
zorglub's avatar
zorglub committed
123

124
125
126
127
128
129
130
131
132
#if DEBUG_COLOR
    QPalette palette2;
    palette2.setColor(this->backgroundRole(), Qt::magenta);
    setPalette(palette2);
#endif

    /**
     *  UI design
     **/
133
    setVLCWindowsTitle();
134
    handleMainUi( settings );
135
136

    /* Menu Bar */
zorglub's avatar
zorglub committed
137
    QVLCMenu::createMenuBar( this, p_intf, playlistEmbeddedFlag,
138
                             advControlsEnabled, visualSelectorEnabled );
139
140

    /* Status Bar */
141
142
143
    timeLabel = new QLabel;
    nameLabel = new QLabel;
    speedLabel = new QLabel( "1.0x" );
144
    timeLabel->setFrameStyle( QFrame::Sunken | QFrame::Panel );
145
146
147
148
    speedLabel->setFrameStyle( QFrame::Sunken | QFrame::Panel );
    statusBar()->addWidget( nameLabel, 8 );
    statusBar()->addPermanentWidget( speedLabel, 0 );
    statusBar()->addPermanentWidget( timeLabel, 2 );
zorglub's avatar
Icons    
zorglub committed
149

150
    /* Systray */
151
    sysTray = NULL;
152
    if( config_GetInt( p_intf, "qt-start-minimized") )
153
154
    {
        hide();
155
        b_createSystray = true;
156
    }
157
158
159
    if( config_GetInt( p_intf, "qt-system-tray") )
        b_createSystray = true;
    if (QSystemTrayIcon::isSystemTrayAvailable() && b_createSystray )
160
            createSystray();
161

162
163
164
165
    /* Init input manager */
    MainInputManager::getInstance( p_intf );
    ON_TIMEOUT( updateOnTimer() );

166
167
168
169
    /**
     * CONNECTs
     **/

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

173
174
175
176
177
    /* 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 ) );
178
179

    /* Naming in the controller */
180
181
    CONNECT( THEMIM->getIM(), nameChanged( QString ), this,
             setName( QString ) );
182
    if( config_GetInt( p_intf, "qt-system-tray" ) && sysTray )
183
184
    {
        CONNECT( THEMIM->getIM(), nameChanged( QString ), this,
185
                 updateSystrayTooltipName( QString ) );
186
    }
187
188
189
190
191
192
193
    if( config_GetInt( p_intf, "qt-name-in-title" ) )
    {
        CONNECT( THEMIM->getIM(), nameChanged( QString ), this,
             setVLCWindowsTitle( QString ) );
    }

    /* PLAY_STATUS */
194
    CONNECT( THEMIM->getIM(), statusChanged( int ), this, setStatus( int ) );
195
    CONNECT( THEMIM->getIM(), navigationChanged( int ),
196
             this, setNavigation(int) );
197
    if( config_GetInt( p_intf, "qt-system-tray" ) && sysTray )
198
199
    {
        CONNECT( THEMIM->getIM(), statusChanged( int ), this,
200
                 updateSystrayTooltipStatus( int ) );
201
    }
202
203
204
    CONNECT( slider, sliderDragged( float ),
             THEMIM->getIM(), sliderUpdate( float ) );

205
    /* Buttons */
206
207
208
209
210
211
212
    CONNECT( ui.prevSectionButton, clicked(), THEMIM->getIM(),
             sectionPrev() );
    CONNECT( ui.nextSectionButton, clicked(), THEMIM->getIM(),
             sectionNext() );
    CONNECT( ui.menuButton, clicked(), THEMIM->getIM(),
             sectionMenu() );

213
214
215
    /**
     * Callbacks
     **/
216
217
218
    var_Create( p_intf, "interaction", VLC_VAR_ADDRESS );
    var_AddCallback( p_intf, "interaction", InteractCallback, this );
    p_intf->b_interaction = VLC_TRUE;
219
220

    /* Register callback for the intf-popupmenu variable */
221
222
    playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_intf,
                                        VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
223
224
225
226
227
228
    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 );
    }
229
230
231
232
}

MainInterface::~MainInterface()
{
233
    /* Unregister callback for the intf-popupmenu variable */
234
235
    playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_intf,
                                        VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
236
237
238
239
240
241
242
    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
243
244
245
246
247
    settings->setValue( "playlist-embedded", playlistEmbeddedFlag );
    settings->setValue( "adv-controls", advControlsEnabled );
    settings->setValue( "pos", pos() );
    settings->endGroup();
    delete settings;
248
249
    p_intf->b_interaction = VLC_FALSE;
    var_DelCallback( p_intf, "interaction", InteractCallback, this );
250
251
252
253

    p_intf->pf_request_window = NULL;
    p_intf->pf_release_window = NULL;
    p_intf->pf_control_window = NULL;
254
255
}

256
257
258
/*****************************
 *   Main UI handling        *
 *****************************/
259
260
261
262
263

/**
 * Give the decorations of the Main Window a correct Name.
 * If nothing is given, set it to VLC...
 **/
264
265
266
267
void MainInterface::setVLCWindowsTitle( QString aTitle )
{
    if( aTitle.isEmpty() )
    {
268
        setWindowTitle( qtr( "VLC media player" ) );
269
270
271
    }
    else
    {
272
        setWindowTitle( aTitle + " - " + qtr( "VLC media player" ) );
273
274
275
    }
}

276
277
278
void MainInterface::handleMainUi( QSettings *settings )
{
    QWidget *main = new QWidget( this );
279
    QVBoxLayout *mainLayout = new QVBoxLayout( main );
280
281
    setCentralWidget( main );

282
283
284
285
286
    /* Margins, spacing */
    main->setContentsMargins( 0, 0, 0, 0 );
    mainLayout->setMargin( 0 );

    /* CONTROLS */
287
    QWidget *controls = new QWidget;
288
289
290
    ui.setupUi( controls );

    /* Configure the UI */
zorglub's avatar
zorglub committed
291
    slider = new InputSlider( Qt::Horizontal, NULL );
292
    ui.vboxLayout->insertWidget( 0, slider );
293
    ui.discFrame->hide();
294

295
296
297
    BUTTON_SET_IMG( ui.prevSectionButton, "", previous.png, "" );
    BUTTON_SET_IMG( ui.nextSectionButton, "", next.png, "" );
    BUTTON_SET_IMG( ui.menuButton, "", previous.png, "" );
298

zorglub's avatar
zorglub committed
299
300
301
302
303
    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() );
304
305

    /* Volume */
306
    ui.volMuteLabel->setPixmap( QPixmap( ":/pixmaps/volume-low.png" ) );
zorglub's avatar
zorglub committed
307
    ui.volumeSlider->setMaximum( 100 );
308
309
310
    ui.volMuteLabel->setToolTip( qtr( "Mute" ) );
    VolumeClickHandler *h = new VolumeClickHandler( p_intf, this );
    ui.volMuteLabel->installEventFilter(h);
zorglub's avatar
zorglub committed
311
312
    ui.volumeSlider->setFocusPolicy( Qt::NoFocus );

313
    BUTTON_SET_IMG( ui.playlistButton, "" , playlist_icon.png,
zorglub's avatar
zorglub committed
314
                        playlistEmbeddedFlag ?  qtr( "Show playlist" ) :
zorglub's avatar
Cleanup    
zorglub committed
315
                                                qtr( "Open playlist" ) );
316
    BUTTONACT( ui.playlistButton, playlist() );
zorglub's avatar
zorglub committed
317

318
319
320
321
322
323
324
325
326
#if DEBUG_COLOR
    QPalette palette;
    palette.setColor(main->backgroundRole(), Qt::green);
    main->setPalette(palette);
#endif

    /* Add the controls Widget */
    mainLayout->addWidget( controls );

zorglub's avatar
zorglub committed
327
    /* Set initial size */
zorglub's avatar
zorglub committed
328
    resize ( PREF_W, PREF_H );
329

330
    addSize = QSize( mainLayout->margin() * 2, PREF_H );
331

332
    /* advanced Controls handling */
zorglub's avatar
zorglub committed
333
    advControls = new ControlsWidget( p_intf );
334
    mainLayout->insertWidget( 0, advControls );
zorglub's avatar
zorglub committed
335
336
337
338
    advControls->updateGeometry();
    if( !advControlsEnabled ) advControls->hide();
    need_components_update = true;

339
    /* Visualisation */
340
    visualSelector = new VisualSelector( p_intf );
341
    mainLayout->insertWidget( 0, visualSelector );
342
343
    visualSelector->hide();

344
345
    /* And video Outputs */
    if(  alwaysVideoFlag )
346
347
348
    {
        bgWidget = new BackgroundWidget( p_intf );
        bgWidget->widgetSize = settings->value( "backgroundSize",
349
                                           QSize( 200, 200 ) ).toSize();
350
351
        bgWidget->resize( bgWidget->widgetSize );
        bgWidget->updateGeometry();
352
        mainLayout->insertWidget( 0, bgWidget );
353
354
    }

355
    if( videoEmbeddedFlag )
356
    {
357
        videoWidget = new VideoWidget( p_intf );
358
        videoWidget->widgetSize = QSize( 1, 1 );
359
        //videoWidget->resize( videoWidget->widgetSize );
360
        mainLayout->insertWidget( 0, videoWidget );
361

362
363
364
        p_intf->pf_request_window  = ::DoRequest;
        p_intf->pf_release_window  = ::DoRelease;
        p_intf->pf_control_window  = ::DoControl;
365
    }
366
367

    /* Finish the sizing */
zorglub's avatar
zorglub committed
368
    setMinimumSize( PREF_W, addSize.height() );
zorglub's avatar
zorglub committed
369
370
}

371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
/**********************************************************************
 * Handling of the components
 **********************************************************************/
void MainInterface::calculateInterfaceSize()
{
    int width = 0, height = 0;
    if( VISIBLE( bgWidget ) )
    {
        width = bgWidget->widgetSize.width();
        height = bgWidget->widgetSize.height();
        assert( !(playlistWidget && playlistWidget->isVisible() ) );
    }
    else if( VISIBLE( playlistWidget ) )
    {
        width = playlistWidget->widgetSize.width();
        height = playlistWidget->widgetSize.height();
    }
    else if( videoIsActive )
    {
        width =  videoWidget->widgetSize.width() ;
        height = videoWidget->widgetSize.height();
    }
    else
    {
        width = PREF_W - addSize.width();
        height = PREF_H - addSize.height();
    }
    if( VISIBLE( visualSelector ) )
        height += visualSelector->height();
    if( VISIBLE( advControls) )
    {
        height += advControls->sizeHint().height();
    }
    mainSize = QSize( width + addSize.width(), height + addSize.height() );
}

void MainInterface::resizeEvent( QResizeEvent *e )
{
    videoWidget->widgetSize.setWidth(  e->size().width() - addSize.width() );
    if( videoWidget && videoIsActive && videoWidget->widgetSize.height() > 1 )
    {
        SET_WH( videoWidget, e->size().width() - addSize.width(),
                             e->size().height()  - addSize.height() );
        videoWidget->updateGeometry();
    }
    if( VISIBLE( playlistWidget ) )
    {
        SET_WH( playlistWidget , e->size().width() - addSize.width(),
                                 e->size().height() - addSize.height() );
        playlistWidget->updateGeometry();
    }
}

424
425
426
427
/*****************************************************************************
 * Systray Icon and Systray Menu
 *****************************************************************************/

428
429
430
431
432
/**
 * Create a SystemTray icon and a menu that would go with it.
 * Connects to a click handler on the icon.
 **/
void MainInterface::createSystray()
433
{
434
    QIcon iconVLC =  QIcon( QPixmap( ":/vlc128.png" ) );
435
    sysTray = new QSystemTrayIcon( iconVLC, this );
436
437
    sysTray->setToolTip( qtr( "VLC media player" ));

438
    systrayMenu = new QMenu( qtr( "VLC media player" ), this );
439
    systrayMenu->setIcon( iconVLC );
440

441
    QVLCMenu::updateSystrayMenu( this, p_intf, true );
442
    sysTray->show();
443

444
445
    CONNECT( sysTray, activated(  QSystemTrayIcon::ActivationReason ),
            this, handleSystrayClick( QSystemTrayIcon::ActivationReason ) );
446
447
}

448
449
450
/**
 * Update the menu of the Systray Icon.
 * May be unneedded, since it just calls QVLCMenu::update
451
 * FIXME !!!
452
 **/
453
454
455
456
457
void MainInterface::updateSystrayMenu( int status )
{
    QVLCMenu::updateSystrayMenu( this, p_intf ) ;
}

458
459
460
/**
 * Updates the Systray Icon's menu and toggle the main interface
 */
461
462
463
void MainInterface::toggleUpdateSystrayMenu()
{
    toggleVisible();
464
    QVLCMenu::updateSystrayMenu( this, p_intf );
465
466
}

467
468
void MainInterface::handleSystrayClick(
                                    QSystemTrayIcon::ActivationReason reason )
469
470
471
472
{
    switch( reason )
    {
        case QSystemTrayIcon::Trigger:
473
474
            toggleUpdateSystrayMenu();
            break;
475
476
        case QSystemTrayIcon::MiddleClick:
            sysTray->showMessage( qtr( "VLC media player" ),
477
                    qtr( "Control menu for the player" ),
478
479
480
481
482
                    QSystemTrayIcon::Information, 4000 );
            break;
    }
}

483
484
485
/**
 * Updates the name of the systray Icon tooltip.
 * Doesn't check if the systray exists, check before you call it.
486
 * FIXME !!! Fusion with next function ?
487
 **/
488
489
490
491
492
493
494
495
496
497
498
499
void MainInterface::updateSystrayTooltipName( QString name )
{
    if( name.isEmpty() )
    {
        sysTray->setToolTip( qtr( "VLC media player" ) );
    }
    else
    {
        sysTray->setToolTip( name );
    }
}

500
501
502
503
/**
 * Updates the status of the systray Icon tooltip.
 * Doesn't check if the systray exists, check before you call it.
 **/
504
505
506
void MainInterface::updateSystrayTooltipStatus( int i_status )
{
    switch( i_status )
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
    {
        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;
            }
    }
526
}
527
528
529
530
531
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 );
532
533
534
    if( ret )
    {
        videoIsActive = true;
535
        if( VISIBLE( playlistWidget ) )
536
537
        {
            embeddedPlaylistWasActive = true;
538
//            playlistWidget->hide();
539
        }
540
541
        bool bgWasVisible = false;
        if( VISIBLE( bgWidget) )
zorglub's avatar
zorglub committed
542
        {
543
            bgWasVisible = true;
544
//            bgWidget->hide();
zorglub's avatar
zorglub committed
545
        }
546
547
548
549
550
551
552
553
554
555
556
        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 );
        }
557
//        videoWidget->updateGeometry(); /// FIXME: Needed ?
558
559
        need_components_update = true;
    }
560
561
562
563
564
565
    return ret;
}

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

569
    if( embeddedPlaylistWasActive )
570
        ;//playlistWidget->show();
zorglub's avatar
zorglub committed
571
    else if( bgWidget )
572
        ;//bgWidget->show();
zorglub's avatar
zorglub committed
573

574
    videoIsActive = false;
575
    need_components_update = true;
576
577
}

578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
class SetVideoOnTopQtEvent : public QEvent
{
public:
    SetVideoOnTopQtEvent( bool _onTop ) :
      QEvent( (QEvent::Type)SetVideoOnTopEvent_Type ), onTop( _onTop)
    {
    }

    bool OnTop() const
    {
        return onTop;
    }

private:
    bool onTop;
};

595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
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 );
614
            // videoWidget->updateGeometry();
615
616
617
618
619
            need_components_update = true;
            i_ret = VLC_SUCCESS;
            break;
        }
        case VOUT_SET_STAY_ON_TOP:
620
621
622
623
624
625
        {
            int i_arg = va_arg( args, int );
            QApplication::postEvent( this, new SetVideoOnTopQtEvent( i_arg ) );
            i_ret = VLC_SUCCESS;
            break;
        }
626
627
628
629
630
631
632
        default:
            msg_Warn( p_intf, "unsupported control query" );
            break;
    }
    return i_ret;
}

zorglub's avatar
zorglub committed
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
void MainInterface::advanced()
{
    if( !VISIBLE( advControls ) )
    {
        advControls->show();
        advControlsEnabled = true;
    }
    else
    {
        advControls->hide();
        advControlsEnabled = false;
    }
    doComponentsUpdate();
}

648
649
650
651
652
653
654
655
656
void MainInterface::visual()
{
    if( !VISIBLE( visualSelector) )
    {
        visualSelector->show();
        if( !THEMIM->getIM()->hasVideo() )
        {
            /* Show the background widget */
        }
657
        visualSelectorEnabled = true;
658
659
660
661
662
    }
    else
    {
        /* Stop any currently running visualization */
        visualSelector->hide();
663
        visualSelectorEnabled = false;
664
    }
665
    doComponentsUpdate();
666
667
}

668
669
670
671
672
673
674
void MainInterface::playlist()
{
    // Toggle the playlist dialog
    if( !playlistEmbeddedFlag )
    {
        if( playlistWidget )
        {
675
            /// \todo Destroy it
676
677
678
679
680
681
682
683
684
685
686
        }
        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
687
                                               QSize( 650, 310 ) ).toSize();
688
        playlistWidget->hide();
689
    }
690
    if( VISIBLE( playlistWidget ) )
691
692
693
694
    {
        playlistWidget->hide();
        if( videoIsActive )
        {
695
696
697
            videoWidget->widgetSize = savedVideoSize;
            videoWidget->resize( videoWidget->widgetSize );
            videoWidget->updateGeometry();
698
699
700
701
702
703
        }
    }
    else
    {
        playlistWidget->show();
        if( videoIsActive )
704
705
706
707
708
709
        {
            savedVideoSize = videoWidget->widgetSize;
            videoWidget->widgetSize.setHeight( 0 );
            videoWidget->resize( videoWidget->widgetSize );
            videoWidget->updateGeometry();
        }
710
        if( VISIBLE( bgWidget ) ) bgWidget->hide();
711
    }
712
    doComponentsUpdate();
713
714
}

zorglub's avatar
zorglub committed
715
716
/* Video widget cannot do this synchronously as it runs in another thread */
/* Well, could it, actually ? Probably dangerous ... */
717
718
void MainInterface::doComponentsUpdate()
{
719
720
    calculateInterfaceSize();
    resize( mainSize );
721
722
}

zorglub's avatar
zorglub committed
723
void MainInterface::undockPlaylist()
724
{
zorglub's avatar
zorglub committed
725
    if( playlistWidget )
726
    {
zorglub's avatar
zorglub committed
727
728
        playlistWidget->hide();
        playlistWidget->deleteLater();
729
730
731
        ui.vboxLayout->removeWidget( playlistWidget );
        playlistWidget = NULL;
        playlistEmbeddedFlag = false;
zorglub's avatar
zorglub committed
732

zorglub's avatar
zorglub committed
733
        menuBar()->clear();
734
735
        QVLCMenu::createMenuBar( this, p_intf, false, advControlsEnabled,
                                 visualSelectorEnabled);
zorglub's avatar
zorglub committed
736
737
738
739
740
741
742
743
744
745

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

        doComponentsUpdate();
        THEDP->playlistDialog();
746
    }
zorglub's avatar
zorglub committed
747
748
749
750
751
}

void MainInterface::customEvent( QEvent *event )
{
    if( event->type() == PLDockEvent_Type )
752
753
754
    {
        PlaylistDialog::killInstance();
        playlistEmbeddedFlag = true;
zorglub's avatar
zorglub committed
755
        menuBar()->clear();
756
757
        QVLCMenu::createMenuBar(this, p_intf, true, advControlsEnabled,
                                visualSelectorEnabled);
758
759
        playlist();
    }
760
761
762
763
764
765
    else if ( event->type() == SetVideoOnTopEvent_Type )
    {
        SetVideoOnTopQtEvent* p_event = (SetVideoOnTopQtEvent*)event;
        if( p_event->OnTop() )
            setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
        else
766
            setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint);
767
768
        show(); /* necessary to apply window flags?? */
    }
769
770
}

771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796

/************************************************************************
 * 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 ) {
797
798
            playlist_Add( THEPL, qtu(s), NULL,
                          PLAYLIST_APPEND | (first ? PLAYLIST_GO:0),
799
                          PLAYLIST_END, VLC_TRUE, VLC_FALSE );
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
            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();
}

818
819
820
/************************************************************************
 * Other stuff
 ************************************************************************/
821
822
void MainInterface::keyPressEvent( QKeyEvent *e )
{
823
    int i_vlck = qtEventToVLCKey( e );
824
825
    if( i_vlck >= 0 )
    {
826
        var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlck );
827
828
829
830
831
832
        e->accept();
    }
    else
        e->ignore();
}

833
834
void MainInterface::wheelEvent( QWheelEvent *e )
{
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
835
    int i_vlckey = qtWheelEventToVLCKey( e );
836
837
838
839
    var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlckey );
    e->accept();
}

zorglub's avatar
zorglub committed
840
841
void MainInterface::stop()
{
842
    THEMIM->stop();
zorglub's avatar
zorglub committed
843
}
844

zorglub's avatar
zorglub committed
845
846
void MainInterface::play()
{
zorglub's avatar
zorglub committed
847
    if( playlist_IsEmpty(THEPL) )
848
849
    {
        /* The playlist is empty, open a file requester */
zorglub's avatar
Wtf ?    
zorglub committed
850
        THEDP->openFileDialog();
851
852
853
854
        setStatus( 0 );
        return;
    }
    THEMIM->togglePlayPause();
zorglub's avatar
zorglub committed
855
}
856

zorglub's avatar
zorglub committed
857
858
void MainInterface::prev()
{
859
    THEMIM->prev();
zorglub's avatar
zorglub committed
860
}
861

zorglub's avatar
zorglub committed
862
863
void MainInterface::next()
{
864
    THEMIM->next();
zorglub's avatar
zorglub committed
865
866
867
868
869
870
871
872
873
}

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 );
874
    timeLabel->setText( " "+title+" " );
zorglub's avatar
zorglub committed
875
876
877
878
}

void MainInterface::setName( QString name )
{
879
    input_name = name;
880
    nameLabel->setText( " " + name+" " );
zorglub's avatar
zorglub committed
881
882
}

883
884
void MainInterface::setStatus( int status )
{
zorglub's avatar
zorglub committed
885
    if( status == 1 ) // Playing
886
887
888
        ui.playButton->setIcon( QIcon( ":/pixmaps/pause.png" ) );
    else
        ui.playButton->setIcon( QIcon( ":/pixmaps/play.png" ) );
889
890
    if( systrayMenu )
        updateSystrayMenu( status );
891
892
}

893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
#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
922
923
static bool b_my_volume;

zorglub's avatar
zorglub committed
924
925
void MainInterface::updateOnTimer()
{
926
    /* \todo Make this event-driven */
zorglub's avatar
zorglub committed
927
928
929
    advControls->enableInput( THEMIM->getIM()->hasInput() );
    advControls->enableVideo( THEMIM->getIM()->hasVideo() );

930
    if( intf_ShouldDie( p_intf ) )
zorglub's avatar
zorglub committed
931
    {
zorglub's avatar
zorglub committed
932
        QApplication::closeAllWindows();
zorglub's avatar
zorglub committed
933
934
        QApplication::quit();
    }
935
936
937
938
939
940
    if( need_components_update )
    {
        doComponentsUpdate();
        need_components_update = false;
    }

zorglub's avatar
zorglub committed
941
942
943
944
945
946
947
948
949
950
951
    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
952
953
954
955
956
}

void MainInterface::closeEvent( QCloseEvent *e )
{
    hide();
957
    vlc_object_kill( p_intf );
zorglub's avatar
zorglub committed
958
}
zorglub's avatar
zorglub committed
959

zorglub's avatar
zorglub committed
960
961
962
963
964
965
966
967
968
969
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
970
971
972
973
974
975
976
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 );
977
    QApplication::postEvent( THEDP, static_cast<QEvent*>(event) );
zorglub's avatar
zorglub committed
978
979
    return VLC_SUCCESS;
}
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010

/*****************************************************************************
 * 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;
}