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 );
415 416
    mainLayout->setMargin( 0 );

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

lukas.durfina's avatar
lukas.durfina committed
423 424 425 426 427 428
    /* 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" ) );

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

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

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

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

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

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

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

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

478
inline void MainInterface::askForPrivacy()
479 480 481 482
{
    /**
     * Ask for the network policy on FIRST STARTUP
     **/
483
    if( config_GetInt( p_intf, "qt-privacy-ask") )
484 485 486 487 488 489 490 491 492 493 494
    {
        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 );
            }

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

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

    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(
513
        "<p>The <i>VideoLAN Team</i> doesn't like when an application goes "
514
        "online without authorization.</p>\n "
515
        "<p><i>VLC media player</i> can request limited information on "
Konstantin Pavlov's avatar
Konstantin Pavlov committed
516
        "the Internet, especially to get CD covers and songs metadata or to know "
517
        "if updates are available.</p>\n"
518
        "<p><i>VLC media player</i> <b>DOES NOT</b> send or collect <b>ANY</b> "
Konstantin Pavlov's avatar
Konstantin Pavlov committed
519
        "information, even anonymously, about your usage.</p>\n"
520 521
        "<p>Therefore please check the following options, the default being "
        "almost no access on the web.</p>\n") );
522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541
    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 );  \
542
        controls.append( control );                               \
543 544 545 546 547 548 549 550
    }

#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 );  \
551
        controls.append( control );                               \
552 553 554 555
    }

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

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

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

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

569

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

/* 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.
578 579
   Maybe the other solution is to redefine the sizeHint() of the playlist and
   ask _parent->isFloating()...
580
   If you think this would be better, please FIXME it...
581
*/
582
#if 0
583 584
QSize MainInterface::sizeHint() const
{
585
    int nwidth  = controls->sizeHint().width();
586 587 588 589 590
    int nheight = controls->isVisible() ?
                  controls->size().height()
                  + menuBar()->size().height()
                  + statusBar()->size().height()
                  : 0 ;
591

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

636 637 638 639 640 641 642 643 644 645
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
646
    if( videoWidget && videoWidget->isVisible() )
647 648 649 650 651 652 653 654
    {
//    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();
}

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

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

    bool OnTop() const
    {
        return onTop;
    }

private:
    bool onTop;
};

683 684 685 686 687 688
/**
 * 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
 **/
689 690
/* function called from ::DoRequest in order to show a nice VideoWidget
    at the good size */
691 692 693 694
void *MainInterface::requestVideo( vout_thread_t *p_nvout, int *pi_x,
                                   int *pi_y, unsigned int *pi_width,
                                   unsigned int *pi_height )
{
695 696 697
    bool bgWasVisible = false;

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

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

        videoIsActive = true;
721 722

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

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

lukas.durfina's avatar
lukas.durfina committed
730 731 732 733 734 735 736
/* 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 );
}

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

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

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

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

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

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

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

826
        dockPL->show();
827
        playlistVisible = true;
828 829 830