X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fgui%2Fqt4%2Fmain_interface.cpp;h=e2248c0225e38bc460639be56f9d7bf46f867bb8;hb=138178799c514eec2286b4b4acd540e12cbbbd2f;hp=7251d2e59397f29651b516c955c5c1c4588f89a1;hpb=a06213d7f406c886dba790418ef8cca43d7ad140;p=vlc diff --git a/modules/gui/qt4/main_interface.cpp b/modules/gui/qt4/main_interface.cpp index 7251d2e593..e2248c0225 100644 --- a/modules/gui/qt4/main_interface.cpp +++ b/modules/gui/qt4/main_interface.cpp @@ -1,10 +1,11 @@ /***************************************************************************** - * main_inteface.cpp : Main interface + * main_interface.cpp : Main interface **************************************************************************** - * Copyright (C) 2006 the VideoLAN team + * Copyright (C) 2006-2007 the VideoLAN team * $Id$ * * Authors: Clément Stenac + * Jean-Baptiste Kempf * * 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 @@ -18,13 +19,14 @@ * * 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. *****************************************************************************/ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + *****************************************************************************/ #include "qt4.hpp" #include "main_interface.hpp" #include "input_manager.hpp" -#include "util/input_slider.hpp" #include "util/qvlcframe.hpp" +#include "util/customwidgets.hpp" #include "dialogs_provider.hpp" #include "components/interface_widgets.hpp" #include "dialogs/playlist.hpp" @@ -35,28 +37,35 @@ #include #include #include +#include +#include +#include +#include +#include #include #include -#include -#include +#include #ifdef WIN32 #define PREF_W 410 #define PREF_H 121 #else #define PREF_W 450 - #define PREF_H 125 + #define PREF_H 160 #endif -#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() +/* 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 ); static int InteractCallback( vlc_object_t *, const char *, vlc_value_t, vlc_value_t, void *); /* Video handling */ @@ -74,71 +83,167 @@ 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 ); } -bool embeddedPlaylistWasActive; -bool videoIsActive; -QSize savedVideoSize; - MainInterface::MainInterface( intf_thread_t *_p_intf ) : QVLCMW( _p_intf ) { - settings = new QSettings( "VideoLAN", "VLC" ); - settings->beginGroup( "MainWindow" ); - + /* Variables initialisation */ need_components_update = false; bgWidget = NULL; videoWidget = NULL; playlistWidget = NULL; embeddedPlaylistWasActive = videoIsActive = false; + input_name = ""; - /* Fetch configuration from settings and vlc config */ + /** + * Configuration and settings + **/ + settings = new QSettings( "VideoLAN", "VLC" ); + settings->beginGroup( "MainWindow" ); + + /* Main settings */ + setFocusPolicy( Qt::StrongFocus ); + setAcceptDrops(true); + setWindowIcon( QApplication::windowIcon() ); + setWindowOpacity( config_GetFloat( p_intf, "qt-opacity" ) ); + + /* Set The Video In emebedded Mode or not */ videoEmbeddedFlag = false; if( config_GetInt( p_intf, "embedded-video" ) ) videoEmbeddedFlag = true; alwaysVideoFlag = false; - if( videoEmbeddedFlag && config_GetInt( p_intf, "qt-always-video" )) + if( videoEmbeddedFlag && config_GetInt( p_intf, "qt-always-video" ) ) alwaysVideoFlag = true; - playlistEmbeddedFlag = settings->value( "playlist-embedded", true ). - toBool(); - advControlsEnabled= settings->value( "adv-controls", false ).toBool(); - - setWindowTitle( QString::fromUtf8( _("VLC media player") ) ); + /* Set the other interface settings */ + playlistEmbeddedFlag = settings->value( "playlist-embedded", true).toBool(); + visualSelectorEnabled = settings->value( "visual-selector", false ).toBool(); + notificationEnabled = config_GetInt( p_intf, "qt-notification" ) + ? true : false; + /************************** + * UI and Widgets design + **************************/ + setVLCWindowsTitle(); handleMainUi( settings ); + /* Menu Bar */ QVLCMenu::createMenuBar( this, p_intf, playlistEmbeddedFlag, - advControlsEnabled ); - - /* Status bar */ - timeLabel = new QLabel( 0 ); - nameLabel = new QLabel( 0 ); - statusBar()->addWidget( nameLabel, 4 ); - statusBar()->addPermanentWidget( timeLabel, 1 ); + isAdvancedVisible(), visualSelectorEnabled ); + + /* Status Bar */ + /** + * TODO: clicking on the elapsed time should switch to the remaining time + **/ + /** + * TODO: do we add a label for the current Volume ? + **/ + b_remainingTime = false; + timeLabel = new QLabel; + nameLabel = new QLabel; + speedLabel = new QLabel( "1.0x" ); + timeLabel->setFrameStyle( QFrame::Sunken | QFrame::Panel ); + speedLabel->setFrameStyle( QFrame::Sunken | QFrame::Panel ); + statusBar()->addWidget( nameLabel, 8 ); + statusBar()->addPermanentWidget( speedLabel, 0 ); + statusBar()->addPermanentWidget( timeLabel, 2 ); + speedLabel->setContextMenuPolicy ( Qt::CustomContextMenu ); + timeLabel->setContextMenuPolicy ( Qt::CustomContextMenu ); + timeLabel->installEventFilter( this ); + CONNECT( speedLabel, customContextMenuRequested( QPoint ), + this, showSpeedMenu( QPoint ) ); + CONNECT( timeLabel, customContextMenuRequested( QPoint ), + this, showTimeMenu( QPoint ) ); + + /********************** + * Systray Management * + **********************/ + sysTray = NULL; + bool b_createSystray = false; + bool b_systrayAvailable = QSystemTrayIcon::isSystemTrayAvailable(); + if( config_GetInt( p_intf, "qt-start-minimized") ) + { + if( b_systrayAvailable ){ + b_createSystray = true; + hide(); //FIXME + } + else msg_Warn( p_intf, "You can't minize if you haven't a system " + "tray bar" ); + } + if( config_GetInt( p_intf, "qt-system-tray") ) + b_createSystray = true; - setFocusPolicy( Qt::StrongFocus ); + if( b_systrayAvailable && b_createSystray ) + createSystray(); /* Init input manager */ MainInputManager::getInstance( p_intf ); ON_TIMEOUT( updateOnTimer() ); - /* Volume control */ - CONNECT( ui.volumeSlider, valueChanged(int), this, updateVolume(int) ); + /** + * Various CONNECTs + **/ + /* Connect the input manager to the GUI elements it manages */ - CONNECT( THEMIM->getIM(), positionUpdated( float, int, int ), - slider, setPosition( float,int, int ) ); + /* It is also connected to the control->slider, see the ControlsWidget */ CONNECT( THEMIM->getIM(), positionUpdated( float, int, int ), this, setDisplay( float, int, int ) ); - CONNECT( THEMIM->getIM(), nameChanged( QString ), this,setName( QString ) ); + + /** Connects on nameChanged() */ + /* Naming in the controller statusbar */ + CONNECT( THEMIM->getIM(), nameChanged( QString ), this, + setName( QString ) ); + /* and in the systray */ + if( sysTray ) + { + CONNECT( THEMIM->getIM(), nameChanged( QString ), this, + updateSystrayTooltipName( QString ) ); + } + /* and in the title of the controller */ + if( config_GetInt( p_intf, "qt-name-in-title" ) ) + { + CONNECT( THEMIM->getIM(), nameChanged( QString ), this, + setVLCWindowsTitle( QString ) ); + } + + /** CONNECTS on PLAY_STATUS **/ + /* Status on the main controller */ CONNECT( THEMIM->getIM(), statusChanged( int ), this, setStatus( int ) ); - CONNECT( slider, sliderDragged( float ), - THEMIM->getIM(), sliderUpdate( float ) ); + /* and in the systray */ + if( sysTray ) + { + CONNECT( THEMIM->getIM(), statusChanged( int ), this, + updateSystrayTooltipStatus( int ) ); + } + /** + * Callbacks + **/ var_Create( p_intf, "interaction", VLC_VAR_ADDRESS ); var_AddCallback( p_intf, "interaction", InteractCallback, this ); p_intf->b_interaction = VLC_TRUE; + + /* 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 ); + } } MainInterface::~MainInterface() { + /* 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 ); + } + settings->setValue( "playlist-embedded", playlistEmbeddedFlag ); - settings->setValue( "adv-controls", advControlsEnabled ); + settings->setValue( "adv-controls", isAdvancedVisible() ); settings->setValue( "pos", pos() ); settings->endGroup(); delete settings; @@ -150,77 +255,90 @@ MainInterface::~MainInterface() p_intf->pf_control_window = NULL; } +/***************************** + * Main UI handling * + *****************************/ + +/** + * Give the decorations of the Main Window a correct Name. + * If nothing is given, set it to VLC... + **/ +void MainInterface::setVLCWindowsTitle( QString aTitle ) +{ + if( aTitle.isEmpty() ) + { + setWindowTitle( qtr( "VLC media player" ) ); + } + else + { + setWindowTitle( aTitle + " - " + qtr( "VLC media player" ) ); + } +} + + void MainInterface::handleMainUi( QSettings *settings ) { + /* Create the main Widget and the mainLayout */ QWidget *main = new QWidget( this ); + mainLayout = new QVBoxLayout( main ); setCentralWidget( main ); - ui.setupUi( centralWidget() ); - - slider = new InputSlider( Qt::Horizontal, NULL ); - ui.hboxLayout->insertWidget( 0, slider ); - - 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() ); - BUTTON_SET_ACT_I( ui.visualButton, "", stop.png, - qtr( "Audio visualizations" ), visual() ); - - /* Volume */ - ui.volMuteLabel->setPixmap( QPixmap( ":/pixmaps/volume-low.png" ) ); - ui.volumeSlider->setMaximum( 100 ); - ui.volMuteLabel->setToolTip( qtr( "Mute" ) ); - VolumeClickHandler *h = new VolumeClickHandler( p_intf, this ); - ui.volMuteLabel->installEventFilter(h); - ui.volumeSlider->setFocusPolicy( Qt::NoFocus ); - - BUTTON_SET_IMG( ui.playlistButton, "" ,volume-low.png, - playlistEmbeddedFlag ? qtr( "Show playlist" ) : - qtr( "Open playlist" ) ); - BUTTONACT( ui.playlistButton, playlist() ); - /* Set initial size */ - resize ( PREF_W, PREF_H ); + /* Margins, spacing */ + main->setContentsMargins( 0, 0, 0, 0 ); + mainLayout->setMargin( 0 ); - addSize = QSize( ui.vboxLayout->margin() * 2, PREF_H ); + /* Create the CONTROLS Widget */ + controls = new ControlsWidget( p_intf, + settings->value( "adv-controls", false ).toBool() ); - advControls = new ControlsWidget( p_intf ); - ui.vboxLayout->insertWidget( 0, advControls ); - advControls->updateGeometry(); - if( !advControlsEnabled ) advControls->hide(); - need_components_update = true; + /* Configure the Controls */ + BUTTON_SET_IMG( controls->playlistButton, "" , playlist_icon.png, + playlistEmbeddedFlag ? qtr( "Show playlist" ) : + qtr( "Open playlist" ) ); + BUTTONACT( controls->playlistButton, togglePlaylist() ); + + /* Add the controls Widget to the main Widget */ + mainLayout->addWidget( controls ); + + + /* Set initial size */ + resize( PREF_W, PREF_H ); + addSize = QSize( mainLayout->margin() * 2, PREF_H ); + /* Visualisation */ visualSelector = new VisualSelector( p_intf ); - ui.vboxLayout->insertWidget( 0, visualSelector ); + mainLayout->insertWidget( 0, visualSelector ); visualSelector->hide(); + /* And video Outputs */ if( alwaysVideoFlag ) { bgWidget = new BackgroundWidget( p_intf ); bgWidget->widgetSize = settings->value( "backgroundSize", - QSize( 200, 200 ) ).toSize(); + QSize( 300, 300 ) ).toSize(); bgWidget->resize( bgWidget->widgetSize ); bgWidget->updateGeometry(); - ui.vboxLayout->insertWidget( 0, bgWidget ); + mainLayout->insertWidget( 0, bgWidget ); } if( videoEmbeddedFlag ) { videoWidget = new VideoWidget( p_intf ); videoWidget->widgetSize = QSize( 1, 1 ); - videoWidget->resize( videoWidget->widgetSize ); - ui.vboxLayout->insertWidget( 0, videoWidget ); + //videoWidget->resize( videoWidget->widgetSize ); + mainLayout->insertWidget( 0, videoWidget ); p_intf->pf_request_window = ::DoRequest; p_intf->pf_release_window = ::DoRelease; p_intf->pf_control_window = ::DoControl; } + + /* Finish the sizing */ setMinimumSize( PREF_W, addSize.height() ); } /********************************************************************** - * Handling of the components + * Handling of sizing of the components **********************************************************************/ void MainInterface::calculateInterfaceSize() { @@ -235,13 +353,11 @@ void MainInterface::calculateInterfaceSize() { width = playlistWidget->widgetSize.width(); height = playlistWidget->widgetSize.height(); - fprintf( stderr, "Have %ix%i playlist\n", width, height ); } else if( videoIsActive ) { width = videoWidget->widgetSize.width() ; height = videoWidget->widgetSize.height(); - fprintf( stderr, "Video Size %ix%i\n", DS( videoWidget->widgetSize ) ); } else { @@ -250,23 +366,15 @@ void MainInterface::calculateInterfaceSize() } if( VISIBLE( visualSelector ) ) height += visualSelector->height(); - fprintf( stderr, "Adv %p - visible %i\n", advControls, advControls->isVisible() ); - if( VISIBLE( advControls) ) +/* if( VISIBLE( advControls) ) { - fprintf( stderr, "visible\n" ); height += advControls->sizeHint().height(); - } - - fprintf( stderr, "Adv height %i\n", advControls->sizeHint().height() ); - fprintf( stderr, "Setting to %ix%i\n", - width + addSize.width() , height + addSize.height() ); - + }*/ mainSize = QSize( width + addSize.width(), height + addSize.height() ); } void MainInterface::resizeEvent( QResizeEvent *e ) { - fprintf( stderr, "Resize event to %ix%i\n", DS( e->size() ) ); videoWidget->widgetSize.setWidth( e->size().width() - addSize.width() ); if( videoWidget && videoIsActive && videoWidget->widgetSize.height() > 1 ) { @@ -282,6 +390,27 @@ void MainInterface::resizeEvent( QResizeEvent *e ) } } +/**************************************************************************** + * Small right-click menus + ****************************************************************************/ +void MainInterface::showSpeedMenu( QPoint pos ) +{ + QMenu menu( this ); + menu.addAction( "Not Implemented Yet" ); + menu.exec( QCursor::pos() ); +} + +void MainInterface::showTimeMenu( QPoint pos ) +{ + QMenu menu( this ); + menu.addAction( qtr("Elapsed Time") , this, SLOT( setElapsedTime() ) ); + menu.addAction( qtr("Remaining Time") , this, SLOT( setRemainTime() ) ); + menu.exec( QCursor::pos() ); +} + +/**************************************************************************** + * Video Handling + ****************************************************************************/ void *MainInterface::requestVideo( vout_thread_t *p_nvout, int *pi_x, int *pi_y, unsigned int *pi_width, unsigned int *pi_height ) @@ -293,7 +422,7 @@ void *MainInterface::requestVideo( vout_thread_t *p_nvout, int *pi_x, if( VISIBLE( playlistWidget ) ) { embeddedPlaylistWasActive = true; - playlistWidget->hide(); +// playlistWidget->hide(); } bool bgWasVisible = false; if( VISIBLE( bgWidget) ) @@ -312,7 +441,7 @@ void *MainInterface::requestVideo( vout_thread_t *p_nvout, int *pi_x, // videoWidget->widgetSize = bgWidget->widgeTSize; videoWidget->widgetSize = QSize( *pi_width, *pi_height ); } - videoWidget->updateGeometry(); /// FIXME: Needed ? +// videoWidget->updateGeometry(); /// FIXME: Needed ? need_components_update = true; } return ret; @@ -333,6 +462,23 @@ void MainInterface::releaseVideo( void *p_win ) need_components_update = true; } +class SetVideoOnTopQtEvent : public QEvent +{ +public: + SetVideoOnTopQtEvent( bool _onTop ) : + QEvent( (QEvent::Type)SetVideoOnTopEvent_Type ), onTop( _onTop) + { + } + + bool OnTop() const + { + return onTop; + } + +private: + bool onTop; +}; + int MainInterface::controlVideo( void *p_window, int i_query, va_list args ) { int i_ret = VLC_EGENERIC; @@ -351,15 +497,19 @@ int MainInterface::controlVideo( void *p_window, int i_query, va_list args ) { unsigned int i_width = va_arg( args, unsigned int ); unsigned int i_height = va_arg( args, unsigned int ); -// if( !i_width && p_vout ) i_width = p_vout->i_window_width; -// if( !i_height && p_vout ) i_height = p_vout->i_window_height; videoWidget->widgetSize = QSize( i_width, i_height ); - videoWidget->updateGeometry(); + // videoWidget->updateGeometry(); need_components_update = true; i_ret = VLC_SUCCESS; break; } case VOUT_SET_STAY_ON_TOP: + { + int i_arg = va_arg( args, int ); + QApplication::postEvent( this, new SetVideoOnTopQtEvent( i_arg ) ); + i_ret = VLC_SUCCESS; + break; + } default: msg_Warn( p_intf, "unsupported control query" ); break; @@ -367,42 +517,15 @@ int MainInterface::controlVideo( void *p_window, int i_query, va_list args ) return i_ret; } -void MainInterface::advanced() -{ - if( !VISIBLE( advControls ) ) - { - advControls->show(); - advControlsEnabled = true; - } - else - { - advControls->hide(); - advControlsEnabled = false; - } - doComponentsUpdate(); -} - -void MainInterface::visual() -{ - if( !VISIBLE( visualSelector) ) - { - visualSelector->show(); - if( !THEMIM->getIM()->hasVideo() ) - { - /* Show the background widget */ - } - } - else - { - /* Stop any currently running visualization */ - visualSelector->hide(); - } - doComponentsUpdate(); -} - -void MainInterface::playlist() +/***************************************************************************** + * Playlist, Visualisation and Menus handling + *****************************************************************************/ +/** + * Toggle the playlist widget or dialog + **/ +void MainInterface::togglePlaylist() { - // Toggle the playlist dialog + // Toggle the playlist dialog if not embedded and return if( !playlistEmbeddedFlag ) { if( playlistWidget ) @@ -413,24 +536,30 @@ void MainInterface::playlist() return; } + // Create the playlist Widget and destroy the existing dialog if( !playlistWidget ) { PlaylistDialog::killInstance(); playlistWidget = new PlaylistWidget( p_intf ); - ui.vboxLayout->insertWidget( 0, playlistWidget ); + mainLayout->insertWidget( 0, playlistWidget ); playlistWidget->widgetSize = settings->value( "playlistSize", QSize( 650, 310 ) ).toSize(); playlistWidget->hide(); + if(bgWidget) + CONNECT( playlistWidget, artSet( QString ), bgWidget, setArt(QString) ); } - /// Todo, reset its size ? - if( VISIBLE( playlistWidget) ) + + // And toggle visibility + if( VISIBLE( playlistWidget ) ) { playlistWidget->hide(); + if( bgWidget ) bgWidget->show(); if( videoIsActive ) { videoWidget->widgetSize = savedVideoSize; videoWidget->resize( videoWidget->widgetSize ); videoWidget->updateGeometry(); + if( bgWidget ) bgWidget->hide(); } } else @@ -445,15 +574,8 @@ void MainInterface::playlist() } if( VISIBLE( bgWidget ) ) bgWidget->hide(); } - doComponentsUpdate(); -} -/* Video widget cannot do this synchronously as it runs in another thread */ -/* Well, could it, actually ? Probably dangerous ... */ -void MainInterface::doComponentsUpdate() -{ - calculateInterfaceSize(); - resize( mainSize ); + doComponentsUpdate(); } void MainInterface::undockPlaylist() @@ -462,12 +584,13 @@ void MainInterface::undockPlaylist() { playlistWidget->hide(); playlistWidget->deleteLater(); - ui.vboxLayout->removeWidget( playlistWidget ); + mainLayout->removeWidget( playlistWidget ); playlistWidget = NULL; playlistEmbeddedFlag = false; menuBar()->clear(); - QVLCMenu::createMenuBar( this, p_intf, false, advControlsEnabled ); + QVLCMenu::createMenuBar( this, p_intf, false, isAdvancedVisible(), + visualSelectorEnabled); if( videoIsActive ) { @@ -481,146 +604,91 @@ void MainInterface::undockPlaylist() } } -void MainInterface::customEvent( QEvent *event ) +#if 0 +void MainInterface::visual() { - if( event->type() == PLDockEvent_Type ) + if( !VISIBLE( visualSelector) ) { - PlaylistDialog::killInstance(); - playlistEmbeddedFlag = true; - menuBar()->clear(); - QVLCMenu::createMenuBar(this, p_intf, true, advControlsEnabled ); - playlist(); - } -} - -/************************************************************************ - * Other stuff - ************************************************************************/ -void MainInterface::keyPressEvent( QKeyEvent *e ) -{ - int i_vlck = 0; - /* Handle modifiers */ - 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; - - bool found = false; - /* Look for some special keys */ -#define HANDLE( qt, vk ) case Qt::qt : i_vlck |= vk; found = true;break - switch( e->key() ) - { - 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 ); - - } - if( !found ) - { - /* Force lowercase */ - 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(); + visualSelector->show(); + if( !THEMIM->getIM()->hasVideo() ) + { + /* Show the background widget */ + } + visualSelectorEnabled = true; } - if( i_vlck >= 0 ) + else { - var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlck ); - e->accept(); + /* Stop any currently running visualization */ + visualSelector->hide(); + visualSelectorEnabled = false; } - else - e->ignore(); + doComponentsUpdate(); } +#endif -void MainInterface::stop() +void MainInterface::toggleMenus() { - playlist_Stop( THEPL ); + msg_Dbg( p_intf, "I HAS HERE, HIDING YOUR MENUZ: \\_o<~~ coin coin" ); + TOGGLEV( controls ); + TOGGLEV( statusBar() ); + updateGeometry(); } -void MainInterface::play() + +/* Video widget cannot do this synchronously as it runs in another thread */ +/* Well, could it, actually ? Probably dangerous ... */ +void MainInterface::doComponentsUpdate() { - if( !THEPL->i_size || !THEPL->i_enabled ) - { - /* The playlist is empty, open a file requester */ - THEDP->simpleOpenDialog(); - setStatus( 0 ); - return; - } - THEMIM->togglePlayPause(); + calculateInterfaceSize(); + resize( mainSize ); } -void MainInterface::prev() + +void MainInterface::toggleAdvanced() { - playlist_Prev( THEPL ); + controls->toggleAdvanced(); } -void MainInterface::next() + +bool MainInterface::isAdvancedVisible() { - playlist_Next( THEPL ); + return controls->b_advancedVisible; } +/************************************************************************ + * Other stuff + ************************************************************************/ 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 ); - timeLabel->setText( " "+title+" " ); + secstotimestr( psz_time, b_remainingTime ? length - time : time ); + QString title; title.sprintf( "%s/%s", psz_time, psz_length ); + if( b_remainingTime ) timeLabel->setText( " -"+title+" " ); + else timeLabel->setText( " "+title+" " ); } +void MainInterface::toggleTimeDisplay() +{ + b_remainingTime = ( b_remainingTime ? false : true ); +} + +void MainInterface::setElapsedTime(){ b_remainingTime = false; } +void MainInterface::setRemainTime(){ b_remainingTime = true; } + void MainInterface::setName( QString name ) { + input_name = name; nameLabel->setText( " " + name+" " ); } void MainInterface::setStatus( int status ) { - if( status == 1 ) // Playing - ui.playButton->setIcon( QIcon( ":/pixmaps/pause.png" ) ); - else - ui.playButton->setIcon( QIcon( ":/pixmaps/play.png" ) ); + controls->setStatus( status ); + if( sysTray ) + updateSystrayMenu( status ); } -static bool b_my_volume; - void MainInterface::updateOnTimer() { - aout_instance_t *p_aout = (aout_instance_t *)vlc_object_find( p_intf, - VLC_OBJECT_AOUT, FIND_ANYWHERE ); - /* Todo: make this event-driven */ - if( p_aout ) - { - ui.visualButton->setEnabled( true ); - vlc_object_release( p_aout ); - } - else - ui.visualButton->setEnabled( false ); - - /* And this too */ - advControls->enableInput( THEMIM->getIM()->hasInput() ); - advControls->enableVideo( THEMIM->getIM()->hasVideo() ); - + /* \todo Make this event-driven */ if( intf_ShouldDie( p_intf ) ) { QApplication::closeAllWindows(); @@ -632,35 +700,251 @@ void MainInterface::updateOnTimer() need_components_update = false; } - 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 ) + controls->updateOnTimer(); +} + +/***************************************************************************** + * Systray Icon and Systray Menu + *****************************************************************************/ + +/** + * Create a SystemTray icon and a menu that would go with it. + * Connects to a click handler on the icon. + **/ +void MainInterface::createSystray() +{ + QIcon iconVLC = QIcon( QPixmap( ":/vlc128.png" ) ); + sysTray = new QSystemTrayIcon( iconVLC, this ); + sysTray->setToolTip( qtr( "VLC media player" )); + + systrayMenu = new QMenu( qtr( "VLC media player" ), this ); + systrayMenu->setIcon( iconVLC ); + + QVLCMenu::updateSystrayMenu( this, p_intf, true ); + sysTray->show(); + + CONNECT( sysTray, activated( QSystemTrayIcon::ActivationReason ), + this, handleSystrayClick( QSystemTrayIcon::ActivationReason ) ); +} + +/** + * Update the menu of the Systray Icon. + * May be unneedded, since it just calls QVLCMenu::update + * FIXME !!! + **/ +void MainInterface::updateSystrayMenu( int status ) +{ + QVLCMenu::updateSystrayMenu( this, p_intf ) ; +} + +/** + * Updates the Systray Icon's menu and toggle the main interface + */ +void MainInterface::toggleUpdateSystrayMenu() +{ + if( isHidden() ) + { + show(); + activateWindow(); + } + else + { +#ifdef WIN32 + /* check if any visible window is above vlc in the z-order, + * but ignore the ones always on top */ + WINDOWINFO wi; + HWND hwnd; + wi.cbSize = sizeof( WINDOWINFO ); + for( hwnd = GetNextWindow( internalWinId(), GW_HWNDPREV ); + hwnd && !IsWindowVisible( hwnd ); + hwnd = GetNextWindow( hwnd, GW_HWNDPREV ) ); + if( !hwnd || !GetWindowInfo( hwnd, &wi ) || + (wi.dwExStyle&WS_EX_TOPMOST) ) +#else + if( isActiveWindow() ) +#endif + { + hide(); + } + else + { + activateWindow(); + } + } + QVLCMenu::updateSystrayMenu( this, p_intf ); +} + +void MainInterface::handleSystrayClick( + QSystemTrayIcon::ActivationReason reason ) +{ + switch( reason ) { - b_my_volume = true; - ui.volumeSlider->setValue( i_volume ); - b_my_volume = false; + case QSystemTrayIcon::Trigger: + toggleUpdateSystrayMenu(); + break; + case QSystemTrayIcon::MiddleClick: + sysTray->showMessage( qtr( "VLC media player" ), + qtr( "Control menu for the player" ), + QSystemTrayIcon::Information, 4000 ); + break; } } -void MainInterface::closeEvent( QCloseEvent *e ) +/** + * Updates the name of the systray Icon tooltip. + * Doesn't check if the systray exists, check before you call it. + * FIXME !!! Fusion with next function ? + **/ +void MainInterface::updateSystrayTooltipName( QString name ) { - hide(); - p_intf->b_die = VLC_TRUE; + if( name.isEmpty() ) + { + sysTray->setToolTip( qtr( "VLC media player" ) ); + } + else + { + sysTray->setToolTip( name ); + if( notificationEnabled ) + { + sysTray->showMessage( qtr( "VLC media player" ), name, + QSystemTrayIcon::NoIcon, 4000 ); + } + } } -void MainInterface::updateVolume( int sliderVolume ) +/** + * Updates the status of the systray Icon tooltip. + * Doesn't check if the systray exists, check before you call it. + **/ +void MainInterface::updateSystrayTooltipStatus( int i_status ) { - if( !b_my_volume ) + switch( i_status ) { - int i_res = sliderVolume * AOUT_VOLUME_MAX / - (2*ui.volumeSlider->maximum() ); - aout_VolumeSet( p_intf, i_res ); + case 0: + { + sysTray->setToolTip( qtr( "VLC media player" ) ); + break; + } + case PLAYING_S: + { + sysTray->setToolTip( input_name ); + //+ " - " + qtr( "Playing" ) ); + break; + } + case PAUSE_S: + { + sysTray->setToolTip( input_name + " - " + + qtr( "Paused") ); + break; + } } } +/************************************************************************ + * D&D Events + ************************************************************************/ +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 ) { + playlist_Add( THEPL, qtu(s), NULL, + PLAYLIST_APPEND | (first ? PLAYLIST_GO:0), + PLAYLIST_END, VLC_TRUE, VLC_FALSE ); + 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(); +} + +/************************************************************************ + * Events stuff + ************************************************************************/ +void MainInterface::customEvent( QEvent *event ) +{ + if( event->type() == PLDockEvent_Type ) + { + PlaylistDialog::killInstance(); + playlistEmbeddedFlag = true; + menuBar()->clear(); + QVLCMenu::createMenuBar(this, p_intf, true, isAdvancedVisible(), + visualSelectorEnabled); + togglePlaylist(); + } + else if ( event->type() == SetVideoOnTopEvent_Type ) + { + SetVideoOnTopQtEvent* p_event = (SetVideoOnTopQtEvent*)event; + if( p_event->OnTop() ) + setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); + else + setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint); + show(); /* necessary to apply window flags?? */ + } +} + +bool MainInterface::eventFilter(QObject *obj, QEvent *event) +{ + if( (obj == timeLabel) && (event->type() == QEvent::MouseButtonPress) ) toggleTimeDisplay(); +} + + +void MainInterface::keyPressEvent( QKeyEvent *e ) +{ + int i_vlck = qtEventToVLCKey( e ); + if( i_vlck >= 0 ) + { + var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlck ); + e->accept(); + } + else + e->ignore(); +} + +void MainInterface::wheelEvent( QWheelEvent *e ) +{ + int i_vlckey = qtWheelEventToVLCKey( e ); + var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlckey ); + e->accept(); +} + +void MainInterface::closeEvent( QCloseEvent *e ) +{ + hide(); + vlc_object_kill( p_intf ); +} + +/***************************************************************************** + * Callbacks + *****************************************************************************/ static int InteractCallback( vlc_object_t *p_this, const char *psz_var, vlc_value_t old_val, vlc_value_t new_val, void *param ) @@ -671,3 +955,34 @@ static int InteractCallback( vlc_object_t *p_this, QApplication::postEvent( THEDP, static_cast(event) ); return VLC_SUCCESS; } + +/***************************************************************************** + * 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; +}