vlc | branch: master | Francois Cartegnie <[email protected]> | Sun Jun 10 22:02:49 2018 +0200| [691c674bfff87d56618dda0b546f6a02feca78b0] | committer: Francois Cartegnie
Qt: split logically renderer widget and improve > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=691c674bfff87d56618dda0b546f6a02feca78b0 --- modules/gui/qt/Makefile.am | 5 + modules/gui/qt/actions_manager.cpp | 169 ----------------------- modules/gui/qt/actions_manager.hpp | 23 ---- modules/gui/qt/components/custom_menus.cpp | 198 +++++++++++++++++++++++++++ modules/gui/qt/components/custom_menus.hpp | 67 +++++++++ modules/gui/qt/main_interface.cpp | 3 + modules/gui/qt/managers/renderer_manager.cpp | 170 +++++++++++++++++++++++ modules/gui/qt/managers/renderer_manager.hpp | 87 ++++++++++++ modules/gui/qt/menus.cpp | 39 +----- modules/gui/qt/menus.hpp | 6 +- po/POTFILES.in | 2 + 11 files changed, 539 insertions(+), 230 deletions(-) diff --git a/modules/gui/qt/Makefile.am b/modules/gui/qt/Makefile.am index 6da5f5bc96..a37baeb1a9 100644 --- a/modules/gui/qt/Makefile.am +++ b/modules/gui/qt/Makefile.am @@ -48,6 +48,7 @@ libqt_plugin_la_SOURCES = \ gui/qt/actions_manager.cpp gui/qt/actions_manager.hpp \ gui/qt/extensions_manager.cpp gui/qt/extensions_manager.hpp \ gui/qt/managers/addons_manager.cpp gui/qt/managers/addons_manager.hpp \ + gui/qt/managers/renderer_manager.cpp gui/qt/managers/renderer_manager.hpp \ gui/qt/recents.cpp gui/qt/recents.hpp \ gui/qt/adapters/seekpoints.cpp gui/qt/adapters/seekpoints.hpp \ gui/qt/adapters/chromaprint.cpp gui/qt/adapters/chromaprint.hpp \ @@ -92,6 +93,8 @@ libqt_plugin_la_SOURCES = \ gui/qt/components/controller.cpp gui/qt/components/controller.hpp \ gui/qt/components/controller_widget.cpp \ gui/qt/components/controller_widget.hpp \ + gui/qt/components/custom_menus.cpp \ + gui/qt/components/custom_menus.hpp \ gui/qt/components/epg/EPGChannels.cpp \ gui/qt/components/epg/EPGChannels.hpp \ gui/qt/components/epg/EPGItem.cpp \ @@ -169,6 +172,7 @@ nodist_libqt_plugin_la_SOURCES = \ gui/qt/actions_manager.moc.cpp \ gui/qt/extensions_manager.moc.cpp \ gui/qt/managers/addons_manager.moc.cpp \ + gui/qt/managers/renderer_manager.moc.cpp \ gui/qt/recents.moc.cpp \ gui/qt/adapters/seekpoints.moc.cpp \ gui/qt/adapters/chromaprint.moc.cpp \ @@ -204,6 +208,7 @@ nodist_libqt_plugin_la_SOURCES = \ gui/qt/components/interface_widgets.moc.cpp \ gui/qt/components/controller.moc.cpp \ gui/qt/components/controller_widget.moc.cpp \ + gui/qt/components/custom_menus.moc.cpp \ gui/qt/components/epg/EPGChannels.moc.cpp \ gui/qt/components/epg/EPGProgram.moc.cpp \ gui/qt/components/epg/EPGRuler.moc.cpp \ diff --git a/modules/gui/qt/actions_manager.cpp b/modules/gui/qt/actions_manager.cpp index e614e424d0..4b9d4e6ad5 100644 --- a/modules/gui/qt/actions_manager.cpp +++ b/modules/gui/qt/actions_manager.cpp @@ -27,7 +27,6 @@ #include <vlc_vout.h> #include <vlc_actions.h> -#include <vlc_renderer_discovery.h> #include "actions_manager.hpp" @@ -40,28 +39,11 @@ ActionsManager::ActionsManager( intf_thread_t * _p_i ) : p_intf( _p_i ) - , m_scanning( false ) { - CONNECT( this, rendererItemAdded( vlc_renderer_item_t* ), - this, onRendererItemAdded( vlc_renderer_item_t* ) ); - CONNECT( this, rendererItemRemoved( vlc_renderer_item_t* ), - this, onRendererItemRemoved( vlc_renderer_item_t* ) ); - m_stop_scan_timer.setSingleShot( true ); - CONNECT( &m_stop_scan_timer, timeout(), this, StopRendererScan() ); } ActionsManager::~ActionsManager() { - StopRendererScan(); - /* reset the list of renderers */ - foreach (QAction* action, VLCMenuBar::rendererMenu->actions()) - { - QVariant data = action->data(); - if (!data.canConvert<QVariantHash>()) - continue; - VLCMenuBar::rendererMenu->removeAction(action); - VLCMenuBar::rendererGroup->removeAction(action); - } } void ActionsManager::doAction( int id_action ) @@ -224,154 +206,3 @@ void ActionsManager::skipBackward() if( p_input ) THEMIM->getIM()->jumpBwd(); } - -vlc_renderer_item_t* ActionsManager::getMatchingRenderer( const QVariant &obj, vlc_renderer_item_t* p_item ) -{ - if (!obj.canConvert<QVariantHash>()) - return NULL; - QVariantHash qvh = obj.value<QVariantHash>(); - if (!qvh.contains( "sout" )) - return NULL; - vlc_renderer_item_t* p_existing = - reinterpret_cast<vlc_renderer_item_t*>( qvh["sout"].value<void*>() ); - if ( !strcasecmp(vlc_renderer_item_sout( p_existing ), - vlc_renderer_item_sout( p_item ) ) ) - return p_existing; - return NULL; -} - -void ActionsManager::onRendererItemAdded(vlc_renderer_item_t* p_item) -{ - QAction *firstSeparator = NULL; - - foreach (QAction* action, VLCMenuBar::rendererMenu->actions()) - { - if (action->isSeparator()) - { - firstSeparator = action; - break; - } - if (getMatchingRenderer( action->data(), p_item )) - { - vlc_renderer_item_release( p_item ); - return; /* we already have this item */ - } - } - - QAction *action = new QAction( vlc_renderer_item_flags(p_item) & VLC_RENDERER_CAN_VIDEO ? QIcon( ":/sidebar/movie.svg" ) : QIcon( ":/sidebar/music.svg" ), - vlc_renderer_item_name(p_item), VLCMenuBar::rendererMenu ); - action->setCheckable(true); - - QVariantHash data; - data.insert( "sout", QVariant::fromValue( reinterpret_cast<void*>( p_item ) ) ); - action->setData( data ); - if (firstSeparator != NULL) - { - VLCMenuBar::rendererMenu->insertAction( firstSeparator, action ); - VLCMenuBar::rendererGroup->addAction(action); - } - else - { - vlc_renderer_item_release( p_item ); - delete action; - } -} - -void ActionsManager::onRendererItemRemoved( vlc_renderer_item_t* p_item ) -{ - foreach (QAction* action, VLCMenuBar::rendererMenu->actions()) - { - if (action->isSeparator()) - continue; - vlc_renderer_item_t *p_existing = getMatchingRenderer( action->data(), p_item ); - if (p_existing) - { - VLCMenuBar::rendererMenu->removeAction( action ); - VLCMenuBar::rendererGroup->removeAction( action ); - vlc_renderer_item_release( p_existing ); - break; - } - } - // Always release the item as we acquired it before emiting the signal - vlc_renderer_item_release( p_item ); -} - -void ActionsManager::renderer_event_item_added( vlc_renderer_discovery_t* p_rd, - vlc_renderer_item_t *p_item ) -{ - ActionsManager *self = reinterpret_cast<ActionsManager*>( p_rd->owner.sys ); - vlc_renderer_item_hold( p_item ); - self->emit rendererItemAdded( p_item ); -} - -void ActionsManager::renderer_event_item_removed( vlc_renderer_discovery_t *p_rd, - vlc_renderer_item_t *p_item ) -{ - ActionsManager *self = reinterpret_cast<ActionsManager*>( p_rd->owner.sys ); - vlc_renderer_item_hold( p_item ); - self->emit rendererItemRemoved( p_item ); -} - -void ActionsManager::StartRendererScan() -{ - m_stop_scan_timer.stop(); - if( m_scanning ) - return; - - /* SD subnodes */ - char **ppsz_longnames; - char **ppsz_names; - if( vlc_rd_get_names( THEPL, &ppsz_names, &ppsz_longnames ) != VLC_SUCCESS ) - return; - - struct vlc_renderer_discovery_owner owner = - { - this, - renderer_event_item_added, - renderer_event_item_removed, - }; - - char **ppsz_name = ppsz_names, **ppsz_longname = ppsz_longnames; - for( ; *ppsz_name; ppsz_name++, ppsz_longname++ ) - { - msg_Dbg( p_intf, "starting renderer discovery service %s", *ppsz_longname ); - vlc_renderer_discovery_t* p_rd = vlc_rd_new( VLC_OBJECT(p_intf), *ppsz_name, &owner ); - if( p_rd != NULL ) - m_rds.push_back( p_rd ); - free( *ppsz_name ); - free( *ppsz_longname ); - } - free( ppsz_names ); - free( ppsz_longnames ); - m_scanning = true; -} - -void ActionsManager::RendererMenuCountdown() -{ - m_stop_scan_timer.start( 20000 ); -} - -void ActionsManager::StopRendererScan() -{ - foreach ( vlc_renderer_discovery_t* p_rd, m_rds ) - vlc_rd_release( p_rd ); - m_rds.clear(); - m_scanning = false; -} - -void ActionsManager::RendererSelected( QAction *selected ) -{ - QVariant data = selected->data(); - vlc_renderer_item_t *p_item = NULL; - if (data.canConvert<QVariantHash>()) - { - QVariantHash hash = data.value<QVariantHash>(); - if ( hash.contains( "sout" ) ) - p_item = reinterpret_cast<vlc_renderer_item_t*>( - hash["sout"].value<void*>() ); - } - // If we failed to convert the action data to a vlc_renderer_item_t, - // assume the selected item was invalid, or most likely that "Local" was selected - playlist_SetRenderer( THEPL, p_item ); -} - diff --git a/modules/gui/qt/actions_manager.hpp b/modules/gui/qt/actions_manager.hpp index f82f6ee0aa..c244699d02 100644 --- a/modules/gui/qt/actions_manager.hpp +++ b/modules/gui/qt/actions_manager.hpp @@ -30,11 +30,8 @@ #include "qt.hpp" #include "util/singleton.hpp" -#include <QVector> #include <QObject> -#include <QTimer> -class QAction; typedef enum actionType_e { @@ -76,16 +73,6 @@ private: virtual ~ActionsManager(); intf_thread_t* const p_intf; - QVector<vlc_renderer_discovery_t*> m_rds; - QTimer m_stop_scan_timer; - bool m_scanning; - - static void renderer_event_item_added( vlc_renderer_discovery_t *, - vlc_renderer_item_t * ); - static void renderer_event_item_removed( vlc_renderer_discovery_t *, - vlc_renderer_item_t * ); - static vlc_renderer_item_t* getMatchingRenderer( const QVariant &m_obj, - vlc_renderer_item_t* p_item ); public slots: void toggleMuteAudio(); @@ -95,24 +82,14 @@ public slots: void record(); void skipForward(); void skipBackward(); - void StartRendererScan(); - void RendererMenuCountdown(); - void StopRendererScan(); - void RendererSelected( QAction * ); protected slots: - void onRendererItemAdded( vlc_renderer_item_t* ); - void onRendererItemRemoved( vlc_renderer_item_t* ); void fullscreen(); void snapshot(); void playlist(); void frame(); virtual void doAction( int ); - -signals: - void rendererItemAdded( vlc_renderer_item_t* ); - void rendererItemRemoved( vlc_renderer_item_t* ); }; #endif diff --git a/modules/gui/qt/components/custom_menus.cpp b/modules/gui/qt/components/custom_menus.cpp new file mode 100644 index 0000000000..c791d3da97 --- /dev/null +++ b/modules/gui/qt/components/custom_menus.cpp @@ -0,0 +1,198 @@ +/***************************************************************************** + * custom_menus.cpp : Qt custom menus classes + ***************************************************************************** + * Copyright © 2006-2018 VideoLAN authors + * 2018 VideoLabs + * + * 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. + *****************************************************************************/ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <vlc_common.h> +#include <vlc_renderer_discovery.h> + +#include "custom_menus.hpp" +#include "../managers/renderer_manager.hpp" + +#include <QMenu> +#include <QAction> +#include <QActionGroup> +#include <QWidgetAction> +#include <QVBoxLayout> +#include <QLabel> +#include <QProgressBar> + +RendererAction::RendererAction( vlc_renderer_item_t *p_item_ ) + : QAction() +{ + p_item = p_item_; + vlc_renderer_item_hold( p_item ); + if( vlc_renderer_item_flags( p_item ) & VLC_RENDERER_CAN_VIDEO ) + setIcon( QIcon( ":/sidebar/movie.svg" ) ); + else + setIcon( QIcon( ":/sidebar/music.svg" ) ); + setText( vlc_renderer_item_name( p_item ) ); + setCheckable(true); +} + +RendererAction::~RendererAction() +{ + vlc_renderer_item_release( p_item ); +} + +vlc_renderer_item_t * RendererAction::getItem() +{ + return p_item; +} + +RendererMenu::RendererMenu( QMenu *parent, intf_thread_t *p_intf_ ) + : QMenu( parent ), p_intf( p_intf_ ) +{ + setTitle( qtr("&Renderer") ); + + group = new QActionGroup( this ); + + QAction *action = new QAction( qtr("<Local>") ); + action->setCheckable(true); + addAction( action ); + group->addAction(action); + + char *psz_renderer = var_InheritString( THEPL, "sout" ); + if ( psz_renderer == NULL ) + action->setChecked( true ); + else + free( psz_renderer ); + + addSeparator(); + + QWidget *statusWidget = new QWidget(); + statusWidget->setLayout( new QVBoxLayout ); + QLabel *label = new QLabel(); + label->setObjectName( "statuslabel" ); + statusWidget->layout()->addWidget( label ); + QProgressBar *pb = new QProgressBar(); + pb->setObjectName( "statusprogressbar" ); + pb->setMaximumHeight( 10 ); + pb->setStyleSheet( QString("\ + QProgressBar:horizontal {\ + border: none;\ + background: transparent;\ + padding: 1px;\ + }\ + QProgressBar::chunk:horizontal {\ + background: qlineargradient(x1: 0, y1: 0.5, x2: 1, y2: 0.5, \ + stop: 0 white, stop: 0.4 orange, stop: 0.6 orange, stop: 1 white);\ + }") ); + pb->setRange( 0, 0 ); + pb->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Maximum ); + statusWidget->layout()->addWidget( pb ); + QWidgetAction *qwa = new QWidgetAction( this ); + qwa->setDefaultWidget( statusWidget ); + qwa->setDisabled( true ); + addAction( qwa ); + status = qwa; + + RendererManager *manager = RendererManager::getInstance( p_intf ); + CONNECT( this, aboutToShow(), manager, StartScan() ); + CONNECT( group, triggered(QAction*), this, RendererSelected( QAction* ) ); + DCONNECT( manager, rendererItemAdded( vlc_renderer_item_t * ), + this, addRendererItem( vlc_renderer_item_t * ) ); + DCONNECT( manager, rendererItemRemoved( vlc_renderer_item_t * ), + this, removeRendererItem( vlc_renderer_item_t * ) ); + CONNECT( manager, statusUpdated( int ), + this, updateStatus( int ) ); +} + +RendererMenu::~RendererMenu() +{ + reset(); +} + +void RendererMenu::updateStatus( int val ) +{ + QProgressBar *pb = findChild<QProgressBar *>("statusprogressbar"); + QLabel *label = findChild<QLabel *>("statuslabel"); + if( val >= RendererManager::RendererStatus::RUNNING ) + { + label->setText( qtr("Scanning..."). + append( QString(" (%1s)").arg( val ) ) ); + pb->setVisible( true ); + status->setVisible( true ); + } + else if( val == RendererManager::RendererStatus::FAILED ) + { + label->setText( "Failed (no discovery module available)" ); + pb->setVisible( false ); + status->setVisible( true ); + } + else status->setVisible( false ); +} + +void RendererMenu::addRendererItem( vlc_renderer_item_t *p_item ) +{ + QAction *action = new RendererAction( p_item ); + insertAction( status, action ); + group->addAction( action ); +} + +void RendererMenu::removeRendererItem( vlc_renderer_item_t *p_item ) +{ + foreach (QAction* action, group->actions()) + { + RendererAction *ra = qobject_cast<RendererAction *>( action ); + if( !ra || ra->getItem() != p_item ) + continue; + removeRendererAction( ra ); + delete ra; + break; + } +} + +void RendererMenu::addRendererAction(QAction *action) +{ + insertAction( status, action ); + group->addAction( action ); +} + +void RendererMenu::removeRendererAction(QAction *action) +{ + removeAction( action ); + group->removeAction( action ); +} + +void RendererMenu::reset() +{ + /* reset the list of renderers */ + foreach (QAction* action, group->actions()) + { + RendererAction *ra = qobject_cast<RendererAction *>( action ); + if( ra ) + { + removeRendererAction( ra ); + delete ra; + } + } +} + +void RendererMenu::RendererSelected(QAction *action) +{ + RendererAction *ra = qobject_cast<RendererAction *>( action ); + if( ra ) + RendererManager::getInstance( p_intf )->SelectRenderer( ra->getItem() ); + else + RendererManager::getInstance( p_intf )->SelectRenderer( NULL ); +} diff --git a/modules/gui/qt/components/custom_menus.hpp b/modules/gui/qt/components/custom_menus.hpp new file mode 100644 index 0000000000..45c8c9039c --- /dev/null +++ b/modules/gui/qt/components/custom_menus.hpp @@ -0,0 +1,67 @@ +/***************************************************************************** + * custom_menus.hpp : Qt custom menus classes + ***************************************************************************** + * Copyright © 2006-2018 VideoLAN authors + * 2018 VideoLabs + * + * 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. + *****************************************************************************/ +#ifndef CUSTOM_MENUS_HPP +#define CUSTOM_MENUS_HPP + +#include "qt.hpp" + +#include <QMenu> + +class RendererAction : public QAction +{ + Q_OBJECT + + public: + RendererAction( vlc_renderer_item_t * ); + ~RendererAction(); + vlc_renderer_item_t *getItem(); + + private: + vlc_renderer_item_t *p_item; +}; + +class RendererMenu : public QMenu +{ + Q_OBJECT + +public: + RendererMenu( QMenu *, intf_thread_t * ); + virtual ~RendererMenu(); + void reset(); + +private slots: + void addRendererItem( vlc_renderer_item_t * ); + void removeRendererItem( vlc_renderer_item_t * ); + void updateStatus( int ); + void RendererSelected( QAction* ); + +private: + void addRendererAction( QAction * ); + void removeRendererAction( QAction * ); + static vlc_renderer_item_t* getMatchingRenderer( const QVariant &, + vlc_renderer_item_t* ); + QAction *status; + QActionGroup *group; + intf_thread_t *p_intf; +}; + + +#endif // CUSTOM_MENUS_HPP diff --git a/modules/gui/qt/main_interface.cpp b/modules/gui/qt/main_interface.cpp index 8b87e29e8f..0cb322bbcf 100644 --- a/modules/gui/qt/main_interface.cpp +++ b/modules/gui/qt/main_interface.cpp @@ -32,6 +32,7 @@ #include "main_interface.hpp" #include "input_manager.hpp" // Creation #include "actions_manager.hpp" // killInstance +#include "managers/renderer_manager.hpp" #include "util/customwidgets.hpp" // qtEventToVLCKey, QVLCStackedWidget #include "util/qt_dirs.hpp" // toNativeSeparators @@ -280,6 +281,8 @@ MainInterface::~MainInterface() /* Delete the FSC controller */ delete fullscreenControls; + RendererManager::killInstance(); + /* Save states */ settings->beginGroup("MainWindow"); diff --git a/modules/gui/qt/managers/renderer_manager.cpp b/modules/gui/qt/managers/renderer_manager.cpp new file mode 100644 index 0000000000..6a46270ad2 --- /dev/null +++ b/modules/gui/qt/managers/renderer_manager.cpp @@ -0,0 +1,170 @@ +#include "renderer_manager.hpp" + +#include <QApplication> + +const QEvent::Type RendererManagerEvent::AddedEvent = + (QEvent::Type)QEvent::registerEventType(); +const QEvent::Type RendererManagerEvent::RemovedEvent = + (QEvent::Type)QEvent::registerEventType(); + +RendererManager::RendererManager( intf_thread_t *p_intf_ ) : + p_intf( p_intf_ ), p_selected_item( NULL ) +{ + CONNECT( &m_stop_scan_timer, timeout(), this, RendererMenuCountdown() ); +} + +RendererManager::~RendererManager() +{ + StopScan(); + foreach( ItemEntry entry, m_items ) + { + emit rendererItemRemoved( entry.second ); + vlc_renderer_item_release( entry.second ); + } +} + +void RendererManager::customEvent( QEvent *event ) +{ + if( event->type() == RendererManagerEvent::AddedEvent || + event->type() == RendererManagerEvent::RemovedEvent ) + { + RendererManagerEvent *ev = static_cast<RendererManagerEvent *>(event); + QString souturi( vlc_renderer_item_sout( ev->getItem() ) ); + vlc_renderer_item_t *p_item = ev->getItem(); + + if( event->type() == RendererManagerEvent::AddedEvent ) + { + if( !m_items.contains( souturi ) ) + { + vlc_renderer_item_hold( p_item ); + ItemEntry entry( true, p_item ); + m_items.insert( souturi, entry ); + emit rendererItemAdded( p_item ); + } + else /* incref for now */ + { + ItemEntry &entry = m_items[ souturi ]; + entry.first = true; /* to be kept */ + } + } + else /* remove event */ + { + if( m_items.contains( souturi ) ) + { + p_item = m_items[ souturi ].second; + if( p_selected_item != p_item ) + { + m_items.remove( souturi ); + emit rendererItemRemoved( p_item ); + vlc_renderer_item_release( p_item ); + } + else m_items[ souturi ].first = true; /* keep */ + } + /* else ignore */ + } + } +} + +void RendererManager::StartScan() +{ + if( m_stop_scan_timer.isActive() ) + return; + + /* SD subnodes */ + char **ppsz_longnames; + char **ppsz_names; + if( vlc_rd_get_names( THEPL, &ppsz_names, &ppsz_longnames ) != VLC_SUCCESS ) + { + emit statusUpdated( RendererManager::RendererStatus::FAILED ); + return; + } + + struct vlc_renderer_discovery_owner owner = + { + this, + renderer_event_item_added, + renderer_event_item_removed, + }; + + char **ppsz_name = ppsz_names, **ppsz_longname = ppsz_longnames; + for( ; *ppsz_name; ppsz_name++, ppsz_longname++ ) + { + msg_Dbg( p_intf, "starting renderer discovery service %s", *ppsz_longname ); + vlc_renderer_discovery_t* p_rd = vlc_rd_new( VLC_OBJECT(p_intf), *ppsz_name, &owner ); + if( p_rd != NULL ) + m_rds.push_back( p_rd ); + free( *ppsz_name ); + free( *ppsz_longname ); + } + free( ppsz_names ); + free( ppsz_longnames ); + + emit statusUpdated( RendererManager::RendererStatus::RUNNING ); + m_scan_remain = 20000; + m_stop_scan_timer.setInterval( 1000 ); + m_stop_scan_timer.start(); +} + +void RendererManager::StopScan() +{ + m_stop_scan_timer.stop(); + foreach ( vlc_renderer_discovery_t* p_rd, m_rds ) + vlc_rd_release( p_rd ); + /* Cleanup of outdated items, and notify removal */ + QHash<QString, ItemEntry>::iterator it = m_items.begin(); + while ( it != m_items.end() ) + { + ItemEntry &entry = it.value(); + if( !entry.first /* don't keep */ && entry.second != p_selected_item ) + { + emit rendererItemRemoved( entry.second ); + vlc_renderer_item_release( entry.second ); + it = m_items.erase( it ); + } + else + { + entry.first = false; /* don't keep if not updated by new detect */ + assert( it.value().first == false ); + ++it; + } + } + m_rds.clear(); + emit statusUpdated( RendererManager::RendererStatus::IDLE ); +} + +void RendererManager::RendererMenuCountdown() +{ + if( m_stop_scan_timer.isActive() && m_scan_remain > 0 ) + { + m_scan_remain -= 1000; + emit statusUpdated( RendererManager::RendererStatus::RUNNING + m_scan_remain / 1000 ); + } + else + { + StopScan(); + } +} + +void RendererManager::SelectRenderer( vlc_renderer_item_t *p_item ) +{ + p_selected_item = p_item; + playlist_SetRenderer( THEPL, p_item ); +} + +void RendererManager::renderer_event_item_added( vlc_renderer_discovery_t* p_rd, + vlc_renderer_item_t *p_item ) +{ + RendererManager *self = reinterpret_cast<RendererManager*>( p_rd->owner.sys ); + QEvent *ev = new RendererManagerEvent( RendererManagerEvent::AddedEvent, + p_item ); + QApplication::postEvent( self, ev ); +} + +void RendererManager::renderer_event_item_removed( vlc_renderer_discovery_t *p_rd, + vlc_renderer_item_t *p_item ) +{ + RendererManager *self = reinterpret_cast<RendererManager*>( p_rd->owner.sys ); + QEvent *ev = new RendererManagerEvent( RendererManagerEvent::RemovedEvent, + p_item ); + QApplication::postEvent( self, ev ); +} diff --git a/modules/gui/qt/managers/renderer_manager.hpp b/modules/gui/qt/managers/renderer_manager.hpp new file mode 100644 index 0000000000..c8126761b0 --- /dev/null +++ b/modules/gui/qt/managers/renderer_manager.hpp @@ -0,0 +1,87 @@ +#ifndef RENDERER_MANAGER_HPP +#define RENDERER_MANAGER_HPP + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "qt.hpp" +#include "util/singleton.hpp" + +#include <vlc_common.h> +#include <vlc_renderer_discovery.h> + +#include <QObject> +#include <QEvent> +#include <QTimer> +#include <QVector> +#include <QHash> +#include <QPair> + +class RendererManagerEvent : public QEvent +{ +public: + static const QEvent::Type AddedEvent; + static const QEvent::Type RemovedEvent; + + RendererManagerEvent( QEvent::Type type, vlc_renderer_item_t *p_item_ ) + : QEvent( type ), p_item( p_item_ ) + { + vlc_renderer_item_hold( p_item ); + } + virtual ~RendererManagerEvent() + { + vlc_renderer_item_release( p_item ); + } + + vlc_renderer_item_t * getItem() const { return p_item; } + +private: + vlc_renderer_item_t *p_item; +}; + +class RendererManager : public QObject, public Singleton<RendererManager> +{ + Q_OBJECT + friend class Singleton<RendererManager>; + +public: + enum RendererStatus + { + FAILED = -2, + IDLE = -1, + RUNNING, + }; + RendererManager( intf_thread_t * ); + virtual ~RendererManager(); + void customEvent( QEvent * ); + +public slots: + void SelectRenderer( vlc_renderer_item_t * ); + void StartScan(); + void StopScan(); + +signals: + void rendererItemAdded( vlc_renderer_item_t * ); /* For non queued only */ + void rendererItemRemoved( vlc_renderer_item_t * ); /* For non queued only */ + void statusUpdated( int ); + +private: + static void renderer_event_item_added( vlc_renderer_discovery_t *, + vlc_renderer_item_t * ); + static void renderer_event_item_removed( vlc_renderer_discovery_t *, + vlc_renderer_item_t * ); + + typedef std::pair<bool, vlc_renderer_item_t *> ItemEntry; + intf_thread_t* const p_intf; + const vlc_renderer_item_t *p_selected_item; + QVector<vlc_renderer_discovery_t*> m_rds; + QHash<QString, ItemEntry> m_items; + QTimer m_stop_scan_timer; + unsigned m_scan_remain; + +private slots: + void RendererMenuCountdown(); +}; + +#endif // RENDERER_MANAGER_HPP diff --git a/modules/gui/qt/menus.cpp b/modules/gui/qt/menus.cpp index 14e07e4cd2..1f877cba58 100644 --- a/modules/gui/qt/menus.cpp +++ b/modules/gui/qt/menus.cpp @@ -80,8 +80,7 @@ enum static QActionGroup *currentGroup; QMenu *VLCMenuBar::recentsMenu = NULL; -QMenu *VLCMenuBar::rendererMenu = NULL; -QActionGroup *VLCMenuBar::rendererGroup = NULL; +RendererMenu *VLCMenuBar::rendererMenu = NULL; /** * @brief Add static entries to DP in menus @@ -733,10 +732,10 @@ QMenu *VLCMenuBar::NavigMenu( intf_thread_t *p_intf, QMenu *menu ) menu->addSeparator(); - if ( !rendererMenu ) - rendererMenu = RendererMenu( p_intf ); + if ( !VLCMenuBar::rendererMenu ) + VLCMenuBar::rendererMenu = new RendererMenu( menu, p_intf ); - menu->addMenu( rendererMenu ); + menu->addMenu( VLCMenuBar::rendererMenu ); menu->addSeparator(); @@ -1630,33 +1629,3 @@ void VLCMenuBar::updateRecents( intf_thread_t *p_intf ) } } } - -QMenu *VLCMenuBar::RendererMenu(intf_thread_t *p_intf, QMenu *menu ) -{ - QMenu *submenu = new QMenu( qtr("&Renderer"), menu ); - - rendererGroup = new QActionGroup(submenu); - - QAction *action = new QAction( qtr("<Local>"), submenu ); - action->setCheckable(true); - submenu->addAction( action ); - rendererGroup->addAction(action); - - char *psz_renderer = var_InheritString( THEPL, "sout" ); - if ( psz_renderer == NULL ) - action->setChecked( true ); - else - free( psz_renderer ); - - submenu->addSeparator(); - - action = new QAction( qtr("Scanning..."), submenu ); - action->setEnabled( false ); - submenu->addAction( action ); - - CONNECT( submenu, aboutToShow(), ActionsManager::getInstance( p_intf ), StartRendererScan() ); - CONNECT( submenu, aboutToHide(), ActionsManager::getInstance( p_intf ), RendererMenuCountdown() ); - CONNECT( rendererGroup, triggered(QAction*), ActionsManager::getInstance( p_intf ), RendererSelected( QAction* ) ); - - return submenu; -} diff --git a/modules/gui/qt/menus.hpp b/modules/gui/qt/menus.hpp index 1bc6519d61..bfa0c818cc 100644 --- a/modules/gui/qt/menus.hpp +++ b/modules/gui/qt/menus.hpp @@ -27,6 +27,8 @@ #include "qt.hpp" +#include "components/custom_menus.hpp" + #include <QObject> #include <QMenu> #include <QVector> @@ -94,8 +96,7 @@ public: }; Q_DECLARE_FLAGS(actionflags, actionflag) - static QMenu *rendererMenu; - static QActionGroup *rendererGroup; + static RendererMenu *rendererMenu; private: /* All main Menus */ @@ -131,7 +132,6 @@ private: } static QMenu *HelpMenu( QWidget * ); - static QMenu *RendererMenu(intf_thread_t *p_intf , QMenu *menu = NULL ); /* Popups Menus */ static void PopupMenuStaticEntries( QMenu *menu ); diff --git a/po/POTFILES.in b/po/POTFILES.in index 7683c437eb..4428605a9c 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -595,6 +595,8 @@ modules/gui/qt/components/controller.cpp modules/gui/qt/components/controller.hpp modules/gui/qt/components/controller_widget.cpp modules/gui/qt/components/controller_widget.hpp +modules/gui/qt/components/custom_menus.cpp +modules/gui/qt/components/custom_menus.hpp modules/gui/qt/components/epg/EPGChannels.cpp modules/gui/qt/components/epg/EPGChannels.hpp modules/gui/qt/components/epg/EPGItem.cpp _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
