main_interface.cpp 30.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
 *
 * Authors: Clément Stenac <zorglub@videolan.org>
8
 *          Jean-Baptiste Kempf <jb@videolan.org>
zorglub's avatar
zorglub committed
9
10
11
12
13
14
15
16
17
18
19
20
21
 *
 * 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
22
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23
 *****************************************************************************/
zorglub's avatar
zorglub committed
24

25
#include "qt4.hpp"
zorglub's avatar
zorglub committed
26
#include "main_interface.hpp"
zorglub's avatar
zorglub committed
27
#include "input_manager.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
#include <QLabel>
45
46
#include <QSlider>
#include <QWidgetAction>
47
48

#include <assert.h>
49
#include <vlc_keys.h>
zorglub's avatar
zorglub committed
50
#include <vlc_vout.h>
zorglub's avatar
zorglub committed
51

zorglub's avatar
zorglub committed
52
#ifdef WIN32
zorglub's avatar
zorglub committed
53
    #define PREF_W 410
54
    #define PREF_H 151
zorglub's avatar
zorglub committed
55
#else
zorglub's avatar
zorglub committed
56
    #define PREF_W 450
57
    #define PREF_H 160
zorglub's avatar
zorglub committed
58
#endif
zorglub's avatar
zorglub committed
59

60
61
62
63
64
65
#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()

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

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

96
    /**
97
     *  Configuration and settings
98
     **/
99
    settings = new QSettings( "vlc", "vlc-qt-interface" );
100
101
    settings->beginGroup( "MainWindow" );

102
103
104
    /* Main settings */
    setFocusPolicy( Qt::StrongFocus );
    setAcceptDrops(true);
105
    setWindowIcon( QApplication::windowIcon() );
106
    setWindowOpacity( config_GetFloat( p_intf, "qt-opacity" ) );
107
108

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

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

117
    /* Set the other interface settings */
118
119
120
121
    playlistEmbeddedFlag = settings->value( "playlist-embedded", true).toBool();
    visualSelectorEnabled = settings->value( "visual-selector", false ).toBool();
    notificationEnabled = config_GetInt( p_intf, "qt-notification" )
                          ? true : false;
122
123
124
    /**************************
     *  UI and Widgets design
     **************************/
125
    setVLCWindowsTitle();
126
    handleMainUi( settings );
127
128

    /* Menu Bar */
zorglub's avatar
zorglub committed
129
    QVLCMenu::createMenuBar( this, p_intf, playlistEmbeddedFlag,
130
                             visualSelectorEnabled );
131
132

    /* Status Bar */
133
134
135
136
    /**
     * TODO: clicking on the elapsed time should switch to the remaining time
     **/
    /**
137
     * TODO: do we add a label for the current Volume ?
138
     **/
139
    b_remainingTime = false;
140
141
142
    timeLabel = new QLabel;
    nameLabel = new QLabel;
    speedLabel = new QLabel( "1.0x" );
143
    timeLabel->setFrameStyle( QFrame::Sunken | QFrame::Panel );
144
145
146
147
    speedLabel->setFrameStyle( QFrame::Sunken | QFrame::Panel );
    statusBar()->addWidget( nameLabel, 8 );
    statusBar()->addPermanentWidget( speedLabel, 0 );
    statusBar()->addPermanentWidget( timeLabel, 2 );
148
149
    speedLabel->setContextMenuPolicy ( Qt::CustomContextMenu );
    timeLabel->setContextMenuPolicy ( Qt::CustomContextMenu );
150
    timeLabel->installEventFilter( this );
151
152
153
154
    CONNECT( speedLabel, customContextMenuRequested( QPoint ),
             this, showSpeedMenu( QPoint ) );
    CONNECT( timeLabel, customContextMenuRequested( QPoint ),
             this, showTimeMenu( QPoint ) );
155

156
157
158
    /**********************
     * Systray Management *
     **********************/
159
    sysTray = NULL;
160
161
    bool b_createSystray = false;
    bool b_systrayAvailable = QSystemTrayIcon::isSystemTrayAvailable();
162
    if( config_GetInt( p_intf, "qt-start-minimized") )
163
    {
164
165
166
167
168
169
        if( b_systrayAvailable ){
            b_createSystray = true;
            hide(); //FIXME
        }
        else msg_Warn( p_intf, "You can't minize if you haven't a system "
                "tray bar" );
170
    }
171
172
    if( config_GetInt( p_intf, "qt-system-tray") )
        b_createSystray = true;
173
174

    if( b_systrayAvailable && b_createSystray )
175
            createSystray();
176

177
178
179
180
    /* Init input manager */
    MainInputManager::getInstance( p_intf );
    ON_TIMEOUT( updateOnTimer() );

181
    /**
182
     * Various CONNECTs
183
184
     **/

185
    /* Connect the input manager to the GUI elements it manages */
186
    /* It is also connected to the control->slider, see the ControlsWidget */
187
    CONNECT( THEMIM->getIM(), positionUpdated( float, int, int ),
188
189
190
191
             this, setDisplayPosition( float, int, int ) );
    
    CONNECT( THEMIM->getIM(), rateChanged( int ), this, setRate( int ) );
    
192
193
    /** Connects on nameChanged() */
    /* Naming in the controller statusbar */
194
195
    CONNECT( THEMIM->getIM(), nameChanged( QString ), this,
             setName( QString ) );
196
    /* and in the systray */
197
    if( sysTray )
198
199
    {
        CONNECT( THEMIM->getIM(), nameChanged( QString ), this,
200
                 updateSystrayTooltipName( QString ) );
201
    }
202
    /* and in the title of the controller */
203
204
205
206
207
208
    if( config_GetInt( p_intf, "qt-name-in-title" ) )
    {
        CONNECT( THEMIM->getIM(), nameChanged( QString ), this,
             setVLCWindowsTitle( QString ) );
    }

209
210
    /** CONNECTS on PLAY_STATUS **/
    /* Status on the main controller */
211
    CONNECT( THEMIM->getIM(), statusChanged( int ), this, setStatus( int ) );
212
    /* and in the systray */
213
    if( sysTray )
214
215
    {
        CONNECT( THEMIM->getIM(), statusChanged( int ), this,
216
                 updateSystrayTooltipStatus( int ) );
217
    }
218

219
220
221
    /**
     * Callbacks
     **/
222
223
224
    var_Create( p_intf, "interaction", VLC_VAR_ADDRESS );
    var_AddCallback( p_intf, "interaction", InteractCallback, this );
    p_intf->b_interaction = VLC_TRUE;
225
226

    /* Register callback for the intf-popupmenu variable */
227
228
    playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_intf,
                                        VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
229
230
231
232
233
234
    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 );
    }
235
236
237
238
}

MainInterface::~MainInterface()
{
239
    /* Unregister callback for the intf-popupmenu variable */
240
241
    playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_intf,
                                        VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
242
243
244
245
246
247
248
    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
249
    settings->setValue( "playlist-embedded", playlistEmbeddedFlag );
250
    settings->setValue( "adv-controls", getControlsVisibilityStatus() & 0x1 );
zorglub's avatar
zorglub committed
251
252
253
    settings->setValue( "pos", pos() );
    settings->endGroup();
    delete settings;
254
255
    p_intf->b_interaction = VLC_FALSE;
    var_DelCallback( p_intf, "interaction", InteractCallback, this );
256
257
258
259

    p_intf->pf_request_window = NULL;
    p_intf->pf_release_window = NULL;
    p_intf->pf_control_window = NULL;
260
261
}

262
263
264
/*****************************
 *   Main UI handling        *
 *****************************/
265
266
267
268
269

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

282

283
284
void MainInterface::handleMainUi( QSettings *settings )
{
285
    /* Create the main Widget and the mainLayout */
286
    QWidget *main = new QWidget( this );
287
    mainLayout = new QVBoxLayout( main );
288
289
    setCentralWidget( main );

290
291
292
293
    /* Margins, spacing */
    main->setContentsMargins( 0, 0, 0, 0 );
    mainLayout->setMargin( 0 );

294
295
296
    /* Create the CONTROLS Widget */
    controls = new ControlsWidget( p_intf,
                   settings->value( "adv-controls", false ).toBool() );
297

298
    /* Configure the Controls */
299
    BUTTON_SET_IMG( controls->playlistButton, "" , playlist_icon.png,
300
301
302
                    playlistEmbeddedFlag ?  qtr( "Show playlist" ) :
                                            qtr( "Open playlist" ) );
    BUTTONACT( controls->playlistButton, togglePlaylist() );
303

304
    /* Add the controls Widget to the main Widget */
305
306
    mainLayout->addWidget( controls );

307
308
309
310
311
312
    /* Create the Speed Control Widget */
    speedControl = new SpeedControlWidget( p_intf );
    speedControlMenu = new QMenu( this );
    QWidgetAction *widgetAction = new QWidgetAction( this );
    widgetAction->setDefaultWidget( speedControl );
    speedControlMenu->addAction( widgetAction );
313

314
315
    /* Set initial size */
    resize( PREF_W, PREF_H );
316
    addSize = QSize( mainLayout->margin() * 2, PREF_H );
317

318
    /* Visualisation */
319
    visualSelector = new VisualSelector( p_intf );
320
    mainLayout->insertWidget( 0, visualSelector );
321
322
    visualSelector->hide();

323
    /* And video Outputs */
324
    if( alwaysVideoFlag )
325
326
327
    {
        bgWidget = new BackgroundWidget( p_intf );
        bgWidget->widgetSize = settings->value( "backgroundSize",
328
                                           QSize( 300, 300 ) ).toSize();
329
330
        bgWidget->resize( bgWidget->widgetSize );
        bgWidget->updateGeometry();
331
        mainLayout->insertWidget( 0, bgWidget );
332
333
    }

334
    if( videoEmbeddedFlag )
335
    {
336
        videoWidget = new VideoWidget( p_intf );
337
        videoWidget->widgetSize = QSize( 1, 1 );
338
        //videoWidget->resize( videoWidget->widgetSize );
339
        mainLayout->insertWidget( 0, videoWidget );
340

341
342
343
        p_intf->pf_request_window  = ::DoRequest;
        p_intf->pf_release_window  = ::DoRelease;
        p_intf->pf_control_window  = ::DoControl;
344
    }
345
346

    /* Finish the sizing */
zorglub's avatar
zorglub committed
347
    setMinimumSize( PREF_W, addSize.height() );
zorglub's avatar
zorglub committed
348
349
}

350
/**********************************************************************
351
 * Handling of sizing of the components
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
 **********************************************************************/
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();
379
/*    if( VISIBLE( advControls) )
380
381
    {
        height += advControls->sizeHint().height();
382
    }*/
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
    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();
    }
}
402

403
404
405
406
407
/****************************************************************************
 * Small right-click menus
 ****************************************************************************/
void MainInterface::showSpeedMenu( QPoint pos )
{
408
    speedControlMenu->exec( QCursor::pos() );
409
410
411
412
413
}

void MainInterface::showTimeMenu( QPoint pos )
{
    QMenu menu( this );
414
415
    menu.addAction(  qtr("Elapsed Time") , this, SLOT( setElapsedTime() ) );
    menu.addAction(  qtr("Remaining Time") , this, SLOT( setRemainTime() ) );
416
417
    menu.exec( QCursor::pos() );
}
418

419
420
421
/****************************************************************************
 * Video Handling
 ****************************************************************************/
422
423
424
425
426
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 );
427
428
429
    if( ret )
    {
        videoIsActive = true;
430
        if( VISIBLE( playlistWidget ) )
431
432
        {
            embeddedPlaylistWasActive = true;
433
//            playlistWidget->hide();
434
        }
435
436
        bool bgWasVisible = false;
        if( VISIBLE( bgWidget) )
zorglub's avatar
zorglub committed
437
        {
438
            bgWasVisible = true;
439
            bgWidget->hide();
zorglub's avatar
zorglub committed
440
        }
441
442
443
444
445
446
447
448
449
450
451
        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 );
        }
452
        videoWidget->updateGeometry(); // Needed for deinterlace
453
454
        need_components_update = true;
    }
455
456
457
458
459
460
    return ret;
}

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

464
    if( embeddedPlaylistWasActive )
465
        playlistWidget->show();
zorglub's avatar
zorglub committed
466
    else if( bgWidget )
467
        bgWidget->show();
zorglub's avatar
zorglub committed
468

469
    videoIsActive = false;
470
    need_components_update = true;
471
472
}

473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
class SetVideoOnTopQtEvent : public QEvent
{
public:
    SetVideoOnTopQtEvent( bool _onTop ) :
      QEvent( (QEvent::Type)SetVideoOnTopEvent_Type ), onTop( _onTop)
    {
    }

    bool OnTop() const
    {
        return onTop;
    }

private:
    bool onTop;
};

490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
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 );
509
            // videoWidget->updateGeometry();
510
511
512
513
514
            need_components_update = true;
            i_ret = VLC_SUCCESS;
            break;
        }
        case VOUT_SET_STAY_ON_TOP:
515
516
517
518
519
520
        {
            int i_arg = va_arg( args, int );
            QApplication::postEvent( this, new SetVideoOnTopQtEvent( i_arg ) );
            i_ret = VLC_SUCCESS;
            break;
        }
521
522
523
524
525
526
527
        default:
            msg_Warn( p_intf, "unsupported control query" );
            break;
    }
    return i_ret;
}

528
529
530
531
532
533
534
/*****************************************************************************
 * Playlist, Visualisation and Menus handling
 *****************************************************************************/
/**
 * Toggle the playlist widget or dialog
 **/
void MainInterface::togglePlaylist()
535
{
536
    // Toggle the playlist dialog if not embedded and return
537
538
539
540
    if( !playlistEmbeddedFlag )
    {
        if( playlistWidget )
        {
541
            /// \todo Destroy it
542
543
544
545
546
        }
        THEDP->playlistDialog();
        return;
    }

547
    // Create the playlist Widget and destroy the existing dialog
548
549
550
551
    if( !playlistWidget )
    {
        PlaylistDialog::killInstance();
        playlistWidget = new PlaylistWidget( p_intf );
552
        mainLayout->insertWidget( 0, playlistWidget );
553
        playlistWidget->widgetSize = settings->value( "playlistSize",
zorglub's avatar
zorglub committed
554
                                               QSize( 650, 310 ) ).toSize();
555
        playlistWidget->hide();
556
557
        if(bgWidget)
        CONNECT( playlistWidget, artSet( QString ), bgWidget, setArt(QString) );
558
    }
559
560

    // And toggle visibility
561
    if( VISIBLE( playlistWidget ) )
562
563
    {
        playlistWidget->hide();
564
        if( bgWidget ) bgWidget->show();
565
566
        if( videoIsActive )
        {
567
568
569
            videoWidget->widgetSize = savedVideoSize;
            videoWidget->resize( videoWidget->widgetSize );
            videoWidget->updateGeometry();
570
            if( bgWidget ) bgWidget->hide();
571
572
573
574
575
576
        }
    }
    else
    {
        playlistWidget->show();
        if( videoIsActive )
577
578
579
580
581
582
        {
            savedVideoSize = videoWidget->widgetSize;
            videoWidget->widgetSize.setHeight( 0 );
            videoWidget->resize( videoWidget->widgetSize );
            videoWidget->updateGeometry();
        }
583
        if( VISIBLE( bgWidget ) ) bgWidget->hide();
584
    }
585

586
    doComponentsUpdate();
587
588
}

zorglub's avatar
zorglub committed
589
void MainInterface::undockPlaylist()
590
{
zorglub's avatar
zorglub committed
591
    if( playlistWidget )
592
    {
zorglub's avatar
zorglub committed
593
594
        playlistWidget->hide();
        playlistWidget->deleteLater();
595
        mainLayout->removeWidget( playlistWidget );
596
597
        playlistWidget = NULL;
        playlistEmbeddedFlag = false;
zorglub's avatar
zorglub committed
598

zorglub's avatar
zorglub committed
599
        menuBar()->clear();
600
        QVLCMenu::createMenuBar( this, p_intf, false, visualSelectorEnabled);
zorglub's avatar
zorglub committed
601
602
603
604
605
606
607
608
609
610

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

        doComponentsUpdate();
        THEDP->playlistDialog();
611
    }
zorglub's avatar
zorglub committed
612
613
}

614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
#if 0
void MainInterface::visual()
{
    if( !VISIBLE( visualSelector) )
    {
        visualSelector->show();
        if( !THEMIM->getIM()->hasVideo() )
        {
            /* Show the background widget */
        }
        visualSelectorEnabled = true;
    }
    else
    {
        /* Stop any currently running visualization */
        visualSelector->hide();
        visualSelectorEnabled = false;
    }
    doComponentsUpdate();
}
#endif

636
637
void MainInterface::toggleMenus()
{
638
    msg_Dbg( p_intf, "I HAS HERE, HIDING YOUR MENUZ: \\_o<~~ coin coin" );
639
640
    TOGGLEV( controls );
    TOGGLEV( statusBar() );
641
    updateGeometry();
642
643
}

644
645
646
/* Video widget cannot do this synchronously as it runs in another thread */
/* Well, could it, actually ? Probably dangerous ... */
void MainInterface::doComponentsUpdate()
zorglub's avatar
zorglub committed
647
{
648
649
650
651
652
653
654
655
656
    calculateInterfaceSize();
    resize( mainSize );
}

void MainInterface::toggleAdvanced()
{
    controls->toggleAdvanced();
}

657
int MainInterface::getControlsVisibilityStatus()
658
{
659
    return( (controls->isVisible() ? 0x2 : 0x0 )
660
                + controls->b_advancedVisible );
661
662
663
664
665
}

/************************************************************************
 * Other stuff
 ************************************************************************/
666
void MainInterface::setDisplayPosition( float pos, int time, int length )
667
668
669
{
    char psz_length[MSTRTIME_MAX_SIZE], psz_time[MSTRTIME_MAX_SIZE];
    secstotimestr( psz_length, length );
670
671
672
673
    secstotimestr( psz_time, b_remainingTime ? length - time : time );
    QString title; title.sprintf( "%s/%s", psz_time, psz_length );
    if( b_remainingTime ) timeLabel->setText( " -"+title+" " );
    else timeLabel->setText( " "+title+" " );
674
675
}

676
void MainInterface::toggleTimeDisplay()
677
678
679
680
681
682
683
{
    b_remainingTime = ( b_remainingTime ? false : true );
}

void MainInterface::setElapsedTime(){ b_remainingTime = false; }
void MainInterface::setRemainTime(){ b_remainingTime = true; }

684
685
686
687
688
689
690
691
692
693
694
695
696
void MainInterface::setName( QString name )
{
    input_name = name;
    nameLabel->setText( " " + name+" " );
}

void MainInterface::setStatus( int status )
{
    controls->setStatus( status );
    if( sysTray )
        updateSystrayMenu( status );
}

697
698
699
700
701
702
void MainInterface::setRate( int rate )
{
    QString str;
    str.setNum( ( 1000/(double)rate), 'f', 2 );
    str.append( "x" );
    speedLabel->setText( str );
703
    speedControl->updateControls( rate );
704
705
}

706
707
708
709
void MainInterface::updateOnTimer()
{
    /* \todo Make this event-driven */
    if( intf_ShouldDie( p_intf ) )
710
    {
711
712
        QApplication::closeAllWindows();
        QApplication::quit();
713
    }
714
    if( need_components_update )
715
    {
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
        doComponentsUpdate();
        need_components_update = false;
    }

    controls->updateOnTimer();
}

/*****************************************************************************
 * Systray Icon and Systray Menu
 *****************************************************************************/

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

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

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

    CONNECT( sysTray, activated(  QSystemTrayIcon::ActivationReason ),
            this, handleSystrayClick( QSystemTrayIcon::ActivationReason ) );
}

/**
 * Update the menu of the Systray Icon.
 * May be unneedded, since it just calls QVLCMenu::update
 * FIXME !!!
 **/
void MainInterface::updateSystrayMenu( int status )
{
    QVLCMenu::updateSystrayMenu( this, p_intf ) ;
}

/**
 * Updates the Systray Icon's menu and toggle the main interface
 */
void MainInterface::toggleUpdateSystrayMenu()
{
    if( isHidden() )
    {
        show();
        activateWindow();
    }
    else
    {
#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
        if( isActiveWindow() )
#endif
        {
            hide();
        }
786
        else
787
788
789
        {
            activateWindow();
        }
790
    }
791
    QVLCMenu::updateSystrayMenu( this, p_intf );
792
793
}

794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
void MainInterface::handleSystrayClick(
                                    QSystemTrayIcon::ActivationReason reason )
{
    switch( reason )
    {
        case QSystemTrayIcon::Trigger:
            toggleUpdateSystrayMenu();
            break;
        case QSystemTrayIcon::MiddleClick:
            sysTray->showMessage( qtr( "VLC media player" ),
                    qtr( "Control menu for the player" ),
                    QSystemTrayIcon::Information, 4000 );
            break;
    }
}

/**
 * Updates the name of the systray Icon tooltip.
 * Doesn't check if the systray exists, check before you call it.
 * FIXME !!! Fusion with next function ?
 **/
void MainInterface::updateSystrayTooltipName( QString name )
{
    if( name.isEmpty() )
    {
        sysTray->setToolTip( qtr( "VLC media player" ) );
    }
    else
    {
        sysTray->setToolTip( name );
824
        if( notificationEnabled )
825
826
827
828
        {
            sysTray->showMessage( qtr( "VLC media player" ), name,
                    QSystemTrayIcon::NoIcon, 4000 );
        }
829
830
831
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
    }
}

/**
 * Updates the status of the systray Icon tooltip.
 * Doesn't check if the systray exists, check before you call it.
 **/
void MainInterface::updateSystrayTooltipStatus( int i_status )
{
    switch( i_status )
    {
        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;
            }
    }
}
859
860

/************************************************************************
861
 * D&D Events
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
 ************************************************************************/
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 ) {
885
886
            playlist_Add( THEPL, qtu(s), NULL,
                          PLAYLIST_APPEND | (first ? PLAYLIST_GO:0),
887
                          PLAYLIST_END, VLC_TRUE, VLC_FALSE );
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
            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();
}

906
/************************************************************************
907
 * Events stuff
908
 ************************************************************************/
909
910
911
912
913
914
915
void MainInterface::customEvent( QEvent *event )
{
    if( event->type() == PLDockEvent_Type )
    {
        PlaylistDialog::killInstance();
        playlistEmbeddedFlag = true;
        menuBar()->clear();
916
        QVLCMenu::createMenuBar(this, p_intf, true, visualSelectorEnabled);
917
918
919
920
921
922
923
924
925
926
927
928
929
        togglePlaylist();
    }
    else if ( event->type() == SetVideoOnTopEvent_Type )
    {
        SetVideoOnTopQtEvent* p_event = (SetVideoOnTopQtEvent*)event;
        if( p_event->OnTop() )
            setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
        else
            setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint);
        show(); /* necessary to apply window flags?? */
    }
}

930
931
932
933
934
935
bool MainInterface::eventFilter(QObject *obj, QEvent *event)
{
    if( (obj == timeLabel) && (event->type() == QEvent::MouseButtonPress) ) toggleTimeDisplay();
}


936
937
void MainInterface::keyPressEvent( QKeyEvent *e )
{
938
    int i_vlck = qtEventToVLCKey( e );
939
940
    if( i_vlck >= 0 )
    {
941
        var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlck );
942
943
944
945
946
947
        e->accept();
    }
    else
        e->ignore();
}

948
949
void MainInterface::wheelEvent( QWheelEvent *e )
{
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
950
    int i_vlckey = qtWheelEventToVLCKey( e );
951
952
953
954
    var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlckey );
    e->accept();
}

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

961
962
963
/*****************************************************************************
 * Callbacks
 *****************************************************************************/
zorglub's avatar
zorglub committed
964
965
966
967
968
969
970
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 );
971
    QApplication::postEvent( THEDP, static_cast<QEvent*>(event) );
zorglub's avatar
zorglub committed
972
973
    return VLC_SUCCESS;
}
974
975
976
977
978
979
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

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