main_interface.cpp 30.9 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
    mainLayout->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
    /* And video Outputs */
345
    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
void MainInterface::toggleUpdateSystrayMenu()
{
463
464
465
    if( isHidden() )
    {
        show();
466
        activateWindow();
467
468
469
    }
    else
    {
470
471
472
473
474
475
476
477
478
479
480
481
#ifdef WIN32
        /* check if any visible window is above vlc in the z-order,
         * but ignore the ones always on top */
        WINDOWINFO wi;
        HWND hwnd;
        wi.cbSize = sizeof( WINDOWINFO );
        for( hwnd = GetNextWindow( internalWinId(), GW_HWNDPREV );
                hwnd && !IsWindowVisible( hwnd );
                hwnd = GetNextWindow( hwnd, GW_HWNDPREV ) );
        if( !hwnd || !GetWindowInfo( hwnd, &wi ) ||
                (wi.dwExStyle&WS_EX_TOPMOST) )
#else
482
        if( isActiveWindow() )
483
#endif
484
485
486
487
488
489
490
491
        {
            hide();
        }
        else
        {
            activateWindow();
        }
    }
492
    QVLCMenu::updateSystrayMenu( this, p_intf );
493
494
}

495
496
void MainInterface::handleSystrayClick(
                                    QSystemTrayIcon::ActivationReason reason )
497
498
499
500
{
    switch( reason )
    {
        case QSystemTrayIcon::Trigger:
501
502
            toggleUpdateSystrayMenu();
            break;
503
504
        case QSystemTrayIcon::MiddleClick:
            sysTray->showMessage( qtr( "VLC media player" ),
505
                    qtr( "Control menu for the player" ),
506
507
508
509
510
                    QSystemTrayIcon::Information, 4000 );
            break;
    }
}

511
512
513
/**
 * Updates the name of the systray Icon tooltip.
 * Doesn't check if the systray exists, check before you call it.
514
 * FIXME !!! Fusion with next function ?
515
 **/
516
517
518
519
520
521
522
523
524
525
526
527
void MainInterface::updateSystrayTooltipName( QString name )
{
    if( name.isEmpty() )
    {
        sysTray->setToolTip( qtr( "VLC media player" ) );
    }
    else
    {
        sysTray->setToolTip( name );
    }
}

528
529
530
531
/**
 * Updates the status of the systray Icon tooltip.
 * Doesn't check if the systray exists, check before you call it.
 **/
532
533
534
void MainInterface::updateSystrayTooltipStatus( int i_status )
{
    switch( i_status )
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
    {
        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;
            }
    }
554
}
555
556
557
558
559
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 );
560
561
562
    if( ret )
    {
        videoIsActive = true;
563
        if( VISIBLE( playlistWidget ) )
564
565
        {
            embeddedPlaylistWasActive = true;
566
//            playlistWidget->hide();
567
        }
568
569
        bool bgWasVisible = false;
        if( VISIBLE( bgWidget) )
zorglub's avatar
zorglub committed
570
        {
571
            bgWasVisible = true;
572
//            bgWidget->hide();
zorglub's avatar
zorglub committed
573
        }
574
575
576
577
578
579
580
581
582
583
584
        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 );
        }
585
//        videoWidget->updateGeometry(); /// FIXME: Needed ?
586
587
        need_components_update = true;
    }
588
589
590
591
592
593
    return ret;
}

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

597
    if( embeddedPlaylistWasActive )
598
        ;//playlistWidget->show();
zorglub's avatar
zorglub committed
599
    else if( bgWidget )
600
        ;//bgWidget->show();
zorglub's avatar
zorglub committed
601

602
    videoIsActive = false;
603
    need_components_update = true;
604
605
}

606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
class SetVideoOnTopQtEvent : public QEvent
{
public:
    SetVideoOnTopQtEvent( bool _onTop ) :
      QEvent( (QEvent::Type)SetVideoOnTopEvent_Type ), onTop( _onTop)
    {
    }

    bool OnTop() const
    {
        return onTop;
    }

private:
    bool onTop;
};

623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
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 );
642
            // videoWidget->updateGeometry();
643
644
645
646
647
            need_components_update = true;
            i_ret = VLC_SUCCESS;
            break;
        }
        case VOUT_SET_STAY_ON_TOP:
648
649
650
651
652
653
        {
            int i_arg = va_arg( args, int );
            QApplication::postEvent( this, new SetVideoOnTopQtEvent( i_arg ) );
            i_ret = VLC_SUCCESS;
            break;
        }
654
655
656
657
658
659
660
        default:
            msg_Warn( p_intf, "unsupported control query" );
            break;
    }
    return i_ret;
}

zorglub's avatar
zorglub committed
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
void MainInterface::advanced()
{
    if( !VISIBLE( advControls ) )
    {
        advControls->show();
        advControlsEnabled = true;
    }
    else
    {
        advControls->hide();
        advControlsEnabled = false;
    }
    doComponentsUpdate();
}

676
677
678
679
680
681
682
683
684
void MainInterface::visual()
{
    if( !VISIBLE( visualSelector) )
    {
        visualSelector->show();
        if( !THEMIM->getIM()->hasVideo() )
        {
            /* Show the background widget */
        }
685
        visualSelectorEnabled = true;
686
687
688
689
690
    }
    else
    {
        /* Stop any currently running visualization */
        visualSelector->hide();
691
        visualSelectorEnabled = false;
692
    }
693
    doComponentsUpdate();
694
695
}

696
697
698
699
700
701
702
void MainInterface::playlist()
{
    // Toggle the playlist dialog
    if( !playlistEmbeddedFlag )
    {
        if( playlistWidget )
        {
703
            /// \todo Destroy it
704
705
706
707
708
709
710
711
712
713
714
        }
        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
715
                                               QSize( 650, 310 ) ).toSize();
716
        playlistWidget->hide();
717
    }
718
    if( VISIBLE( playlistWidget ) )
719
720
721
722
    {
        playlistWidget->hide();
        if( videoIsActive )
        {
723
724
725
            videoWidget->widgetSize = savedVideoSize;
            videoWidget->resize( videoWidget->widgetSize );
            videoWidget->updateGeometry();
726
        }
727
        if( bgWidget ) bgWidget->show();
728
729
730
731
732
    }
    else
    {
        playlistWidget->show();
        if( videoIsActive )
733
734
735
736
737
738
        {
            savedVideoSize = videoWidget->widgetSize;
            videoWidget->widgetSize.setHeight( 0 );
            videoWidget->resize( videoWidget->widgetSize );
            videoWidget->updateGeometry();
        }
739
        if( VISIBLE( bgWidget ) ) bgWidget->hide();
740
    }
741
    doComponentsUpdate();
742
743
}

zorglub's avatar
zorglub committed
744
745
/* Video widget cannot do this synchronously as it runs in another thread */
/* Well, could it, actually ? Probably dangerous ... */
746
747
void MainInterface::doComponentsUpdate()
{
748
749
    calculateInterfaceSize();
    resize( mainSize );
750
751
}

zorglub's avatar
zorglub committed
752
void MainInterface::undockPlaylist()
753
{
zorglub's avatar
zorglub committed
754
    if( playlistWidget )
755
    {
zorglub's avatar
zorglub committed
756
757
        playlistWidget->hide();
        playlistWidget->deleteLater();
758
759
760
        ui.vboxLayout->removeWidget( playlistWidget );
        playlistWidget = NULL;
        playlistEmbeddedFlag = false;
zorglub's avatar
zorglub committed
761

zorglub's avatar
zorglub committed
762
        menuBar()->clear();
763
764
        QVLCMenu::createMenuBar( this, p_intf, false, advControlsEnabled,
                                 visualSelectorEnabled);
zorglub's avatar
zorglub committed
765
766
767
768
769
770
771
772
773
774

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

        doComponentsUpdate();
        THEDP->playlistDialog();
775
    }
zorglub's avatar
zorglub committed
776
777
}

778
779
780
781
782
783
784
void MainInterface::toggleMenus()
{
    if( menuBar()->isVisible() ) menuBar()->hide();
        else menuBar()->show();
    msg_Dbg( p_intf, "I was there: \\_o<~~ coin coin" );
}

zorglub's avatar
zorglub committed
785
786
787
void MainInterface::customEvent( QEvent *event )
{
    if( event->type() == PLDockEvent_Type )
788
789
790
    {
        PlaylistDialog::killInstance();
        playlistEmbeddedFlag = true;
zorglub's avatar
zorglub committed
791
        menuBar()->clear();
792
793
        QVLCMenu::createMenuBar(this, p_intf, true, advControlsEnabled,
                                visualSelectorEnabled);
794
795
        playlist();
    }
796
797
798
799
800
801
    else if ( event->type() == SetVideoOnTopEvent_Type )
    {
        SetVideoOnTopQtEvent* p_event = (SetVideoOnTopQtEvent*)event;
        if( p_event->OnTop() )
            setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
        else
802
            setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint);
803
804
        show(); /* necessary to apply window flags?? */
    }
805
806
}

807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832

/************************************************************************
 * 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 ) {
833
834
            playlist_Add( THEPL, qtu(s), NULL,
                          PLAYLIST_APPEND | (first ? PLAYLIST_GO:0),
835
                          PLAYLIST_END, VLC_TRUE, VLC_FALSE );
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
            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();
}

854
855
856
/************************************************************************
 * Other stuff
 ************************************************************************/
857
858
void MainInterface::keyPressEvent( QKeyEvent *e )
{
859
    int i_vlck = qtEventToVLCKey( e );
860
861
    if( i_vlck >= 0 )
    {
862
        var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlck );
863
864
865
866
867
868
        e->accept();
    }
    else
        e->ignore();
}

869
870
void MainInterface::wheelEvent( QWheelEvent *e )
{
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
871
    int i_vlckey = qtWheelEventToVLCKey( e );
872
873
874
875
    var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlckey );
    e->accept();
}

zorglub's avatar
zorglub committed
876
877
void MainInterface::stop()
{
878
    THEMIM->stop();
zorglub's avatar
zorglub committed
879
}
880

zorglub's avatar
zorglub committed
881
882
void MainInterface::play()
{
zorglub's avatar
zorglub committed
883
    if( playlist_IsEmpty(THEPL) )
884
885
    {
        /* The playlist is empty, open a file requester */
zorglub's avatar
Wtf ?    
zorglub committed
886
        THEDP->openFileDialog();
887
888
889
890
        setStatus( 0 );
        return;
    }
    THEMIM->togglePlayPause();
zorglub's avatar
zorglub committed
891
}
892

zorglub's avatar
zorglub committed
893
894
void MainInterface::prev()
{
895
    THEMIM->prev();
zorglub's avatar
zorglub committed
896
}
897

zorglub's avatar
zorglub committed
898
899
void MainInterface::next()
{
900
    THEMIM->next();
zorglub's avatar
zorglub committed
901
902
903
904
905
906
907
908
909
}

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 );
910
    timeLabel->setText( " "+title+" " );
zorglub's avatar
zorglub committed
911
912
913
914
}

void MainInterface::setName( QString name )
{
915
    input_name = name;
916
    nameLabel->setText( " " + name+" " );
zorglub's avatar
zorglub committed
917
918
}

919
920
void MainInterface::setStatus( int status )
{
zorglub's avatar
zorglub committed
921
    if( status == 1 ) // Playing
922
923
924
        ui.playButton->setIcon( QIcon( ":/pixmaps/pause.png" ) );
    else
        ui.playButton->setIcon( QIcon( ":/pixmaps/play.png" ) );
925
926
    if( systrayMenu )
        updateSystrayMenu( status );
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
952
953
954
955
956
957
#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
958
959
static bool b_my_volume;

zorglub's avatar
zorglub committed
960
961
void MainInterface::updateOnTimer()
{
962
    /* \todo Make this event-driven */
zorglub's avatar
zorglub committed
963
964
965
    advControls->enableInput( THEMIM->getIM()->hasInput() );
    advControls->enableVideo( THEMIM->getIM()->hasVideo() );

966
    if( intf_ShouldDie( p_intf ) )
zorglub's avatar
zorglub committed
967
    {
zorglub's avatar
zorglub committed
968
        QApplication::closeAllWindows();
zorglub's avatar
zorglub committed
969
970
        QApplication::quit();
    }
971
972
973
974
975
976
    if( need_components_update )
    {
        doComponentsUpdate();
        need_components_update = false;
    }

zorglub's avatar
zorglub committed
977
978
979
980
981
982
983
984
985
986
987
    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
988
989
990
991
992
}

void MainInterface::closeEvent( QCloseEvent *e )
{
    hide();
993
    vlc_object_kill( p_intf );
zorglub's avatar
zorglub committed
994
}
zorglub's avatar
zorglub committed
995

zorglub's avatar
zorglub committed
996
997
998
999
1000
1001
1002
1003
1004
1005
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
1006
1007
1008
1009
1010
1011
1012
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 );
1013
    QApplication::postEvent( THEDP, static_cast<QEvent*>(event) );
zorglub's avatar
zorglub committed
1014
1015
    return VLC_SUCCESS;
}
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046

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