Fix channel selection menus disappearing

When adding/removing an action to/from the toolbar, the aspect ratio,
audio channel, and subtitle channel menus would disappear from the
parent settings menu.

My understanding is that this happened because nothing was keeping those
menus present (plugged?) when other actions were plugged/unplugged.

This changes it so "Aspect Ratio", "Subtitles", and "Audio Channels"
each are a TDESelectAction that is dynamically filled with items. This
way, each popup menu is still present after other actions being
plugged/unplugged.

Resolves: TDE/codeine#24
Signed-off-by: mio <stigma@disroot.org>
pull/25/head
mio 2 months ago
parent cc8974895a
commit f460840a5e

@ -1,5 +1,5 @@
<!DOCTYPE kpartgui> <!DOCTYPE kpartgui>
<kpartgui name="codeine" version="4"> <kpartgui name="codeine" version="5">
<MenuBar> <MenuBar>
<Menu name="file" noMerge="1"><text>&amp;Play</text> <Menu name="file" noMerge="1"><text>&amp;Play</text>
<Action name="play_media"/> <Action name="play_media"/>
@ -10,9 +10,12 @@
<Action name="file_quit"/> <Action name="file_quit"/>
</Menu> </Menu>
<Menu name="settings" noMerge="1"><text>&amp;Settings</text> <Menu name="settings" noMerge="1"><text>&amp;Settings</text>
<Separator/><!-- this seperator doesn't show :( --> <Action name="aspect_ratio_select"/>
<Action name="audio_channels_select"/>
<Action name="subtitle_channels_select"/>
<Separator/>
<Action name="fullscreen"/> <Action name="fullscreen"/>
<Separator/><!-- this seperator doesn't show :( --> <Separator/>
<Action name="options_configure_keybinding"/> <Action name="options_configure_keybinding"/>
<Action name="options_configure_toolbars"/> <Action name="options_configure_toolbars"/>
<Separator/> <Separator/>

@ -9,7 +9,7 @@ extern "C"
typedef struct xine_s xine_t; typedef struct xine_s xine_t;
} }
class TQPopupMenu; class TDESelectAction;
class TQWidget; class TQWidget;
namespace Codeine namespace Codeine
@ -22,7 +22,7 @@ namespace Codeine
void showVideoSettingsDialog( TQWidget* ); void showVideoSettingsDialog( TQWidget* );
void showXineConfigurationDialog( TQWidget*, xine_t* ); void showXineConfigurationDialog( TQWidget*, xine_t* );
void insertAspectRatioMenuItems( TQPopupMenu* ); void insertAspectRatioMenuItems( TDESelectAction* );
} }
#endif #endif

@ -1,8 +1,8 @@
// Copyright 2005 Max Howell (max.howell@methylblue.com) // Copyright 2005 Max Howell (max.howell@methylblue.com)
// See COPYING file for licensing information // See COPYING file for licensing information
#include <tdeactionclasses.h>
#include <tqpopupmenu.h> #include <tqpopupmenu.h>
#include <xine.h>
TQString i18n( const char *text ); TQString i18n( const char *text );
@ -11,15 +11,15 @@ TQString i18n( const char *text );
namespace Codeine namespace Codeine
{ {
void void
insertAspectRatioMenuItems( TQPopupMenu *menu ) insertAspectRatioMenuItems(TDESelectAction *action)
{ {
menu->insertItem( i18n( "Determine &Automatically" ), XINE_VO_ASPECT_AUTO ); TQStringList items(i18n("Determine &Automatically"));
menu->insertSeparator(); items.append(i18n("&Square (1:1)"));
menu->insertItem( i18n( "&Square (1:1)" ), XINE_VO_ASPECT_SQUARE ); items.append(i18n("&4:3"));
menu->insertItem( i18n( "&4:3" ), XINE_VO_ASPECT_4_3 ); items.append(i18n("Ana&morphic (16:9)"));
menu->insertItem( i18n( "Ana&morphic (16:9)" ), XINE_VO_ASPECT_ANAMORPHIC ); items.append(i18n("&DVB (2.11:1)"));
menu->insertItem( i18n( "&DVB (2.11:1)" ), XINE_VO_ASPECT_DVB );
menu->setItemChecked( XINE_VO_ASPECT_AUTO, true ); action->setItems(items);
action->popupMenu()->insertSeparator(1);
} }
} }

@ -18,7 +18,6 @@
#include <kurldrag.h> #include <kurldrag.h>
#include <twin.h> #include <twin.h>
#include <tqcstring.h> #include <tqcstring.h>
#include <tqdesktopwidget.h>
#include <tqevent.h> //::stateChanged() #include <tqevent.h> //::stateChanged()
#include <tqlayout.h> //ctor #include <tqlayout.h> //ctor
#include <tqpopupmenu.h> //because XMLGUI is poorly designed #include <tqpopupmenu.h> //because XMLGUI is poorly designed
@ -48,6 +47,9 @@ extern "C"
} }
#endif #endif
constexpr auto kAspectSelectActionName = "aspect_ratio_select";
constexpr auto kAudioSelectActionName = "audio_channels_select";
constexpr auto kSubtitleSelectActionName = "subtitle_channels_select";
namespace Codeine { namespace Codeine {
@ -116,27 +118,27 @@ MainWindow::MainWindow()
} }
{ {
TQPopupMenu *menu = nullptr; /* Disable aspect/channel menus until the stream has loaded;
TQPopupMenu *settings = static_cast<TQPopupMenu*>(factory()->container( "settings", this )); * Make sure they have the same default item selected. */
int id = SubtitleChannelsMenuItemId, index = 0; TQStringList defaultItems("&Determine Automatically");
if (const auto aspectAction = dynamic_cast<TDESelectAction *>(action(kAspectSelectActionName)))
#define make_menu( name, text ) \ {
menu = new TQPopupMenu( this, name ); \ aspectAction->setToolTip(i18n("Aspect Ratio"));
menu->setCheckable( true ); \ insertAspectRatioMenuItems(aspectAction);
connect( menu, TQ_SIGNAL(activated( int )), engine(), TQ_SLOT(setStreamParameter( int )) ); \ aspectAction->setEnabled(false);
connect( menu, TQ_SIGNAL(aboutToShow()), TQ_SLOT(aboutToShowMenu()) ); \ }
settings->insertItem( text, menu, id, index ); \ if (const auto audioChannelAction = dynamic_cast<TDESelectAction *>(action(kAudioSelectActionName)))
settings->setItemEnabled( id, false ); \ {
id++, index++; audioChannelAction->setToolTip(i18n("Audio Channels"));
audioChannelAction->setItems(defaultItems);
make_menu( "subtitle_channels_menu", i18n( "&Subtitles" ) ); audioChannelAction->setEnabled(false);
make_menu( "audio_channels_menu", i18n( "A&udio Channels" ) ); }
make_menu( "aspect_ratio_menu", i18n( "Aspect &Ratio" ) ); if (const auto subChannelAction = dynamic_cast<TDESelectAction *>(action(kSubtitleSelectActionName)))
#undef make_menu {
subChannelAction->setToolTip(i18n("Subtitles"));
Codeine::insertAspectRatioMenuItems( menu ); //so we don't have to include xine.h here subChannelAction->setItems(defaultItems);
subChannelAction->setEnabled(false);
settings->insertSeparator( index ); }
} }
TQObjectList *list = toolBar()->queryList( "TDEToolBarButton" ); TQObjectList *list = toolBar()->queryList( "TDEToolBarButton" );
@ -171,10 +173,14 @@ MainWindow::init()
connect( engine(), TQ_SIGNAL(statusMessage( const TQString& )), this, TQ_SLOT(engineMessage( const TQString& )) ); connect( engine(), TQ_SIGNAL(statusMessage( const TQString& )), this, TQ_SLOT(engineMessage( const TQString& )) );
connect( engine(), TQ_SIGNAL(stateChanged( Engine::State )), this, TQ_SLOT(engineStateChanged( Engine::State )) ); connect( engine(), TQ_SIGNAL(stateChanged( Engine::State )), this, TQ_SLOT(engineStateChanged( Engine::State )) );
connect( engine(), TQ_SIGNAL(channelsChanged( const TQStringList& )), this, TQ_SLOT(setChannels( const TQStringList& )) );
connect( engine(), TQ_SIGNAL(titleChanged( const TQString& )), m_titleLabel, TQ_SLOT(setText( const TQString& )) ); connect( engine(), TQ_SIGNAL(titleChanged( const TQString& )), m_titleLabel, TQ_SLOT(setText( const TQString& )) );
connect( m_positionSlider, TQ_SIGNAL(valueChanged( int )), this, TQ_SLOT(showTime( int )) ); connect( m_positionSlider, TQ_SIGNAL(valueChanged( int )), this, TQ_SLOT(showTime( int )) );
connect(engine(), TQ_SIGNAL(audioChannelsChanged(const TQStringList &)),
this, TQ_SLOT(setAudioChannels(const TQStringList &)));
connect(engine(), TQ_SIGNAL(subtitleChannelsChanged(const TQStringList &)),
this, TQ_SLOT(setSubtitleChannels(const TQStringList &)));
if( !engine()->init() ) { if( !engine()->init() ) {
KMessageBox::error( this, i18n( KMessageBox::error( this, i18n(
"<qt>xine could not be successfully initialised. " PRETTY_NAME " will now exit. " "<qt>xine could not be successfully initialised. " PRETTY_NAME " will now exit. "
@ -266,6 +272,15 @@ MainWindow::setupActions()
(new KWidgetAction( m_positionSlider, i18n("Position Slider"), nullptr, nullptr, nullptr, ac, "position_slider" ))->setAutoSized( true ); (new KWidgetAction( m_positionSlider, i18n("Position Slider"), nullptr, nullptr, nullptr, ac, "position_slider" ))->setAutoSized( true );
const auto audioSelectAction = new TDESelectAction(i18n("A&udio Channels"), 0, ac, kAudioSelectActionName);
connect(audioSelectAction, TQ_SIGNAL(activated(int)), engine(), TQ_SLOT(setStreamParameter(int)));
const auto subSelectAction = new TDESelectAction(i18n("&Subtitles"), 0, ac, kSubtitleSelectActionName);
connect(subSelectAction, TQ_SIGNAL(activated(int)), engine(), TQ_SLOT(setStreamParameter(int)));
const auto aspectSelectAction = new TDESelectAction(i18n("Aspect &Ratio"), 0, ac, kAspectSelectActionName);
connect(aspectSelectAction, TQ_SIGNAL(activated(int)), engine(), TQ_SLOT(setStreamParameter(int)));
m_volumeAction = new VolumeAction( toolBar(), ac ); m_volumeAction = new VolumeAction( toolBar(), ac );
} }
@ -594,54 +609,49 @@ MainWindow::streamInformation()
} }
void void
MainWindow::setChannels( const TQStringList &channels ) MainWindow::setAudioChannels(const TQStringList &channels) const
{ {
DEBUG_FUNC_INFO DEBUG_FUNC_INFO
//TODO -1 = auto /* Xine uses -1 and -2 to indicate that a channel should be determined automatically or
* turned off. TDESelectAction inserts items starting from index 0, so we add 2 to the
TQStringList::ConstIterator it = channels.begin(); * channel returned from TheStream to match. */
TQPopupMenu *menu = (TQPopupMenu*)child( (*it).latin1() );
menu->clear();
menu->insertItem( i18n("&Determine Automatically"), 1 ); if (const auto audioSelection = dynamic_cast<TDESelectAction *>(action(kAudioSelectActionName)))
menu->insertSeparator(); {
TQStringList audioChannels(channels);
//the id is crucial, since the slot this menu is connected to requires audioChannels.prepend("&Determine Automatically");
//that information to set the correct channel audioChannels.prepend("&Off");
//NOTE we subtract 2 in xineEngine because TQMenuData doesn't allow negative id audioSelection->setItems(audioChannels);
int id = 2; audioSelection->popupMenu()->insertSeparator(2);
++it; audioSelection->setCurrentItem(TheStream::audioChannel() + 2);
for( TQStringList::ConstIterator const end = channels.end(); it != end; ++it, ++id ) audioSelection->setEnabled(channels.count());
menu->insertItem( *it, id ); }
else
menu->insertSeparator(); {
menu->insertItem( i18n("&Off"), 0 ); Debug::error() << "Failed to update the audio channels (selection menu not found)" << endl;
}
id = channels.first() == "subtitle_channels_menu" ? SubtitleChannelsMenuItemId : AudioChannelsMenuItemId;
MainWindow::menu( "settings" )->setItemEnabled( id, channels.count() > 1 );
} }
void void
MainWindow::aboutToShowMenu() MainWindow::setSubtitleChannels(const TQStringList &channels) const
{ {
TQPopupMenu *menu = (TQPopupMenu*)sender(); DEBUG_FUNC_INFO
TQCString name( sender() ? sender()->name() : nullptr );
// uncheck all items first
for( uint x = 0; x < menu->count(); ++x )
menu->setItemChecked( menu->idAt( x ), false );
int id; if (const auto subSelection = dynamic_cast<TDESelectAction *>(action(kSubtitleSelectActionName)))
if( name == "subtitle_channels_menu" ) {
id = TheStream::subtitleChannel() + 2; TQStringList subChannels(channels);
else if( name == "audio_channels_menu" ) subChannels.prepend("&Determine Automatically");
id = TheStream::audioChannel() + 2; subChannels.prepend("&Off");
subSelection->setItems(subChannels);
subSelection->popupMenu()->insertSeparator(2);
subSelection->setCurrentItem(TheStream::subtitleChannel() + 2);
subSelection->setEnabled(channels.count());
}
else else
id = TheStream::aspectRatio(); {
Debug::error() << "Failed to update the subtitle channels (selection menu not found)" << endl;
menu->setItemChecked( id, true ); }
} }
void void
@ -682,10 +692,10 @@ MainWindow::keyPressEvent( TQKeyEvent *e )
} }
TQPopupMenu* TQPopupMenu*
MainWindow::menu( const char *name ) MainWindow::menu( const TQString& name )
{ {
// KXMLGUI is "really good". // KXMLGUI is "really good".
return static_cast<TQPopupMenu*>(factory()->container( name, this )); return dynamic_cast<TQPopupMenu*>(factory()->container( name, this ));
} }

@ -40,9 +40,9 @@ namespace Codeine
void engineStateChanged( Engine::State ); void engineStateChanged( Engine::State );
void init(); void init();
void showTime( int = -1 ); void showTime( int = -1 );
void setChannels( const TQStringList& );
void aboutToShowMenu();
void fullScreenToggled( bool ); void fullScreenToggled( bool );
void setAudioChannels(const TQStringList&) const;
void setSubtitleChannels(const TQStringList&) const;
private: private:
void setupActions(); void setupActions();
@ -50,7 +50,7 @@ namespace Codeine
bool load( const KURL& ); bool load( const KURL& );
bool open( const KURL& ); bool open( const KURL& );
TQPopupMenu *menu( const char *name ); TQPopupMenu *menu(const TQString&);
virtual void timerEvent( TQTimerEvent* ); virtual void timerEvent( TQTimerEvent* );
virtual void dragEnterEvent( TQDragEnterEvent* ); virtual void dragEnterEvent( TQDragEnterEvent* );

@ -90,11 +90,14 @@ MainWindow::engineStateChanged( Engine::State state )
file_menu->changeItem( play_id, item.iconSet(), item.text() ); file_menu->changeItem( play_id, item.iconSet(), item.text() );
file_menu->setItemChecked( play_id, false ); file_menu->setItemChecked( play_id, false );
settings_menu->setItemEnabled( AspectRatioMenuItemId, state & (Playing | Paused) && TheStream::hasVideo() ); if (const auto aspectAction = dynamic_cast<TDESelectAction *>(action("aspect_ratio_select")))
{
// set correct aspect ratio aspectAction->setEnabled((state & (Playing | Paused)) && TheStream::hasVideo());
if (state == Loaded) if (state == Loaded)
static_cast<TQPopupMenu*>(child( "aspect_ratio_menu" ))->setItemChecked( TheStream::aspectRatio(), true ); {
aspectAction->setCurrentItem(TheStream::aspectRatio());
}
}
} }

@ -579,13 +579,13 @@ VideoWindow::setStreamParameter( int value )
parameter = XINE_PARAM_VO_CONTRAST; parameter = XINE_PARAM_VO_CONTRAST;
else if( sender == "brightness" ) else if( sender == "brightness" )
parameter = XINE_PARAM_VO_BRIGHTNESS; parameter = XINE_PARAM_VO_BRIGHTNESS;
else if( sender == "subtitle_channels_menu" ) else if( sender == "subtitle_channels_select" )
parameter = XINE_PARAM_SPU_CHANNEL, parameter = XINE_PARAM_SPU_CHANNEL,
value -= 2; value -= 2;
else if( sender == "audio_channels_menu" ) else if( sender == "audio_channels_select" )
parameter = XINE_PARAM_AUDIO_CHANNEL_LOGICAL, parameter = XINE_PARAM_AUDIO_CHANNEL_LOGICAL,
value -= 2; value -= 2;
else if( sender == "aspect_ratio_menu" ) else if( sender == "aspect_ratio_select" )
parameter = XINE_PARAM_VO_ASPECT_RATIO; parameter = XINE_PARAM_VO_ASPECT_RATIO;
else if( sender == "volume" ) else if( sender == "volume" )
{ {
@ -709,19 +709,19 @@ VideoWindow::customEvent( TQCustomEvent *e )
char s[128]; //apparently sufficient char s[128]; //apparently sufficient
{ {
TQStringList languages( "subtitle_channels_menu" ); TQStringList languages;
int channels = xine_get_stream_info( m_stream, XINE_STREAM_INFO_MAX_SPU_CHANNEL ); int channels = xine_get_stream_info( m_stream, XINE_STREAM_INFO_MAX_SPU_CHANNEL );
for( int j = 0; j < channels; j++ ) for( int j = 0; j < channels; j++ )
languages += xine_get_spu_lang( m_stream, j, s ) ? s : i18n("Channel %1").arg( j+1 ); languages += xine_get_spu_lang( m_stream, j, s ) ? s : i18n("Channel %1").arg( j+1 );
emit channelsChanged( languages ); emit subtitleChannelsChanged(languages);
} }
{ {
TQStringList languages( "audio_channels_menu" ); TQStringList languages;
int channels = xine_get_stream_info( m_stream, XINE_STREAM_INFO_MAX_AUDIO_CHANNEL ); int channels = xine_get_stream_info( m_stream, XINE_STREAM_INFO_MAX_AUDIO_CHANNEL );
for( int j = 0; j < channels; j++ ) for( int j = 0; j < channels; j++ )
languages += xine_get_audio_lang( m_stream, j, s ) ? s : i18n("Channel %1").arg( j+1 ); languages += xine_get_audio_lang( m_stream, j, s ) ? s : i18n("Channel %1").arg( j+1 );
emit channelsChanged( languages ); emit audioChannelsChanged(languages);
} }
break; break;
} }

@ -83,7 +83,8 @@ namespace Codeine
void stateChanged( Engine::State ); void stateChanged( Engine::State );
void statusMessage( const TQString& ); void statusMessage( const TQString& );
void titleChanged( const TQString& ); void titleChanged( const TQString& );
void channelsChanged( const TQStringList& ); void audioChannelsChanged( const TQStringList &);
void subtitleChannelsChanged( const TQStringList &);
private: private:
static void xineEventListener( void*, const xine_event_t* ); static void xineEventListener( void*, const xine_event_t* );

Loading…
Cancel
Save