diff --git a/misc/codeineui.rc b/misc/codeineui.rc index d6ef71f..c5afb14 100644 --- a/misc/codeineui.rc +++ b/misc/codeineui.rc @@ -1,5 +1,5 @@ - + &Play @@ -10,9 +10,12 @@ &Settings - + + + + - + diff --git a/src/app/extern.h b/src/app/extern.h index 442b4d3..410f459 100644 --- a/src/app/extern.h +++ b/src/app/extern.h @@ -9,7 +9,7 @@ extern "C" typedef struct xine_s xine_t; } -class TQPopupMenu; +class TDESelectAction; class TQWidget; namespace Codeine @@ -22,7 +22,7 @@ namespace Codeine void showVideoSettingsDialog( TQWidget* ); void showXineConfigurationDialog( TQWidget*, xine_t* ); - void insertAspectRatioMenuItems( TQPopupMenu* ); + void insertAspectRatioMenuItems( TDESelectAction* ); } #endif diff --git a/src/app/insertAspectRatioMenuItems.cpp b/src/app/insertAspectRatioMenuItems.cpp index d2baafc..f0438a7 100644 --- a/src/app/insertAspectRatioMenuItems.cpp +++ b/src/app/insertAspectRatioMenuItems.cpp @@ -1,8 +1,8 @@ // Copyright 2005 Max Howell (max.howell@methylblue.com) // See COPYING file for licensing information +#include #include -#include TQString i18n( const char *text ); @@ -11,15 +11,15 @@ TQString i18n( const char *text ); namespace Codeine { void - insertAspectRatioMenuItems( TQPopupMenu *menu ) + insertAspectRatioMenuItems(TDESelectAction *action) { - menu->insertItem( i18n( "Determine &Automatically" ), XINE_VO_ASPECT_AUTO ); - menu->insertSeparator(); - menu->insertItem( i18n( "&Square (1:1)" ), XINE_VO_ASPECT_SQUARE ); - menu->insertItem( i18n( "&4:3" ), XINE_VO_ASPECT_4_3 ); - menu->insertItem( i18n( "Ana&morphic (16:9)" ), XINE_VO_ASPECT_ANAMORPHIC ); - menu->insertItem( i18n( "&DVB (2.11:1)" ), XINE_VO_ASPECT_DVB ); + TQStringList items(i18n("Determine &Automatically")); + items.append(i18n("&Square (1:1)")); + items.append(i18n("&4:3")); + items.append(i18n("Ana&morphic (16:9)")); + items.append(i18n("&DVB (2.11:1)")); - menu->setItemChecked( XINE_VO_ASPECT_AUTO, true ); + action->setItems(items); + action->popupMenu()->insertSeparator(1); } } diff --git a/src/app/mainWindow.cpp b/src/app/mainWindow.cpp index 159d84c..9409d85 100644 --- a/src/app/mainWindow.cpp +++ b/src/app/mainWindow.cpp @@ -18,7 +18,6 @@ #include #include #include -#include #include //::stateChanged() #include //ctor #include //because XMLGUI is poorly designed @@ -48,6 +47,9 @@ extern "C" } #endif +constexpr auto kAspectSelectActionName = "aspect_ratio_select"; +constexpr auto kAudioSelectActionName = "audio_channels_select"; +constexpr auto kSubtitleSelectActionName = "subtitle_channels_select"; namespace Codeine { @@ -116,27 +118,27 @@ MainWindow::MainWindow() } { - TQPopupMenu *menu = nullptr; - TQPopupMenu *settings = static_cast(factory()->container( "settings", this )); - int id = SubtitleChannelsMenuItemId, index = 0; - - #define make_menu( name, text ) \ - menu = new TQPopupMenu( this, name ); \ - menu->setCheckable( true ); \ - connect( menu, TQ_SIGNAL(activated( int )), engine(), TQ_SLOT(setStreamParameter( int )) ); \ - connect( menu, TQ_SIGNAL(aboutToShow()), TQ_SLOT(aboutToShowMenu()) ); \ - settings->insertItem( text, menu, id, index ); \ - settings->setItemEnabled( id, false ); \ - id++, index++; - - make_menu( "subtitle_channels_menu", i18n( "&Subtitles" ) ); - make_menu( "audio_channels_menu", i18n( "A&udio Channels" ) ); - make_menu( "aspect_ratio_menu", i18n( "Aspect &Ratio" ) ); - #undef make_menu - - Codeine::insertAspectRatioMenuItems( menu ); //so we don't have to include xine.h here - - settings->insertSeparator( index ); + /* Disable aspect/channel menus until the stream has loaded; + * Make sure they have the same default item selected. */ + TQStringList defaultItems("&Determine Automatically"); + if (const auto aspectAction = dynamic_cast(action(kAspectSelectActionName))) + { + aspectAction->setToolTip(i18n("Aspect Ratio")); + insertAspectRatioMenuItems(aspectAction); + aspectAction->setEnabled(false); + } + if (const auto audioChannelAction = dynamic_cast(action(kAudioSelectActionName))) + { + audioChannelAction->setToolTip(i18n("Audio Channels")); + audioChannelAction->setItems(defaultItems); + audioChannelAction->setEnabled(false); + } + if (const auto subChannelAction = dynamic_cast(action(kSubtitleSelectActionName))) + { + subChannelAction->setToolTip(i18n("Subtitles")); + subChannelAction->setItems(defaultItems); + subChannelAction->setEnabled(false); + } } 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(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( 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() ) { KMessageBox::error( this, i18n( "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 ); + 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 ); } @@ -594,54 +609,49 @@ MainWindow::streamInformation() } void -MainWindow::setChannels( const TQStringList &channels ) +MainWindow::setAudioChannels(const TQStringList &channels) const { DEBUG_FUNC_INFO - //TODO -1 = auto - - TQStringList::ConstIterator it = channels.begin(); - - TQPopupMenu *menu = (TQPopupMenu*)child( (*it).latin1() ); - menu->clear(); - - menu->insertItem( i18n("&Determine Automatically"), 1 ); - menu->insertSeparator(); - - //the id is crucial, since the slot this menu is connected to requires - //that information to set the correct channel - //NOTE we subtract 2 in xineEngine because TQMenuData doesn't allow negative id - int id = 2; - ++it; - for( TQStringList::ConstIterator const end = channels.end(); it != end; ++it, ++id ) - menu->insertItem( *it, id ); + /* 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 + * channel returned from TheStream to match. */ - menu->insertSeparator(); - menu->insertItem( i18n("&Off"), 0 ); - - id = channels.first() == "subtitle_channels_menu" ? SubtitleChannelsMenuItemId : AudioChannelsMenuItemId; - MainWindow::menu( "settings" )->setItemEnabled( id, channels.count() > 1 ); + if (const auto audioSelection = dynamic_cast(action(kAudioSelectActionName))) + { + TQStringList audioChannels(channels); + audioChannels.prepend("&Determine Automatically"); + audioChannels.prepend("&Off"); + audioSelection->setItems(audioChannels); + audioSelection->popupMenu()->insertSeparator(2); + audioSelection->setCurrentItem(TheStream::audioChannel() + 2); + audioSelection->setEnabled(channels.count()); + } + else + { + Debug::error() << "Failed to update the audio channels (selection menu not found)" << endl; + } } void -MainWindow::aboutToShowMenu() +MainWindow::setSubtitleChannels(const TQStringList &channels) const { - TQPopupMenu *menu = (TQPopupMenu*)sender(); - 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( name == "subtitle_channels_menu" ) - id = TheStream::subtitleChannel() + 2; - else if( name == "audio_channels_menu" ) - id = TheStream::audioChannel() + 2; - else - id = TheStream::aspectRatio(); + DEBUG_FUNC_INFO - menu->setItemChecked( id, true ); + if (const auto subSelection = dynamic_cast(action(kSubtitleSelectActionName))) + { + TQStringList subChannels(channels); + subChannels.prepend("&Determine Automatically"); + subChannels.prepend("&Off"); + subSelection->setItems(subChannels); + subSelection->popupMenu()->insertSeparator(2); + subSelection->setCurrentItem(TheStream::subtitleChannel() + 2); + subSelection->setEnabled(channels.count()); + } + else + { + Debug::error() << "Failed to update the subtitle channels (selection menu not found)" << endl; + } } void @@ -682,10 +692,10 @@ MainWindow::keyPressEvent( TQKeyEvent *e ) } TQPopupMenu* -MainWindow::menu( const char *name ) +MainWindow::menu( const TQString& name ) { // KXMLGUI is "really good". - return static_cast(factory()->container( name, this )); + return dynamic_cast(factory()->container( name, this )); } diff --git a/src/app/mainWindow.h b/src/app/mainWindow.h index 6ba9e89..634d444 100644 --- a/src/app/mainWindow.h +++ b/src/app/mainWindow.h @@ -40,9 +40,9 @@ namespace Codeine void engineStateChanged( Engine::State ); void init(); void showTime( int = -1 ); - void setChannels( const TQStringList& ); - void aboutToShowMenu(); void fullScreenToggled( bool ); + void setAudioChannels(const TQStringList&) const; + void setSubtitleChannels(const TQStringList&) const; private: void setupActions(); @@ -50,7 +50,7 @@ namespace Codeine bool load( const KURL& ); bool open( const KURL& ); - TQPopupMenu *menu( const char *name ); + TQPopupMenu *menu(const TQString&); virtual void timerEvent( TQTimerEvent* ); virtual void dragEnterEvent( TQDragEnterEvent* ); diff --git a/src/app/stateChange.cpp b/src/app/stateChange.cpp index efa9389..9322a13 100644 --- a/src/app/stateChange.cpp +++ b/src/app/stateChange.cpp @@ -90,11 +90,14 @@ MainWindow::engineStateChanged( Engine::State state ) file_menu->changeItem( play_id, item.iconSet(), item.text() ); file_menu->setItemChecked( play_id, false ); - settings_menu->setItemEnabled( AspectRatioMenuItemId, state & (Playing | Paused) && TheStream::hasVideo() ); - - // set correct aspect ratio - if( state == Loaded ) - static_cast(child( "aspect_ratio_menu" ))->setItemChecked( TheStream::aspectRatio(), true ); + if (const auto aspectAction = dynamic_cast(action("aspect_ratio_select"))) + { + aspectAction->setEnabled((state & (Playing | Paused)) && TheStream::hasVideo()); + if (state == Loaded) + { + aspectAction->setCurrentItem(TheStream::aspectRatio()); + } + } } diff --git a/src/app/xineEngine.cpp b/src/app/xineEngine.cpp index e38ff4e..708ab13 100644 --- a/src/app/xineEngine.cpp +++ b/src/app/xineEngine.cpp @@ -579,13 +579,13 @@ VideoWindow::setStreamParameter( int value ) parameter = XINE_PARAM_VO_CONTRAST; else if( sender == "brightness" ) parameter = XINE_PARAM_VO_BRIGHTNESS; - else if( sender == "subtitle_channels_menu" ) + else if( sender == "subtitle_channels_select" ) parameter = XINE_PARAM_SPU_CHANNEL, value -= 2; - else if( sender == "audio_channels_menu" ) + else if( sender == "audio_channels_select" ) parameter = XINE_PARAM_AUDIO_CHANNEL_LOGICAL, value -= 2; - else if( sender == "aspect_ratio_menu" ) + else if( sender == "aspect_ratio_select" ) parameter = XINE_PARAM_VO_ASPECT_RATIO; else if( sender == "volume" ) { @@ -709,19 +709,19 @@ VideoWindow::customEvent( TQCustomEvent *e ) 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 ); for( int j = 0; j < channels; j++ ) 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 ); for( int j = 0; j < channels; j++ ) languages += xine_get_audio_lang( m_stream, j, s ) ? s : i18n("Channel %1").arg( j+1 ); - emit channelsChanged( languages ); + emit audioChannelsChanged(languages); } break; } diff --git a/src/app/xineEngine.h b/src/app/xineEngine.h index 638bc01..6f8170a 100644 --- a/src/app/xineEngine.h +++ b/src/app/xineEngine.h @@ -83,7 +83,8 @@ namespace Codeine void stateChanged( Engine::State ); void statusMessage( const TQString& ); void titleChanged( const TQString& ); - void channelsChanged( const TQStringList& ); + void audioChannelsChanged( const TQStringList &); + void subtitleChannelsChanged( const TQStringList &); private: static void xineEventListener( void*, const xine_event_t* );