main_interface.cpp 39.1 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>
9
 *          Ilkka Ollakka <ileoo@videolan.org>
zorglub's avatar
zorglub committed
10 11 12 13 14 15 16 17 18 19 20 21 22
 *
 * 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
23
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
24
 *****************************************************************************/
25

26 27 28
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
zorglub's avatar
zorglub committed
29

30
#include "qt4.hpp"
zorglub's avatar
zorglub committed
31
#include "main_interface.hpp"
zorglub's avatar
zorglub committed
32
#include "input_manager.hpp"
zorglub's avatar
zorglub committed
33
#include "util/qvlcframe.hpp"
34
#include "util/customwidgets.hpp"
zorglub's avatar
zorglub committed
35
#include "dialogs_provider.hpp"
36
#include "components/interface_widgets.hpp"
37
#include "components/playlist/playlist.hpp"
38
#include "dialogs/extended.hpp"
39 40 41
#include "dialogs/playlist.hpp"
#include "menus.hpp"

zorglub's avatar
zorglub committed
42
#include <QMenuBar>
zorglub's avatar
zorglub committed
43
#include <QCloseEvent>
zorglub's avatar
zorglub committed
44
#include <QPushButton>
zorglub's avatar
zorglub committed
45
#include <QStatusBar>
46
#include <QKeyEvent>
zorglub's avatar
zorglub committed
47
#include <QUrl>
48
#include <QSystemTrayIcon>
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
49 50
#include <QSize>
#include <QMenu>
51
#include <QLabel>
52 53
#include <QSlider>
#include <QWidgetAction>
54
#if 0
55
#include <QDockWidget>
56
#endif
57
#include <QToolBar>
58
#include <QGroupBox>
59
#include <QDate>
60
#include <QProgressBar>
61 62

#include <assert.h>
63
#include <vlc_keys.h>
zorglub's avatar
zorglub committed
64
#include <vlc_vout.h>
zorglub's avatar
zorglub committed
65

66 67 68 69 70 71
#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()

72 73 74 75 76
/* 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
77 78
static int InteractCallback( vlc_object_t *, const char *, vlc_value_t,
                             vlc_value_t, void *);
79 80 81 82 83 84
/* 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 );
}
lukas.durfina's avatar
lukas.durfina committed
85 86 87 88 89 90 91 92

static void *DoNotEmbeddedRequest( intf_thread_t *p_intf, vout_thread_t *p_vout,
                        int *pi1, int *pi2, unsigned int*pi3,unsigned int*pi4)
{
    p_intf->p_sys->p_mi->requestNotEmbeddedVideo( p_vout );
    return NULL;
}

93 94 95 96
static void DoRelease( intf_thread_t *p_intf, void *p_win )
{
    return p_intf->p_sys->p_mi->releaseVideo( p_win );
}
lukas.durfina's avatar
lukas.durfina committed
97

98 99 100 101
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
102

zorglub's avatar
zorglub committed
103
MainInterface::MainInterface( intf_thread_t *_p_intf ) : QVLCMW( _p_intf )
zorglub's avatar
zorglub committed
104
{
105
    /* Variables initialisation */
106
    // need_components_update = false;
107 108
    bgWidget = NULL;
    videoWidget = NULL;
109 110
    playlistWidget = NULL;
    sysTray = NULL;
111
    videoIsActive = false;
112
    playlistVisible = false;
113
    input_name = "";
114

115
    /* Ask for privacy */
116
    askForPrivacy();
117

118
    /**
119
     *  Configuration and settings
120
     *  Pre-building of interface
121
     **/
122 123
    /* Main settings */
    setFocusPolicy( Qt::StrongFocus );
124
    setAcceptDrops( true );
125
    setWindowIcon( QApplication::windowIcon() );
126
    setWindowOpacity( config_GetFloat( p_intf, "qt-opacity" ) );
127 128

    /* Set The Video In emebedded Mode or not */
129
    videoEmbeddedFlag = config_GetInt( p_intf, "embedded-video" );
zorglub's avatar
zorglub committed
130

131
    /* Are we in the enhanced always-video mode or not ? */
132
    i_visualmode = config_GetInt( p_intf, "qt-display-mode" );
zorglub's avatar
zorglub committed
133

134
    /* Set the other interface settings */
135 136 137
    settings = new QSettings( "vlc", "vlc-qt-interface" );
    settings->beginGroup( "MainWindow" );

138
    //TODO: I don't like that code
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
139
    visualSelectorEnabled = settings->value( "visual-selector", false ).toBool();
140
    notificationEnabled = (bool)config_GetInt( p_intf, "qt-notification" );
141

142 143 144
    /**************************
     *  UI and Widgets design
     **************************/
145
    setVLCWindowsTitle();
146
    handleMainUi( settings );
147

148
#if 0
149
    /* Create a Dock to get the playlist */
150
    dockPL = new QDockWidget( qtr( "Playlist" ), this );
151
    dockPL->setSizePolicy( QSizePolicy::Preferred,
152
                           QSizePolicy::Expanding );
153
    dockPL->setFeatures( QDockWidget::AllDockWidgetFeatures );
154 155 156
    dockPL->setAllowedAreas( Qt::LeftDockWidgetArea
                           | Qt::RightDockWidgetArea
                           | Qt::BottomDockWidgetArea );
157
    dockPL->hide();
158
#endif
159

160
    /************
161
     * Menu Bar
162
     ************/
163
    QVLCMenu::createMenuBar( this, p_intf, visualSelectorEnabled );
164

165 166
    /* StatusBar Creation */
    createStatusBar();
167

168

169 170 171
    /********************
     * Input Manager    *
     ********************/
172
    MainInputManager::getInstance( p_intf );
173

174 175 176
    /**************************
     * Various CONNECTs on IM *
     **************************/
177
    /* Connect the input manager to the GUI elements it manages */
178

179
    /* It is also connected to the control->slider, see the ControlsWidget */
180
    CONNECT( THEMIM->getIM(), positionUpdated( float, int, int ),
181
             this, setDisplayPosition( float, int, int ) );
182
    /* Change the SpeedRate in the Status */
183
    CONNECT( THEMIM->getIM(), rateChanged( int ), this, setRate( int ) );
184

185 186
    /**
     * Connects on nameChanged()
187 188
     * Those connects are not merged because different options can trigger
     * them down.
189
     */
190
    /* Naming in the controller statusbar */
191 192
    CONNECT( THEMIM->getIM(), nameChanged( QString ), this,
             setName( QString ) );
193
    /* and in the systray */
194
    if( sysTray )
195 196
    {
        CONNECT( THEMIM->getIM(), nameChanged( QString ), this,
197
                 updateSystrayTooltipName( QString ) );
198
    }
199
    /* and in the title of the controller */
200 201 202 203 204 205
    if( config_GetInt( p_intf, "qt-name-in-title" ) )
    {
        CONNECT( THEMIM->getIM(), nameChanged( QString ), this,
             setVLCWindowsTitle( QString ) );
    }

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

218 219 220
    /* END CONNECTS ON IM */


221
    /** OnTimeOut **/
222 223
    /* TODO Remove this function, but so far, there is no choice because there
       is no intf-should-die variable */
224 225 226
    ON_TIMEOUT( updateOnTimer() );
    //ON_TIMEOUT( debug() );

227 228 229
    /**
     * Callbacks
     **/
230 231
    var_Create( p_intf, "interaction", VLC_VAR_ADDRESS );
    var_AddCallback( p_intf, "interaction", InteractCallback, this );
232
    p_intf->b_interaction = true;
233

234 235
    var_AddCallback( p_intf->p_libvlc, "intf-show", IntfShowCB, p_intf );

236
    /* Register callback for the intf-popupmenu variable */
237 238 239
    playlist_t *p_playlist = pl_Yield( p_intf );
    var_AddCallback( p_playlist, "intf-popupmenu", PopupMenuCB, p_intf );
    pl_Release( p_intf );
240

241
    /* VideoWidget connect mess to avoid different threads speaking to each other */
242 243
    CONNECT( this, askReleaseVideo( void * ),
             this, releaseVideoSlot( void * ) );
244
    CONNECT( this, askVideoToResize( unsigned int, unsigned int ),
245
             videoWidget, SetSizing( unsigned int, unsigned int ) );
246

247
    CONNECT( this, askUpdate(), this, doComponentsUpdate() );
248

249
    CONNECT( controls, advancedControlsToggled( bool ),
250
             this, doComponentsUpdate() );
251

lukas.durfina's avatar
lukas.durfina committed
252 253 254 255 256 257 258
    CONNECT( fullscreenControls, advancedControlsToggled( bool ),
             this, doComponentsUpdate() );

    CONNECT( THEMIM->getIM(), inputUnset(),
            fullscreenControls, unregFullscreenCallback() );


259
    /* Size and placement of interface */
260
    QVLCTools::restoreWidgetPosition(settings,this,QSize(350,60));
261 262


263
    /* Playlist */
264
    if( settings->value( "playlist-visible", 0 ).toInt() ) togglePlaylist();
265
    settings->endGroup();
266

267
    show();
268

269 270
    if( i_visualmode == QT_MINIMAL_MODE )
        toggleMinimalView();
271

272
    /* Update the geometry TODO: is it useful ?*/
273
    updateGeometry();
274 275 276 277 278

    /*****************************************************
     * End everything by creating the Systray Management *
     *****************************************************/
    initSystray();
279 280 281 282
}

MainInterface::~MainInterface()
{
283 284
    msg_Dbg( p_intf, "Destroying the main interface" );

285 286
    if( playlistWidget )
        playlistWidget->savingSettings( settings );
287

288
    settings->beginGroup( "MainWindow" );
289 290

    // settings->setValue( "playlist-floats", (int)(dockPL->isFloating()) );
291
    settings->setValue( "playlist-visible", (int)playlistVisible );
292
    settings->setValue( "adv-controls",
293
                        getControlsVisibilityStatus() & CONTROLS_ADVANCED );
294

295
    if( !videoIsActive )
296 297
        QVLCTools::saveWidgetPosition(settings, this);

298 299
    if( bgWidget )
        settings->setValue( "backgroundSize", bgWidget->size() );
300 301 302 303

    settings->endGroup();
    delete settings;

304 305
    var_DelCallback( p_intf->p_libvlc, "intf-show", IntfShowCB, p_intf );

306
    /* Unregister callback for the intf-popupmenu variable */
307 308 309
    playlist_t *p_playlist = pl_Yield( p_intf );
    var_DelCallback( p_playlist, "intf-popupmenu", PopupMenuCB, p_intf );
    pl_Release( p_intf );
310

311
    p_intf->b_interaction = false;
312
    var_DelCallback( p_intf, "interaction", InteractCallback, this );
313 314 315 316

    p_intf->pf_request_window = NULL;
    p_intf->pf_release_window = NULL;
    p_intf->pf_control_window = NULL;
317
    p_intf->p_sys->p_mi = NULL;
318 319
}

320 321 322
/*****************************
 *   Main UI handling        *
 *****************************/
323

324 325 326 327 328 329 330 331 332 333 334 335 336
inline void MainInterface::createStatusBar()
{
    /****************
     *  Status Bar  *
     ****************/
    /* Widgets Creation*/
    b_remainingTime = false;
    timeLabel = new TimeLabel;
    timeLabel->setText( " --:--/--:-- " );
    timeLabel->setAlignment( Qt::AlignRight | Qt::AlignVCenter );
    nameLabel = new QLabel;
    nameLabel->setTextInteractionFlags( Qt::TextSelectableByMouse
                                      | Qt::TextSelectableByKeyboard );
337
    speedLabel = new SpeedLabel( p_intf, "1.00x" );
338 339 340 341 342 343 344 345 346 347 348 349 350 351 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 379 380 381 382 383 384 385 386 387 388
    speedLabel->setContextMenuPolicy ( Qt::CustomContextMenu );

    /* Styling those labels */
    timeLabel->setFrameStyle( QFrame::Sunken | QFrame::Panel );
    speedLabel->setFrameStyle( QFrame::Sunken | QFrame::Panel );
    nameLabel->setFrameStyle( QFrame::Sunken | QFrame::StyledPanel);

    pgBar = new QProgressBar;
    pgBar->hide();

    /* and adding those */
    statusBar()->addWidget( nameLabel, 8 );
    statusBar()->addPermanentWidget( speedLabel, 0 );
    statusBar()->addPermanentWidget( pgBar, 0 );
    statusBar()->addPermanentWidget( timeLabel, 0 );

    /* timeLabel behaviour:
       - double clicking opens the goto time dialog
       - right-clicking and clicking just toggle between remaining and
         elapsed time.*/
    CONNECT( timeLabel, timeLabelClicked(), this, toggleTimeDisplay() );
    CONNECT( timeLabel, timeLabelDoubleClicked(), THEDP, gotoTimeDialog() );
    CONNECT( timeLabel, timeLabelDoubleClicked(), this, toggleTimeDisplay() );

    /* Speed Label behaviour:
       - right click gives the vertical speed slider */
    CONNECT( speedLabel, customContextMenuRequested( QPoint ),
             this, showSpeedMenu( QPoint ) );
}

inline void MainInterface::initSystray()
{
    bool b_createSystray = false;
    bool b_systrayAvailable = QSystemTrayIcon::isSystemTrayAvailable();
    if( config_GetInt( p_intf, "qt-start-minimized") )
    {
        if( b_systrayAvailable )
        {
            b_createSystray = true;
            hide();
        }
        else msg_Err( p_intf, "You can't minimize if you haven't a system "
                "tray bar" );
    }
    if( config_GetInt( p_intf, "qt-system-tray") )
        b_createSystray = true;

    if( b_systrayAvailable && b_createSystray )
            createSystray();
}

389 390 391 392
/**
 * Give the decorations of the Main Window a correct Name.
 * If nothing is given, set it to VLC...
 **/
393 394 395 396
void MainInterface::setVLCWindowsTitle( QString aTitle )
{
    if( aTitle.isEmpty() )
    {
397
        setWindowTitle( qtr( "VLC media player" ) );
398 399 400
    }
    else
    {
401
        setWindowTitle( aTitle + " - " + qtr( "VLC media player" ) );
402 403 404
    }
}

405 406
void MainInterface::handleMainUi( QSettings *settings )
{
407
    /* Create the main Widget and the mainLayout */
408
    QWidget *main = new QWidget;
409
    setCentralWidget( main );
410
    mainLayout = new QVBoxLayout( main );
411

412 413
    /* Margins, spacing */
    main->setContentsMargins( 0, 0, 0, 0 );
414
    main->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Maximum );
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
415
    mainLayout->setSpacing( 0 );
416 417
    mainLayout->setMargin( 0 );

418
    /* Create the CONTROLS Widget */
419
    /* bool b_shiny = config_GetInt( p_intf, "qt-blingbling" ); */
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
420
    controls = new ControlsWidget( p_intf, this,
421
                   settings->value( "adv-controls", false ).toBool(),
422
                   config_GetInt( p_intf, "qt-blingbling" ) );
423

lukas.durfina's avatar
lukas.durfina committed
424 425 426 427 428 429
    /* Create the FULLSCREEN CONTROLS Widget */
    /* bool b_shiny = config_GetInt( p_intf, "qt-blingbling" ); */
    fullscreenControls = new FullscreenControllerWidget( p_intf, this,
                   settings->value( "adv-controls", false ).toBool(),
                   config_GetInt( p_intf, "qt-blingbling" ) );

430
    /* Add the controls Widget to the main Widget */
Adrien Grand's avatar
Adrien Grand committed
431
    mainLayout->insertWidget( 0, controls, 0, Qt::AlignBottom );
432

433 434 435
    /* Create the Speed Control Widget */
    speedControl = new SpeedControlWidget( p_intf );
    speedControlMenu = new QMenu( this );
436 437

    QWidgetAction *widgetAction = new QWidgetAction( speedControl );
438 439
    widgetAction->setDefaultWidget( speedControl );
    speedControlMenu->addAction( widgetAction );
440

441
    /* Visualisation */
442 443
    /* Disabled for now, they SUCK */
    #if 0
444
    visualSelector = new VisualSelector( p_intf );
445
    mainLayout->insertWidget( 0, visualSelector );
446
    visualSelector->hide();
447
    #endif
448

449
    /* And video Outputs */
450 451
    if( i_visualmode == QT_ALWAYS_VIDEO_MODE ||
        i_visualmode == QT_MINIMAL_MODE )
452 453
    {
        bgWidget = new BackgroundWidget( p_intf );
454 455
        bgWidget->resize(
             settings->value( "backgroundSize", QSize( 300, 150 ) ).toSize() );
456
        bgWidget->updateGeometry();
457
        mainLayout->insertWidget( 0, bgWidget );
458
        CONNECT( this, askBgWidgetToToggle(), bgWidget, toggle() );
459 460
    }

461
    if( videoEmbeddedFlag )
462
    {
463
        videoWidget = new VideoWidget( p_intf );
464
        mainLayout->insertWidget( 0, videoWidget );
465

466 467 468
        p_intf->pf_request_window  = ::DoRequest;
        p_intf->pf_release_window  = ::DoRelease;
        p_intf->pf_control_window  = ::DoControl;
469
    }
lukas.durfina's avatar
lukas.durfina committed
470 471 472 473
    else
    {
        p_intf->pf_request_window  = ::DoNotEmbeddedRequest;
    }
474 475

    /* Finish the sizing */
476
    main->updateGeometry();
zorglub's avatar
zorglub committed
477 478
}

479
inline void MainInterface::askForPrivacy()
480 481 482 483
{
    /**
     * Ask for the network policy on FIRST STARTUP
     **/
484
    if( config_GetInt( p_intf, "qt-privacy-ask") )
485 486 487 488 489 490 491 492 493 494 495
    {
        QList<ConfigControl *> controls;
        if( privacyDialog( controls ) == QDialog::Accepted )
        {
            QList<ConfigControl *>::Iterator i;
            for(  i = controls.begin() ; i != controls.end() ; i++ )
            {
                ConfigControl *c = qobject_cast<ConfigControl *>(*i);
                c->doApply( p_intf );
            }

496
            config_PutInt( p_intf,  "qt-privacy-ask" , 0 );
497
            /* We have to save here because the user may not launch Prefs */
498 499 500 501 502
            config_SaveConfigFile( p_intf, NULL );
        }
    }
}

503
int MainInterface::privacyDialog( QList<ConfigControl *> controls )
504
{
505
    QDialog *privacy = new QDialog();
506 507 508 509 510 511 512 513

    privacy->setWindowTitle( qtr( "Privacy and Network policies" ) );

    QGridLayout *gLayout = new QGridLayout( privacy );

    QGroupBox *blabla = new QGroupBox( qtr( "Privacy and Network Warning" ) );
    QGridLayout *blablaLayout = new QGridLayout( blabla );
    QLabel *text = new QLabel( qtr(
514
        "<p>The <i>VideoLAN Team</i> doesn't like when an application goes "
515
        "online without authorization.</p>\n "
516
        "<p><i>VLC media player</i> can request limited information on "
Konstantin Pavlov's avatar
Konstantin Pavlov committed
517
        "the Internet, especially to get CD covers and songs metadata or to know "
518
        "if updates are available.</p>\n"
519
        "<p><i>VLC media player</i> <b>DOES NOT</b> send or collect <b>ANY</b> "
Konstantin Pavlov's avatar
Konstantin Pavlov committed
520
        "information, even anonymously, about your usage.</p>\n"
521 522
        "<p>Therefore please check the following options, the default being "
        "almost no access on the web.</p>\n") );
523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542
    text->setWordWrap( true );
    text->setTextFormat( Qt::RichText );

    blablaLayout->addWidget( text, 0, 0 ) ;

    QGroupBox *options = new QGroupBox;
    QGridLayout *optionsLayout = new QGridLayout( options );

    gLayout->addWidget( blabla, 0, 0, 1, 3 );
    gLayout->addWidget( options, 1, 0, 1, 3 );
    module_config_t *p_config;
    ConfigControl *control;
    int line = 0;

#define CONFIG_GENERIC( option, type )                            \
    p_config =  config_FindConfig( VLC_OBJECT(p_intf), option );  \
    if( p_config )                                                \
    {                                                             \
        control =  new type ## ConfigControl( VLC_OBJECT(p_intf), \
                p_config, options, false, optionsLayout, line );  \
543
        controls.append( control );                               \
544 545 546 547 548 549 550 551
    }

#define CONFIG_GENERIC_NOBOOL( option, type )                     \
    p_config =  config_FindConfig( VLC_OBJECT(p_intf), option );  \
    if( p_config )                                                \
    {                                                             \
        control =  new type ## ConfigControl( VLC_OBJECT(p_intf), \
                p_config, options, optionsLayout, line );  \
552
        controls.append( control );                               \
553 554 555 556
    }

    CONFIG_GENERIC( "album-art", IntegerList ); line++;
    CONFIG_GENERIC_NOBOOL( "fetch-meta", Bool ); line++;
557
#ifdef UPDATE_CHECK
558 559
    CONFIG_GENERIC_NOBOOL( "qt-updates-notif", Bool ); line++;
    CONFIG_GENERIC_NOBOOL( "qt-updates-days", Integer ); line++;
560
#endif
561

562 563 564 565 566
    QPushButton *ok = new QPushButton( qtr( "Ok" ) );

    gLayout->addWidget( ok, 2, 2 );

    CONNECT( ok, clicked(), privacy, accept() );
567
    return privacy->exec();
568 569
}

570

571
/**********************************************************************
572
 * Handling of sizing of the components
573
 **********************************************************************/
574 575 576 577 578

/* This function is probably wrong, but we don't have many many choices...
   Since we can't know from the playlist Widget if we are inside a dock or not,
   because the playlist Widget can be called by THEDP, as a separate windows for
   the skins.
579 580
   Maybe the other solution is to redefine the sizeHint() of the playlist and
   ask _parent->isFloating()...
581
   If you think this would be better, please FIXME it...
582
*/
583
#if 0
584 585
QSize MainInterface::sizeHint() const
{
586
    int nwidth  = controls->sizeHint().width();
587 588 589 590 591
    int nheight = controls->isVisible() ?
                  controls->size().height()
                  + menuBar()->size().height()
                  + statusBar()->size().height()
                  : 0 ;
592

593
    msg_Dbg( p_intf, "1 %i %i", nheight, nwidth );
594
    if( VISIBLE( bgWidget ) )
595 596 597
    {
        nheight += bgWidget->size().height();
        nwidth  = bgWidget->size().width();
598
        msg_Dbg( p_intf, "1b %i %i", nheight, nwidth );
599
    }
600
    else if( videoIsActive )
601 602 603 604 605
    {
        nheight += videoWidget->size().height();
        nwidth  = videoWidget->size().width();
        msg_Dbg( p_intf, "2 %i %i", nheight, nwidth );
    }
606
/*    if( !dockPL->isFloating() && dockPL->isVisible() && dockPL->widget()  )
607 608
    {
        nheight += dockPL->size().height();
609
        nwidth = __MAX( nwidth, dockPL->size().width() );
610
        msg_Dbg( p_intf, "3 %i %i", nheight, nwidth );
611
    }*/
612 613
    msg_Dbg( p_intf, "4 %i %i", nheight, nwidth );
    return QSize( nwidth, nheight );
614
}
615
#endif
616
#if 0
617
/* FIXME This is dead code and need to be removed AT THE END */
618 619
void MainInterface::resizeEvent( QResizeEvent *e )
{
620 621
    if( videoWidget )
        videoWidget->widgetSize.setWidth( e->size().width() - addSize.width() );
622 623 624 625 626 627 628 629
    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 ) )
    {
630 631
//        SET_WH( playlistWidget , e->size().width() - addSize.width(),
              //                   e->size().height() - addSize.height() );
632 633 634
        playlistWidget->updateGeometry();
    }
}
635
#endif
636

637 638 639 640 641 642 643 644 645 646
void MainInterface::requestLayoutUpdate()
{
    emit askUpdate();
}

//FIXME remove me at the end...
void MainInterface::debug()
{
    msg_Dbg( p_intf, "size: %i - %i", size().height(), size().width() );
    msg_Dbg( p_intf, "sizeHint: %i - %i", sizeHint().height(), sizeHint().width() );
Rafaël Carré's avatar
Rafaël Carré committed
647
    if( videoWidget && videoWidget->isVisible() )
648 649 650 651 652 653 654 655
    {
//    sleep( 10 );
    msg_Dbg( p_intf, "size: %i - %i", size().height(), size().width() );
    msg_Dbg( p_intf, "sizeHint: %i - %i", sizeHint().height(), sizeHint().width() );
    }
    adjustSize();
}

656
/****************************************************************************
657
 * Small right-click menu for rate control
658 659 660
 ****************************************************************************/
void MainInterface::showSpeedMenu( QPoint pos )
{
661
    speedControlMenu->exec( QCursor::pos() - pos
662
                          + QPoint( 0, speedLabel->height() ) );
663 664
}

665 666 667
/****************************************************************************
 * Video Handling
 ****************************************************************************/
668 669 670 671 672
class SetVideoOnTopQtEvent : public QEvent
{
public:
    SetVideoOnTopQtEvent( bool _onTop ) :
      QEvent( (QEvent::Type)SetVideoOnTopEvent_Type ), onTop( _onTop)
673
    {}
674 675 676 677 678 679 680 681 682 683

    bool OnTop() const
    {
        return onTop;
    }

private:
    bool onTop;
};

684 685 686 687 688 689
/**
 * README
 * README
 * Thou shall not call/resize/hide widgets from on another thread.
 * This is wrong, and this is TEH reason to emit signals on those Video Functions
 **/
690 691
/* function called from ::DoRequest in order to show a nice VideoWidget
    at the good size */
692 693 694 695
void *MainInterface::requestVideo( vout_thread_t *p_nvout, int *pi_x,
                                   int *pi_y, unsigned int *pi_width,
                                   unsigned int *pi_height )
{
696 697 698
    bool bgWasVisible = false;

    /* Request the videoWidget */
699
    void *ret = videoWidget->request( p_nvout,pi_x, pi_y, pi_width, pi_height );
700
    if( ret ) /* The videoWidget is available */
701
    {
702
        /* Did we have a bg ? Hide it! */
703
        if( VISIBLE( bgWidget) )
zorglub's avatar
zorglub committed
704
        {
705
            bgWasVisible = true;
706
            emit askBgWidgetToToggle();
zorglub's avatar
zorglub committed
707
        }
708

709
        /*if( THEMIM->getIM()->hasVideo() || !bgWasVisible )
710 711 712 713
        {
            videoWidget->widgetSize = QSize( *pi_width, *pi_height );
        }
        else /* Background widget available, use its size */
714
        /*{
715 716 717
            /* Ok, our visualizations are bad, so don't do this for the moment
             * use the requested size anyway */
            // videoWidget->widgetSize = bgWidget->widgeTSize;
718 719 720 721
          /*  videoWidget->widgetSize = QSize( *pi_width, *pi_height );
        }*/

        videoIsActive = true;
722 723

        emit askVideoToResize( *pi_width, *pi_height );
724
        emit askUpdate();
lukas.durfina's avatar
lukas.durfina committed
725 726

        fullscreenControls->regFullscreenCallback( p_nvout );
727
    }
728 729 730
    return ret;
}

lukas.durfina's avatar
lukas.durfina committed
731 732 733 734 735 736 737
/* function called from ::DoRequest in order to show a nice VideoWidget
    at the good size */
void MainInterface::requestNotEmbeddedVideo( vout_thread_t *p_nvout )
{
    fullscreenControls->regFullscreenCallback( p_nvout );
}

738
void MainInterface::releaseVideo( void *p_win )
739 740 741 742 743
{
    emit askReleaseVideo( p_win );
}

void MainInterface::releaseVideoSlot( void *p_win )
744 745
{
    videoWidget->release( p_win );
746
    videoWidget->hide();
zorglub's avatar
zorglub committed
747

748
    if( bgWidget )// WORONG
749
        bgWidget->show();
zorglub's avatar
zorglub committed
750

751
    adjustSize();
752 753 754
    videoIsActive = false;
}

755 756
int MainInterface::controlVideo( void *p_window, int i_query, va_list args )
{
757
    int i_ret = VLC_SUCCESS;
758 759 760 761 762 763
    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 * );
764 765
            *pi_width = videoWidget->videoSize.width();
            *pi_height = videoWidget->videoSize.height();
766 767 768 769 770 771
            break;
        }
        case VOUT_SET_SIZE:
        {
            unsigned int i_width  = va_arg( args, unsigned int );
            unsigned int i_height = va_arg( args, unsigned int );
772 773
            emit askVideoToResize( i_width, i_height );
            emit askUpdate();
774 775 776
            break;
        }
        case VOUT_SET_STAY_ON_TOP:
777 778 779 780 781
        {
            int i_arg = va_arg( args, int );
            QApplication::postEvent( this, new SetVideoOnTopQtEvent( i_arg ) );
            break;
        }
782
        default:
783
            i_ret = VLC_EGENERIC;
784 785 786 787 788 789
            msg_Warn( p_intf, "unsupported control query" );
            break;
    }
    return i_ret;
}

790 791 792 793 794 795 796
/*****************************************************************************
 * Playlist, Visualisation and Menus handling
 *****************************************************************************/
/**
 * Toggle the playlist widget or dialog
 **/
void MainInterface::togglePlaylist()
797
{
798 799
    THEDP->playlistDialog();
#if 0
800
    /* CREATION
801
    If no playlist exist, then create one and attach it to the DockPL*/
802 803
    if( !playlistWidget )
    {
804
        playlistWidget = new PlaylistWidget( p_intf, settings, dockPL );
805 806 807 808 809 810 811 812

        /* Add it to the parent DockWidget */
        dockPL->setWidget( playlistWidget );

        /* Add the dock to the main Interface */
        addDockWidget( Qt::BottomDockWidgetArea, dockPL );

        /* Make the playlist floating is requested. Default is not. */
813 814
        settings->beginGroup( "MainWindow" );
        if( settings->value( "playlist-floats", 1 ).toInt() )
815
        {
816
            msg_Dbg( p_intf, "we don't want the playlist inside");
817
            dockPL->setFloating( true );
818
        }
819
        settings->endGroup();
820 821
        settings->beginGroup( "playlist" );
        dockPL->move( settings->value( "pos", QPoint( 0,0 ) ).toPoint() );
822 823 824
        QSize newSize = settings->value( "size", QSize( 400, 300 ) ).toSize();
        if( newSize.isValid() )
            dockPL->resize( newSize );
825
        settings->endGroup();
826

827
        dockPL->show();
828
        playlistVisible = true;
Jean-Baptiste Kempf's avatar