main_interface.cpp 24.4 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 5
 * Copyright (C) 2006 the VideoLAN team
 * $Id$
zorglub's avatar
zorglub committed
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
 *
 * Authors: Clément Stenac <zorglub@videolan.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/

23
#include "qt4.hpp"
zorglub's avatar
zorglub committed
24
#include "main_interface.hpp"
zorglub's avatar
zorglub committed
25
#include "input_manager.hpp"
26
#include "util/input_slider.hpp"
zorglub's avatar
zorglub committed
27
#include "util/qvlcframe.hpp"
28
#include "util/customwidgets.hpp"
zorglub's avatar
zorglub committed
29
#include "dialogs_provider.hpp"
30
#include "components/interface_widgets.hpp"
31 32 33
#include "dialogs/playlist.hpp"
#include "menus.hpp"

zorglub's avatar
zorglub committed
34
#include <QMenuBar>
zorglub's avatar
zorglub committed
35
#include <QCloseEvent>
zorglub's avatar
zorglub committed
36
#include <QPushButton>
zorglub's avatar
zorglub committed
37
#include <QStatusBar>
38
#include <QKeyEvent>
zorglub's avatar
zorglub committed
39
#include <QUrl>
40 41

#include <assert.h>
42
#include <vlc_keys.h>
zorglub's avatar
zorglub committed
43
#include <vlc_vout.h>
zorglub's avatar
zorglub committed
44

zorglub's avatar
zorglub committed
45
#ifdef WIN32
zorglub's avatar
zorglub committed
46
    #define PREF_W 410
zorglub's avatar
zorglub committed
47 48
    #define PREF_H 121
#else
zorglub's avatar
zorglub committed
49
    #define PREF_W 450
zorglub's avatar
zorglub committed
50 51
    #define PREF_H 125
#endif
zorglub's avatar
zorglub committed
52

53 54 55 56 57 58 59 60
#define VISIBLE(i) (i && i->isVisible())

#define SET_WIDTH(i,j) i->widgetSize.setWidth(j)
#define SET_HEIGHT(i,j) i->widgetSize.setHeight(j)
#define SET_WH( i,j,k) i->widgetSize.setWidth(j); i->widgetSize.setHeight(k);

#define DS(i) i.width(),i.height()

61 62 63 64 65
/* 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
66 67
static int InteractCallback( vlc_object_t *, const char *, vlc_value_t,
                             vlc_value_t, void *);
68 69 70 71 72 73 74 75 76 77 78 79 80 81
/* 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
82

zorglub's avatar
zorglub committed
83
MainInterface::MainInterface( intf_thread_t *_p_intf ) : QVLCMW( _p_intf )
zorglub's avatar
zorglub committed
84
{
85
    /* Configuration */
86 87 88
    settings = new QSettings( "VideoLAN", "VLC" );
    settings->beginGroup( "MainWindow" );

89 90
    setWindowIcon( QApplication::windowIcon() );

91
    need_components_update = false;
92
    bgWidget = NULL; videoWidget = NULL; playlistWidget = NULL;
zorglub's avatar
zorglub committed
93
    embeddedPlaylistWasActive = videoIsActive = false;
94

zorglub's avatar
zorglub committed
95
    videoEmbeddedFlag = false;
96
    if( config_GetInt( p_intf, "embedded-video" ) ) videoEmbeddedFlag = true;
zorglub's avatar
zorglub committed
97 98 99 100 101

    alwaysVideoFlag = false;
    if( videoEmbeddedFlag && config_GetInt( p_intf, "qt-always-video" ))
        alwaysVideoFlag = true;

102
    playlistEmbeddedFlag = settings->value("playlist-embedded", true).toBool();
zorglub's avatar
zorglub committed
103
    advControlsEnabled= settings->value( "adv-controls", false ).toBool();
104
    visualSelectorEnabled= settings->value( "visual-selector", false ).toBool();
zorglub's avatar
zorglub committed
105

106
    /* UI */
107
    setWindowTitle( qtr( "VLC media player" ) );
108
    handleMainUi( settings );
zorglub's avatar
zorglub committed
109
    QVLCMenu::createMenuBar( this, p_intf, playlistEmbeddedFlag,
110
                             advControlsEnabled, visualSelectorEnabled );
111 112 113 114
    timeLabel = new QLabel( 0 );
    nameLabel = new QLabel( 0 );
    statusBar()->addWidget( nameLabel, 4 );
    statusBar()->addPermanentWidget( timeLabel, 1 );
zorglub's avatar
Icons  
zorglub committed
115

116
    setFocusPolicy( Qt::StrongFocus );
117
    setAcceptDrops(true);
118

119 120 121 122 123 124 125 126 127 128 129 130 131
    /* Init input manager */
    MainInputManager::getInstance( p_intf );
    ON_TIMEOUT( updateOnTimer() );

    /* Volume control */
    CONNECT( ui.volumeSlider, valueChanged(int), this, updateVolume(int) );
    /* Connect the input manager to the GUI elements it manages */
    CONNECT( THEMIM->getIM(), positionUpdated( float, int, int ),
             slider, setPosition( float,int, int ) );
    CONNECT( THEMIM->getIM(), positionUpdated( float, int, int ),
             this, setDisplay( float, int, int ) );
    CONNECT( THEMIM->getIM(), nameChanged( QString ), this,setName( QString ) );
    CONNECT( THEMIM->getIM(), statusChanged( int ), this, setStatus( int ) );
132
    CONNECT( THEMIM->getIM(), navigationChanged( int ), this, setNavigation(int) );
133 134 135
    CONNECT( slider, sliderDragged( float ),
             THEMIM->getIM(), sliderUpdate( float ) );

136 137 138 139 140 141 142
    CONNECT( ui.prevSectionButton, clicked(), THEMIM->getIM(),
             sectionPrev() );
    CONNECT( ui.nextSectionButton, clicked(), THEMIM->getIM(),
             sectionNext() );
    CONNECT( ui.menuButton, clicked(), THEMIM->getIM(),
             sectionMenu() );

143 144 145
    var_Create( p_intf, "interaction", VLC_VAR_ADDRESS );
    var_AddCallback( p_intf, "interaction", InteractCallback, this );
    p_intf->b_interaction = VLC_TRUE;
146 147 148 149 150 151 152 153 154 155

    /* Register callback for the intf-popupmenu variable */
    playlist_t *p_playlist =
        (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
    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 );
    }
156 157 158 159
}

MainInterface::~MainInterface()
{
160 161 162 163 164 165 166 167 168 169
    /* Unregister callback for the intf-popupmenu variable */
    playlist_t *p_playlist =
        (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
    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
170 171 172 173 174
    settings->setValue( "playlist-embedded", playlistEmbeddedFlag );
    settings->setValue( "adv-controls", advControlsEnabled );
    settings->setValue( "pos", pos() );
    settings->endGroup();
    delete settings;
175 176
    p_intf->b_interaction = VLC_FALSE;
    var_DelCallback( p_intf, "interaction", InteractCallback, this );
177 178 179 180

    p_intf->pf_request_window = NULL;
    p_intf->pf_release_window = NULL;
    p_intf->pf_control_window = NULL;
181 182 183 184 185 186 187 188
}

void MainInterface::handleMainUi( QSettings *settings )
{
    QWidget *main = new QWidget( this );
    setCentralWidget( main );
    ui.setupUi( centralWidget() );

zorglub's avatar
zorglub committed
189
    slider = new InputSlider( Qt::Horizontal, NULL );
190
    ui.vboxLayout->insertWidget( 0, slider );
191 192 193 194
    ui.discFrame->hide();
    BUTTON_SET_IMG( ui.prevSectionButton, "", previous.png, "" );
    BUTTON_SET_IMG( ui.nextSectionButton, "", next.png, "" );
    BUTTON_SET_IMG( ui.menuButton, "", previous.png, "" );
195

zorglub's avatar
zorglub committed
196 197 198 199 200
    BUTTON_SET_ACT_I( ui.prevButton, "" , previous.png,
                      qtr("Previous"), prev() );
    BUTTON_SET_ACT_I( ui.nextButton, "", next.png, qtr("Next"), next() );
    BUTTON_SET_ACT_I( ui.playButton, "", play.png, qtr("Play"), play() );
    BUTTON_SET_ACT_I( ui.stopButton, "", stop.png, qtr("Stop"), stop() );
201 202

    /* Volume */
203
    ui.volMuteLabel->setPixmap( QPixmap( ":/pixmaps/volume-low.png" ) );
zorglub's avatar
zorglub committed
204
    ui.volumeSlider->setMaximum( 100 );
205 206 207
    ui.volMuteLabel->setToolTip( qtr( "Mute" ) );
    VolumeClickHandler *h = new VolumeClickHandler( p_intf, this );
    ui.volMuteLabel->installEventFilter(h);
zorglub's avatar
zorglub committed
208 209
    ui.volumeSlider->setFocusPolicy( Qt::NoFocus );

210
    BUTTON_SET_IMG( ui.playlistButton, "" , playlist_icon.png,
zorglub's avatar
zorglub committed
211
                        playlistEmbeddedFlag ?  qtr( "Show playlist" ) :
zorglub's avatar
Cleanup  
zorglub committed
212
                                                qtr( "Open playlist" ) );
213
    BUTTONACT( ui.playlistButton, playlist() );
zorglub's avatar
zorglub committed
214

zorglub's avatar
zorglub committed
215
    /* Set initial size */
zorglub's avatar
zorglub committed
216
    resize ( PREF_W, PREF_H );
217

218
    addSize = QSize( ui.vboxLayout->margin() * 2, PREF_H );
219

zorglub's avatar
zorglub committed
220 221 222 223 224 225
    advControls = new ControlsWidget( p_intf );
    ui.vboxLayout->insertWidget( 0, advControls );
    advControls->updateGeometry();
    if( !advControlsEnabled ) advControls->hide();
    need_components_update = true;

226 227 228 229 230 231 232 233 234 235 236 237 238 239
    visualSelector = new VisualSelector( p_intf );
    ui.vboxLayout->insertWidget( 0, visualSelector );
    visualSelector->hide();

    if( alwaysVideoFlag )
    {
        bgWidget = new BackgroundWidget( p_intf );
        bgWidget->widgetSize = settings->value( "backgroundSize",
                                                QSize( 200, 200 ) ).toSize();
        bgWidget->resize( bgWidget->widgetSize );
        bgWidget->updateGeometry();
        ui.vboxLayout->insertWidget( 0, bgWidget );
    }

240
    if( videoEmbeddedFlag )
241
    {
242
        videoWidget = new VideoWidget( p_intf );
243
        videoWidget->widgetSize = QSize( 1, 1 );
244 245 246
        videoWidget->resize( videoWidget->widgetSize );
        ui.vboxLayout->insertWidget( 0, videoWidget );

247 248 249
        p_intf->pf_request_window  = ::DoRequest;
        p_intf->pf_release_window  = ::DoRelease;
        p_intf->pf_control_window  = ::DoControl;
250
    }
zorglub's avatar
zorglub committed
251
    setMinimumSize( PREF_W, addSize.height() );
zorglub's avatar
zorglub committed
252 253
}

254 255 256
/**********************************************************************
 * Handling of the components
 **********************************************************************/
257
void MainInterface::calculateInterfaceSize()
zorglub's avatar
zorglub committed
258
{
259
    int width = 0, height = 0;
260
    if( VISIBLE( bgWidget ) )
zorglub's avatar
zorglub committed
261
    {
262 263
        width = bgWidget->widgetSize.width();
        height = bgWidget->widgetSize.height();
zorglub's avatar
zorglub committed
264
        assert( !(playlistWidget && playlistWidget->isVisible() ) );
zorglub's avatar
zorglub committed
265
    }
266
    else if( VISIBLE( playlistWidget ) )
267
    {
268 269
        width = playlistWidget->widgetSize.width();
        height = playlistWidget->widgetSize.height();
270
    }
271 272 273 274 275
    else if( videoIsActive )
    {
        width =  videoWidget->widgetSize.width() ;
        height = videoWidget->widgetSize.height();
    }
zorglub's avatar
Cleanup  
zorglub committed
276 277 278 279 280
    else
    {
        width = PREF_W - addSize.width();
        height = PREF_H - addSize.height();
    }
281 282
    if( VISIBLE( visualSelector ) )
        height += visualSelector->height();
zorglub's avatar
zorglub committed
283 284 285 286
    if( VISIBLE( advControls) )
    {
        height += advControls->sizeHint().height();
    }
287
    mainSize = QSize( width + addSize.width(), height + addSize.height() );
zorglub's avatar
zorglub committed
288
}
zorglub's avatar
zorglub committed
289

zorglub's avatar
zorglub committed
290
void MainInterface::resizeEvent( QResizeEvent *e )
291
{
292 293
    videoWidget->widgetSize.setWidth(  e->size().width() - addSize.width() );
    if( videoWidget && videoIsActive && videoWidget->widgetSize.height() > 1 )
294
    {
295 296 297
        SET_WH( videoWidget, e->size().width() - addSize.width(),
                             e->size().height()  - addSize.height() );
        videoWidget->updateGeometry();
298
    }
299
    if( VISIBLE( playlistWidget ) )
300
    {
301 302 303
        SET_WH( playlistWidget , e->size().width() - addSize.width(),
                                 e->size().height() - addSize.height() );
        playlistWidget->updateGeometry();
304
    }
305 306
}

307 308 309 310 311
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 );
312 313 314
    if( ret )
    {
        videoIsActive = true;
315
        if( VISIBLE( playlistWidget ) )
316 317
        {
            embeddedPlaylistWasActive = true;
318
//            playlistWidget->hide();
319
        }
320 321
        bool bgWasVisible = false;
        if( VISIBLE( bgWidget) )
zorglub's avatar
zorglub committed
322
        {
323
            bgWasVisible = true;
324
//            bgWidget->hide();
zorglub's avatar
zorglub committed
325
        }
326 327 328 329 330 331 332 333 334 335 336
        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 );
        }
337
//        videoWidget->updateGeometry(); /// FIXME: Needed ?
338 339
        need_components_update = true;
    }
340 341 342 343 344 345
    return ret;
}

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

349
    if( embeddedPlaylistWasActive )
350
        ;//playlistWidget->show();
zorglub's avatar
zorglub committed
351
    else if( bgWidget )
352
        ;//bgWidget->show();
zorglub's avatar
zorglub committed
353

354
    videoIsActive = false;
355
    need_components_update = true;
356 357
}

358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374
class SetVideoOnTopQtEvent : public QEvent
{
public:
    SetVideoOnTopQtEvent( bool _onTop ) :
      QEvent( (QEvent::Type)SetVideoOnTopEvent_Type ), onTop( _onTop)
    {
    }

    bool OnTop() const
    {
        return onTop;
    }

private:
    bool onTop;
};

375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393
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 );
394
            // videoWidget->updateGeometry();
395 396 397 398 399
            need_components_update = true;
            i_ret = VLC_SUCCESS;
            break;
        }
        case VOUT_SET_STAY_ON_TOP:
400 401 402 403 404 405
        {
            int i_arg = va_arg( args, int );
            QApplication::postEvent( this, new SetVideoOnTopQtEvent( i_arg ) );
            i_ret = VLC_SUCCESS;
            break;
        }
406 407 408 409 410 411 412
        default:
            msg_Warn( p_intf, "unsupported control query" );
            break;
    }
    return i_ret;
}

zorglub's avatar
zorglub committed
413 414 415 416 417 418 419 420 421 422 423 424 425 426 427
void MainInterface::advanced()
{
    if( !VISIBLE( advControls ) )
    {
        advControls->show();
        advControlsEnabled = true;
    }
    else
    {
        advControls->hide();
        advControlsEnabled = false;
    }
    doComponentsUpdate();
}

428 429 430 431 432 433 434 435 436
void MainInterface::visual()
{
    if( !VISIBLE( visualSelector) )
    {
        visualSelector->show();
        if( !THEMIM->getIM()->hasVideo() )
        {
            /* Show the background widget */
        }
437
        visualSelectorEnabled = true;
438 439 440 441 442
    }
    else
    {
        /* Stop any currently running visualization */
        visualSelector->hide();
443
        visualSelectorEnabled = false;
444
    }
445
    doComponentsUpdate();
446 447
}

448 449 450 451 452 453 454
void MainInterface::playlist()
{
    // Toggle the playlist dialog
    if( !playlistEmbeddedFlag )
    {
        if( playlistWidget )
        {
455
            /// \todo Destroy it
456 457 458 459 460 461 462 463 464 465 466
        }
        THEDP->playlistDialog();
        return;
    }

    if( !playlistWidget )
    {
        PlaylistDialog::killInstance();
        playlistWidget = new PlaylistWidget( p_intf );
        ui.vboxLayout->insertWidget( 0, playlistWidget );
        playlistWidget->widgetSize = settings->value( "playlistSize",
zorglub's avatar
zorglub committed
467
                                               QSize( 650, 310 ) ).toSize();
468
        playlistWidget->hide();
469
    }
470
    if( VISIBLE( playlistWidget ) )
471 472 473 474
    {
        playlistWidget->hide();
        if( videoIsActive )
        {
475 476 477
            videoWidget->widgetSize = savedVideoSize;
            videoWidget->resize( videoWidget->widgetSize );
            videoWidget->updateGeometry();
478 479 480 481 482 483
        }
    }
    else
    {
        playlistWidget->show();
        if( videoIsActive )
484 485 486 487 488 489
        {
            savedVideoSize = videoWidget->widgetSize;
            videoWidget->widgetSize.setHeight( 0 );
            videoWidget->resize( videoWidget->widgetSize );
            videoWidget->updateGeometry();
        }
490
        if( VISIBLE( bgWidget ) ) bgWidget->hide();
491
    }
492
    doComponentsUpdate();
493 494
}

zorglub's avatar
zorglub committed
495 496
/* Video widget cannot do this synchronously as it runs in another thread */
/* Well, could it, actually ? Probably dangerous ... */
497 498
void MainInterface::doComponentsUpdate()
{
499 500
    calculateInterfaceSize();
    resize( mainSize );
501 502
}

zorglub's avatar
zorglub committed
503
void MainInterface::undockPlaylist()
504
{
zorglub's avatar
zorglub committed
505
    if( playlistWidget )
506
    {
zorglub's avatar
zorglub committed
507 508
        playlistWidget->hide();
        playlistWidget->deleteLater();
509 510 511
        ui.vboxLayout->removeWidget( playlistWidget );
        playlistWidget = NULL;
        playlistEmbeddedFlag = false;
zorglub's avatar
zorglub committed
512

zorglub's avatar
zorglub committed
513
        menuBar()->clear();
514 515
        QVLCMenu::createMenuBar( this, p_intf, false, advControlsEnabled,
                                 visualSelectorEnabled);
zorglub's avatar
zorglub committed
516 517 518 519 520 521 522 523 524 525

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

        doComponentsUpdate();
        THEDP->playlistDialog();
526
    }
zorglub's avatar
zorglub committed
527 528 529 530 531
}

void MainInterface::customEvent( QEvent *event )
{
    if( event->type() == PLDockEvent_Type )
532 533 534
    {
        PlaylistDialog::killInstance();
        playlistEmbeddedFlag = true;
zorglub's avatar
zorglub committed
535
        menuBar()->clear();
536 537
        QVLCMenu::createMenuBar(this, p_intf, true, advControlsEnabled,
                                visualSelectorEnabled);
538 539
        playlist();
    }
540 541 542 543 544 545 546 547 548
    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?? */
    }
549 550
}

551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576

/************************************************************************
 * D&D
 ************************************************************************/
void MainInterface::dropEvent(QDropEvent *event)
{
     const QMimeData *mimeData = event->mimeData();

     /* D&D of a subtitles file, add it on the fly */
     if( mimeData->urls().size() == 1 )
     {
        if( THEMIM->getIM()->hasInput() )
        {
            if( input_AddSubtitles( THEMIM->getInput(),
                                    qtu( mimeData->urls()[0].toString() ),
                                    VLC_TRUE ) )
            {
                event->acceptProposedAction();
                return;
            }
        }
     }
     bool first = true;
     foreach( QUrl url, mimeData->urls() ) {
        QString s = url.toString();
        if( s.length() > 0 ) {
577 578
            playlist_Add( THEPL, qtu(s), NULL,
                          PLAYLIST_APPEND | (first ? PLAYLIST_GO:0),
579
                          PLAYLIST_END, VLC_TRUE, VLC_FALSE );
580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597
            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();
}

598 599 600
/************************************************************************
 * Other stuff
 ************************************************************************/
601 602
void MainInterface::keyPressEvent( QKeyEvent *e )
{
603
    int i_vlck = qtEventToVLCKey( e );
604 605
    if( i_vlck >= 0 )
    {
606
        var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlck );
607 608 609 610 611 612
        e->accept();
    }
    else
        e->ignore();
}

613 614
void MainInterface::wheelEvent( QWheelEvent *e )
{
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
615
    int i_vlckey = qtWheelEventToVLCKey( e );
616 617 618 619
    var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlckey );
    e->accept();
}

zorglub's avatar
zorglub committed
620 621
void MainInterface::stop()
{
622
    THEMIM->stop();
zorglub's avatar
zorglub committed
623 624 625
}
void MainInterface::play()
{
zorglub's avatar
zorglub committed
626
    if( playlist_IsEmpty(THEPL) )
627 628
    {
        /* The playlist is empty, open a file requester */
zorglub's avatar
Wtf ?  
zorglub committed
629
        THEDP->openFileDialog();
630 631 632 633
        setStatus( 0 );
        return;
    }
    THEMIM->togglePlayPause();
zorglub's avatar
zorglub committed
634 635 636
}
void MainInterface::prev()
{
637
    THEMIM->prev();
zorglub's avatar
zorglub committed
638 639 640
}
void MainInterface::next()
{
641
    THEMIM->next();
zorglub's avatar
zorglub committed
642 643 644 645 646 647 648 649 650
}

void MainInterface::setDisplay( float pos, int time, int length )
{
    char psz_length[MSTRTIME_MAX_SIZE], psz_time[MSTRTIME_MAX_SIZE];
    secstotimestr( psz_length, length );
    secstotimestr( psz_time, time );
    QString title;
    title.sprintf( "%s/%s", psz_time, psz_length );
651
    timeLabel->setText( " "+title+" " );
zorglub's avatar
zorglub committed
652 653 654 655
}

void MainInterface::setName( QString name )
{
656
    nameLabel->setText( " " + name+" " );
zorglub's avatar
zorglub committed
657 658
}

659 660
void MainInterface::setStatus( int status )
{
zorglub's avatar
zorglub committed
661
    if( status == 1 ) // Playing
662 663 664 665 666
        ui.playButton->setIcon( QIcon( ":/pixmaps/pause.png" ) );
    else
        ui.playButton->setIcon( QIcon( ":/pixmaps/play.png" ) );
}

667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695
#define HELP_MENU N_("Menu")
#define HELP_PCH N_("Previous chapter")
#define HELP_NCH N_("Next chapter")
#define HELP_PTR N_("Previous track")
#define HELP_NTR N_("Next track")

void MainInterface::setNavigation( int navigation )
{
    // 1 = chapter, 2 = title, 0 = no
    if( navigation == 0 )
    {
        ui.discFrame->hide();
    } else if( navigation == 1 ) {
        ui.prevSectionButton->show();
        ui.prevSectionButton->setToolTip( qfu(HELP_PCH) );
        ui.nextSectionButton->show();
        ui.nextSectionButton->setToolTip( qfu(HELP_NCH) );
        ui.menuButton->show();
        ui.discFrame->show();
    } else {
        ui.prevSectionButton->show();
        ui.prevSectionButton->setToolTip( qfu(HELP_PCH) );
        ui.nextSectionButton->show();
        ui.nextSectionButton->setToolTip( qfu(HELP_NCH) );
        ui.menuButton->hide();
        ui.discFrame->show();
    }
}

zorglub's avatar
zorglub committed
696 697
static bool b_my_volume;

zorglub's avatar
zorglub committed
698 699
void MainInterface::updateOnTimer()
{
700
    /* \todo Make this event-driven */
zorglub's avatar
zorglub committed
701 702 703
    advControls->enableInput( THEMIM->getIM()->hasInput() );
    advControls->enableVideo( THEMIM->getIM()->hasVideo() );

704
    if( intf_ShouldDie( p_intf ) )
zorglub's avatar
zorglub committed
705
    {
zorglub's avatar
zorglub committed
706
        QApplication::closeAllWindows();
zorglub's avatar
zorglub committed
707 708
        QApplication::quit();
    }
709 710 711 712 713 714
    if( need_components_update )
    {
        doComponentsUpdate();
        need_components_update = false;
    }

zorglub's avatar
zorglub committed
715 716 717 718 719 720 721 722 723 724 725
    audio_volume_t i_volume;
    aout_VolumeGet( p_intf, &i_volume );
    i_volume = (i_volume *  200 )/ AOUT_VOLUME_MAX ;
    int i_gauge = ui.volumeSlider->value();
    b_my_volume = false;
    if( i_volume - i_gauge > 1 || i_gauge - i_volume > 1 )
    {
        b_my_volume = true;
        ui.volumeSlider->setValue( i_volume );
        b_my_volume = false;
    }
zorglub's avatar
zorglub committed
726 727 728 729 730 731
}

void MainInterface::closeEvent( QCloseEvent *e )
{
    hide();
    p_intf->b_die = VLC_TRUE;
zorglub's avatar
zorglub committed
732
}
zorglub's avatar
zorglub committed
733

zorglub's avatar
zorglub committed
734 735 736 737 738 739 740 741 742 743
void MainInterface::updateVolume( int sliderVolume )
{
    if( !b_my_volume )
    {
        int i_res = sliderVolume * AOUT_VOLUME_MAX /
                            (2*ui.volumeSlider->maximum() );
        aout_VolumeSet( p_intf, i_res );
    }
}

zorglub's avatar
zorglub committed
744 745 746 747 748 749 750
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 );
751
    QApplication::postEvent( THEDP, static_cast<QEvent*>(event) );
zorglub's avatar
zorglub committed
752 753
    return VLC_SUCCESS;
}
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

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