main_interface.cpp 10.3 KB
Newer Older
Clément Stenac's avatar
Clément Stenac committed
1 2 3
/*****************************************************************************
 * main_inteface.cpp : Main interface
 ****************************************************************************
4 5
 * Copyright (C) 2006 the VideoLAN team
 * $Id$
Clément Stenac's avatar
Clément Stenac 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"
Clément Stenac's avatar
Clément Stenac committed
24
#include "main_interface.hpp"
Clément Stenac's avatar
Clément Stenac committed
25
#include "input_manager.hpp"
26
#include "util/input_slider.hpp"
Clément Stenac's avatar
Clément Stenac committed
27
#include "util/qvlcframe.hpp"
Clément Stenac's avatar
Clément Stenac committed
28
#include "dialogs_provider.hpp"
29
#include "components/video_widget.hpp"
Clément Stenac's avatar
Clément Stenac committed
30
#include <QCloseEvent>
31
#include <assert.h>
Clément Stenac's avatar
Clément Stenac committed
32
#include <QPushButton>
Clément Stenac's avatar
Clément Stenac committed
33
#include <QStatusBar>
34
#include <QKeyEvent>
35
#include "menus.hpp"
36
#include <vlc_keys.h>
Clément Stenac's avatar
Clément Stenac committed
37

Clément Stenac's avatar
Clément Stenac committed
38
#ifdef WIN32
39
    #define PREF_W 410
Clément Stenac's avatar
Clément Stenac committed
40 41
    #define PREF_H 121
#else
42
    #define PREF_W 450
Clément Stenac's avatar
Clément Stenac committed
43 44
    #define PREF_H 125
#endif
Clément Stenac's avatar
Clément Stenac committed
45

46 47 48
static int InteractCallback( vlc_object_t *, const char *, vlc_value_t,
                             vlc_value_t, void *);

49
MainInterface::MainInterface( intf_thread_t *_p_intf ) : QVLCMW( _p_intf )
Clément Stenac's avatar
Clément Stenac committed
50
{
51 52 53
    /* All UI stuff */
    QWidget *main = new QWidget( this );
    setCentralWidget( main );
Clément Stenac's avatar
Clément Stenac committed
54
    setWindowTitle( QString::fromUtf8( _("VLC media player") ) );
55
    ui.setupUi( centralWidget() );
Clément Stenac's avatar
Icons  
Clément Stenac committed
56

57 58
    setFocusPolicy( Qt::StrongFocus );

Clément Stenac's avatar
Clément Stenac committed
59 60
    slider = new InputSlider( Qt::Horizontal, NULL );
    ui.hboxLayout->insertWidget( 0, slider );
Clément Stenac's avatar
Clément Stenac committed
61 62
    ui.prevButton->setText( "" );
    ui.nextButton->setText( "" );
Clément Stenac's avatar
Clément Stenac committed
63 64
    ui.playButton->setText( "" );
    ui.stopButton->setText( "" );
Clément Stenac's avatar
Icons  
Clément Stenac committed
65 66 67 68 69 70
    ui.prevButton->setIcon( QIcon( ":/pixmaps/previous.png" ) );
    ui.nextButton->setIcon( QIcon( ":/pixmaps/next.png" ) );
    ui.playButton->setIcon( QIcon( ":/pixmaps/play.png" ) );
    ui.stopButton->setIcon( QIcon( ":/pixmaps/stop.png" ) );
    ui.volLowLabel->setPixmap( QPixmap( ":/pixmaps/volume-low.png" ) );
    ui.volHighLabel->setPixmap( QPixmap( ":/pixmaps/volume-high.png" ) );
Clément Stenac's avatar
Clément Stenac committed
71
    ui.volumeSlider->setMaximum( 100 );
Clément Stenac's avatar
Clément Stenac committed
72
    ui.playlistButton->setText( "" );
73 74
    ui.playlistButton->setIcon( QIcon( ":/pixmaps/volume-low.png" ) );

Clément Stenac's avatar
Clément Stenac committed
75 76 77
    VolumeClickHandler *h = new VolumeClickHandler( this );
    ui.volLowLabel->installEventFilter(h);
    ui.volHighLabel->installEventFilter(h);
Clément Stenac's avatar
Icons  
Clément Stenac committed
78

Clément Stenac's avatar
Clément Stenac committed
79 80
    ui.volumeSlider->setFocusPolicy( Qt::NoFocus );

81
    QVLCMenu::createMenuBar( menuBar(), p_intf );
82

Clément Stenac's avatar
Clément Stenac committed
83 84
    timeLabel = new QLabel( 0 );
    nameLabel = new QLabel( 0 );
Clément Stenac's avatar
Clément Stenac committed
85 86 87 88
    statusBar()->addWidget( nameLabel, 4 );
    statusBar()->addPermanentWidget( timeLabel, 1 );

    resize ( PREF_W, PREF_H );
89
    if( config_GetInt( p_intf, "embedded" ) )
90
    {
91 92
        videoWidget = new VideoWidget( p_intf, config_GetInt( p_intf,
                                         "qt-always-video" ) ? true:false );
93 94 95 96 97 98
        if( config_GetInt( p_intf, "qt-always-video" ) )
        {
            QSettings settings( "VideoLAN", "VLC" );
            settings.beginGroup( "MainWindow" );
            videoSize = settings.value( "videoSize", QSize( 200, 200 ) ).
                                                toSize();
Clément Stenac's avatar
Clément Stenac committed
99
        }
100 101 102
        else
            videoSize = QSize( 1,1 );
        videoWidget->resize( videoSize );
103 104
        ui.vboxLayout->insertWidget( 0, videoWidget );
    }
105
    readSettings( "MainWindow" );
106

Clément Stenac's avatar
Clément Stenac committed
107
    addSize = QSize( ui.vboxLayout->margin() * 2, PREF_H );
108 109
    mainSize.setWidth( videoSize.width() + addSize.width() );
    mainSize.setHeight( videoSize.height() + addSize.height() );
110 111
    resize( mainSize );
    mainSize = size();
Clément Stenac's avatar
Icons  
Clément Stenac committed
112

Clément Stenac's avatar
Clément Stenac committed
113
    setMinimumSize( PREF_W, addSize.height() );
Clément Stenac's avatar
Clément Stenac committed
114 115

    /* Init input manager */
116
    MainInputManager::getInstance( p_intf );
Clément Stenac's avatar
Clément Stenac committed
117
    ON_TIMEOUT( updateOnTimer() );
Clément Stenac's avatar
Clément Stenac committed
118

Clément Stenac's avatar
Clément Stenac committed
119
    /* Volume control */
Clément Stenac's avatar
Clément Stenac committed
120
    CONNECT( ui.volumeSlider, valueChanged(int), this, updateVolume(int) );
Clément Stenac's avatar
Clément Stenac committed
121
    /* Connect the input manager to the GUI elements it manages */
Clément Stenac's avatar
Clément Stenac committed
122 123 124 125 126 127 128 129
    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 ) );
    CONNECT( slider, sliderDragged( float ),
             THEMIM->getIM(), sliderUpdate( float ) );
130

Clément Stenac's avatar
Clément Stenac committed
131
    /* Actions */
Clément Stenac's avatar
Clément Stenac committed
132 133 134 135 136
    BUTTONACT( ui.playButton, play() );
    BUTTONACT( ui.stopButton, stop() );
    BUTTONACT( ui.nextButton, next() );
    BUTTONACT( ui.prevButton, prev() );
    CONNECT( ui.playlistButton, clicked(), THEDP, playlistDialog() );
137 138 139 140

    var_Create( p_intf, "interaction", VLC_VAR_ADDRESS );
    var_AddCallback( p_intf, "interaction", InteractCallback, this );
    p_intf->b_interaction = VLC_TRUE;
Clément Stenac's avatar
Clément Stenac committed
141 142 143 144
}

MainInterface::~MainInterface()
{
145 146 147 148 149 150 151 152 153 154
    writeSettings( "MainWindow" );
    if( config_GetInt( p_intf, "qt-always-video" ) )
    {
        QSettings s("VideoLAN", "VLC" );
        s.beginGroup( "MainWindow" );
        s.setValue( "videoSize", videoSize );
        s.endGroup();
    }
    p_intf->b_interaction = VLC_FALSE;
    var_DelCallback( p_intf, "interaction", InteractCallback, this );
Clément Stenac's avatar
Clément Stenac committed
155
}
Clément Stenac's avatar
Clément Stenac committed
156

157
void MainInterface::resizeEvent( QResizeEvent *e )
158
{
159 160
    videoSize.setHeight( e->size().height() - addSize.height() );
    videoSize.setWidth( e->size().width() - addSize.width() );
161
    p_intf->p_sys->p_video->updateGeometry() ;
162 163
}

164 165 166
void MainInterface::keyPressEvent( QKeyEvent *e )
{
    int i_vlck = 0;
Clément Stenac's avatar
Clément Stenac committed
167
    /* Handle modifiers */
168 169 170 171 172 173 174 175
    if( e->modifiers()& Qt::ShiftModifier ) i_vlck |= KEY_MODIFIER_SHIFT;
    if( e->modifiers()& Qt::AltModifier ) i_vlck |= KEY_MODIFIER_ALT;
    if( e->modifiers()& Qt::ControlModifier ) i_vlck |= KEY_MODIFIER_CTRL;
    if( e->modifiers()& Qt::MetaModifier ) i_vlck |= KEY_MODIFIER_META;

    fprintf( stderr, "After modifiers %x\n", i_vlck );
    bool found = false;
    fprintf( stderr, "Qt %x\n", e->key() );
Clément Stenac's avatar
Clément Stenac committed
176 177
    /* Look for some special keys */
#define HANDLE( qt, vk ) case Qt::qt : i_vlck |= vk; found = true;break
178 179
    switch( e->key() )
    {
Clément Stenac's avatar
Clément Stenac committed
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205
        HANDLE( Key_Left, KEY_LEFT );
        HANDLE( Key_Right, KEY_RIGHT );
        HANDLE( Key_Up, KEY_UP );
        HANDLE( Key_Down, KEY_DOWN );
        HANDLE( Key_Space, KEY_SPACE );
        HANDLE( Key_Escape, KEY_ESC );
        HANDLE( Key_Enter, KEY_ENTER );
        HANDLE( Key_F1, KEY_F1 );
        HANDLE( Key_F2, KEY_F2 );
        HANDLE( Key_F3, KEY_F3 );
        HANDLE( Key_F4, KEY_F4 );
        HANDLE( Key_F5, KEY_F5 );
        HANDLE( Key_F6, KEY_F6 );
        HANDLE( Key_F7, KEY_F7 );
        HANDLE( Key_F8, KEY_F8 );
        HANDLE( Key_F9, KEY_F9 );
        HANDLE( Key_F10, KEY_F10 );
        HANDLE( Key_F11, KEY_F11 );
        HANDLE( Key_F12, KEY_F12 );
        HANDLE( Key_PageUp, KEY_PAGEUP );
        HANDLE( Key_PageDown, KEY_PAGEDOWN );
        HANDLE( Key_Home, KEY_HOME );
        HANDLE( Key_End, KEY_END );
        HANDLE( Key_Insert, KEY_INSERT );
        HANDLE( Key_Delete, KEY_DELETE );

206 207 208 209
    }
    fprintf( stderr, "After keys %x\n", i_vlck );
    if( !found )
    {
Clément Stenac's avatar
Clément Stenac committed
210
        /* Force lowercase */
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
        if( e->key() >= Qt::Key_A && e->key() <= Qt::Key_Z )
            i_vlck += e->key() + 32;
        /* Rest of the ascii range */
        else if( e->key() >= Qt::Key_Space && e->key() <= Qt::Key_AsciiTilde )
            i_vlck += e->key();
    }
    if( i_vlck >= 0 )
    {
        var_SetInteger( p_intf->p_vlc, "key-pressed", i_vlck );
        e->accept();
    }
    else
        e->ignore();
}

Clément Stenac's avatar
Clément Stenac committed
226 227
void MainInterface::stop()
{
228
    playlist_Stop( THEPL );
Clément Stenac's avatar
Clément Stenac committed
229 230 231
}
void MainInterface::play()
{
232 233 234 235 236 237 238 239
    if( !THEPL->i_size || !THEPL->i_enabled )
    {
        /* The playlist is empty, open a file requester */
        THEDP->openDialog();
        setStatus( 0 );
        return;
    }
    THEMIM->togglePlayPause();
Clément Stenac's avatar
Clément Stenac committed
240 241 242
}
void MainInterface::prev()
{
243
    playlist_Prev( THEPL );
Clément Stenac's avatar
Clément Stenac committed
244 245 246
}
void MainInterface::next()
{
247
    playlist_Next( THEPL );
Clément Stenac's avatar
Clément Stenac committed
248 249 250 251 252 253 254 255 256
}

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 );
257
    timeLabel->setText( " "+title+" " );
Clément Stenac's avatar
Clément Stenac committed
258 259 260 261
}

void MainInterface::setName( QString name )
{
262
    nameLabel->setText( " " + name+" " );
Clément Stenac's avatar
Clément Stenac committed
263 264
}

265 266
void MainInterface::setStatus( int status )
{
Clément Stenac's avatar
Clément Stenac committed
267
    if( status == 1 ) // Playing
268 269 270 271 272
        ui.playButton->setIcon( QIcon( ":/pixmaps/pause.png" ) );
    else
        ui.playButton->setIcon( QIcon( ":/pixmaps/play.png" ) );
}

Clément Stenac's avatar
Clément Stenac committed
273 274
static bool b_my_volume;

Clément Stenac's avatar
Clément Stenac committed
275 276
void MainInterface::updateOnTimer()
{
Clément Stenac's avatar
Clément Stenac committed
277 278 279 280
    if( p_intf->b_die )
    {
        QApplication::quit();
    }
Clément Stenac's avatar
Clément Stenac committed
281 282 283 284 285 286 287 288 289 290 291
    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;
    }
Clément Stenac's avatar
Clément Stenac committed
292 293 294 295 296 297
}

void MainInterface::closeEvent( QCloseEvent *e )
{
    hide();
    p_intf->b_die = VLC_TRUE;
Clément Stenac's avatar
Clément Stenac committed
298
}
299

Clément Stenac's avatar
Clément Stenac committed
300 301 302 303 304 305 306 307 308 309
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 );
    }
}

310 311 312 313 314 315
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);
Clément Stenac's avatar
Clément Stenac committed
316

317 318
    MainInterface *p_interface = (MainInterface*)param;
    DialogEvent *event = new DialogEvent( INTF_DIALOG_INTERACTION, 0, p_arg );
319
    QApplication::postEvent( THEDP, static_cast<QEvent*>(event) );
320 321
    return VLC_SUCCESS;
}