Amarok – versatile and easy to use audio player
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 
 
 

666 lignes
21 KiB

  1. // Maintainer: Max Howell <max.howell@methylblue.com>, (C) 2004
  2. // Copyright: See COPYING file that comes with this distribution
  3. #include "config.h" //HAVE_LIBVISUAL definition
  4. #include "actionclasses.h"
  5. #include "amarok.h"
  6. #include "amarokconfig.h"
  7. #include "app.h"
  8. #include "debug.h"
  9. #include "collectiondb.h"
  10. #include "covermanager.h"
  11. #include "enginecontroller.h"
  12. #include "k3bexporter.h"
  13. #include "mediumpluginmanager.h"
  14. #include "playlistwindow.h"
  15. #include "playlist.h"
  16. #include "socketserver.h" //Vis::Selector::showInstance()
  17. #include "threadmanager.h"
  18. #include <tqpixmap.h>
  19. #include <tqtooltip.h>
  20. #include <tdeaction.h>
  21. #include <khelpmenu.h>
  22. #include <kiconloader.h>
  23. #include <tdelocale.h>
  24. #include <kstandarddirs.h>
  25. #include <tdetoolbar.h>
  26. #include <tdetoolbarbutton.h>
  27. #include <kurl.h>
  28. extern TDEAboutData aboutData;
  29. namespace Amarok
  30. {
  31. bool repeatNone() { return AmarokConfig::repeat() == AmarokConfig::EnumRepeat::Off; }
  32. bool repeatTrack() { return AmarokConfig::repeat() == AmarokConfig::EnumRepeat::Track; }
  33. bool repeatAlbum() { return AmarokConfig::repeat() == AmarokConfig::EnumRepeat::Album; }
  34. bool repeatPlaylist() { return AmarokConfig::repeat() == AmarokConfig::EnumRepeat::Playlist; }
  35. bool randomOff() { return AmarokConfig::randomMode() == AmarokConfig::EnumRandomMode::Off; }
  36. bool randomTracks() { return AmarokConfig::randomMode() == AmarokConfig::EnumRandomMode::Tracks; }
  37. bool randomAlbums() { return AmarokConfig::randomMode() == AmarokConfig::EnumRandomMode::Albums; }
  38. bool favorNone() { return AmarokConfig::favorTracks() == AmarokConfig::EnumFavorTracks::Off; }
  39. bool favorScores() { return AmarokConfig::favorTracks() == AmarokConfig::EnumFavorTracks::HigherScores; }
  40. bool favorRatings() { return AmarokConfig::favorTracks() == AmarokConfig::EnumFavorTracks::HigherRatings; }
  41. bool favorLastPlay() { return AmarokConfig::favorTracks() == AmarokConfig::EnumFavorTracks::LessRecentlyPlayed; }
  42. bool entireAlbums() { return repeatAlbum() || randomAlbums(); }
  43. }
  44. using namespace Amarok;
  45. KHelpMenu *Menu::s_helpMenu = 0;
  46. static void
  47. safePlug( TDEActionCollection *ac, const char *name, TQWidget *w )
  48. {
  49. if( ac )
  50. {
  51. TDEAction *a = ac->action( name );
  52. if( a ) a->plug( w );
  53. }
  54. }
  55. //////////////////////////////////////////////////////////////////////////////////////////
  56. // MenuAction && Menu
  57. // TDEActionMenu doesn't work very well, so we derived our own
  58. //////////////////////////////////////////////////////////////////////////////////////////
  59. MenuAction::MenuAction( TDEActionCollection *ac )
  60. : TDEAction( i18n( "Amarok Menu" ), 0, ac, "amarok_menu" )
  61. {
  62. setShortcutConfigurable ( false ); //FIXME disabled as it doesn't work, should use TQCursor::pos()
  63. }
  64. int
  65. MenuAction::plug( TQWidget *w, int index )
  66. {
  67. TDEToolBar *bar = dynamic_cast<TDEToolBar*>(w);
  68. if( bar && kapp->authorizeTDEAction( name() ) )
  69. {
  70. const int id = TDEAction::getToolButtonID();
  71. addContainer( bar, id );
  72. connect( bar, TQT_SIGNAL( destroyed() ), TQT_SLOT( slotDestroyed() ) );
  73. //TODO create menu on demand
  74. //TODO create menu above and aligned within window
  75. //TODO make the arrow point upwards!
  76. bar->insertButton( TQString(), id, true, i18n( "Menu" ), index );
  77. bar->alignItemRight( id );
  78. TDEToolBarButton* button = bar->getButton( id );
  79. button->setPopup( Amarok::Menu::instance() );
  80. button->setName( "toolbutton_amarok_menu" );
  81. button->setIcon( "amarok" );
  82. return containerCount() - 1;
  83. }
  84. else return -1;
  85. }
  86. Menu::Menu()
  87. {
  88. TDEActionCollection *ac = Amarok::actionCollection();
  89. setCheckable( true );
  90. safePlug( ac, "repeat", this );
  91. safePlug( ac, "random_mode", this );
  92. insertSeparator();
  93. safePlug( ac, "playlist_playmedia", this );
  94. safePlug( ac, "play_audiocd", this );
  95. safePlug( ac, "lastfm_play", this );
  96. insertSeparator();
  97. insertItem( SmallIconSet( Amarok::icon( "covermanager" ) ), i18n( "C&over Manager" ), ID_SHOW_COVER_MANAGER );
  98. safePlug( ac, "queue_manager", this );
  99. insertItem( SmallIconSet( Amarok::icon( "visualizations" ) ), i18n( "&Visualizations" ), ID_SHOW_VIS_SELECTOR );
  100. insertItem( SmallIconSet( Amarok::icon( "equalizer" ) ), i18n( "E&qualizer" ), kapp, TQT_SLOT( slotConfigEqualizer() ), 0, ID_CONFIGURE_EQUALIZER );
  101. safePlug( ac, "script_manager", this );
  102. safePlug( ac, "statistics", this );
  103. insertSeparator();
  104. safePlug( ac, "update_collection", this );
  105. insertItem( SmallIconSet( Amarok::icon( "rescan" ) ), i18n("&Rescan Collection"), ID_RESCAN_COLLECTION );
  106. setItemEnabled( ID_RESCAN_COLLECTION, !ThreadManager::instance()->isJobPending( "CollectionScanner" ) );
  107. #ifndef TQ_WS_MAC
  108. insertSeparator();
  109. safePlug( ac, KStdAction::name(KStdAction::ShowMenubar), this );
  110. #endif
  111. insertSeparator();
  112. safePlug( ac, KStdAction::name(KStdAction::ConfigureToolbars), this );
  113. safePlug( ac, KStdAction::name(KStdAction::KeyBindings), this );
  114. safePlug( ac, "options_configure_globals", this ); //we created this one
  115. safePlug( ac, KStdAction::name(KStdAction::Preferences), this );
  116. insertSeparator();
  117. insertItem( SmallIconSet("help"), i18n( "&Help" ), helpMenu( this ) );
  118. insertSeparator();
  119. safePlug( ac, KStdAction::name(KStdAction::Quit), this );
  120. connect( this, TQT_SIGNAL( aboutToShow() ), TQT_SLOT( slotAboutToShow() ) );
  121. connect( this, TQT_SIGNAL( activated(int) ), TQT_SLOT( slotActivated(int) ) );
  122. setItemEnabled( ID_SHOW_VIS_SELECTOR, false );
  123. #ifdef HAVE_LIBVISUAL
  124. setItemEnabled( ID_SHOW_VIS_SELECTOR, true );
  125. #endif
  126. }
  127. Menu*
  128. Menu::instance()
  129. {
  130. static Menu menu;
  131. return &menu;
  132. }
  133. TDEPopupMenu*
  134. Menu::helpMenu( TQWidget *parent ) //STATIC
  135. {
  136. if ( s_helpMenu == 0 )
  137. s_helpMenu = new KHelpMenu( parent, &aboutData, Amarok::actionCollection() );
  138. return s_helpMenu->menu();
  139. }
  140. void
  141. Menu::slotAboutToShow()
  142. {
  143. setItemEnabled( ID_CONFIGURE_EQUALIZER, EngineController::hasEngineProperty( "HasEqualizer" ) );
  144. setItemEnabled( ID_CONF_DECODER, EngineController::hasEngineProperty( "HasConfigure" ) );
  145. }
  146. void
  147. Menu::slotActivated( int index )
  148. {
  149. switch( index )
  150. {
  151. case ID_SHOW_COVER_MANAGER:
  152. CoverManager::showOnce();
  153. break;
  154. case ID_SHOW_VIS_SELECTOR:
  155. Vis::Selector::instance()->show(); //doing it here means we delay creation of the widget
  156. break;
  157. case ID_RESCAN_COLLECTION:
  158. CollectionDB::instance()->startScan();
  159. break;
  160. }
  161. }
  162. //////////////////////////////////////////////////////////////////////////////////////////
  163. // PlayPauseAction
  164. //////////////////////////////////////////////////////////////////////////////////////////
  165. PlayPauseAction::PlayPauseAction( TDEActionCollection *ac )
  166. : TDEToggleAction( i18n( "Play/Pause" ), 0, ac, "play_pause" )
  167. , EngineObserver( EngineController::instance() )
  168. {
  169. engineStateChanged( EngineController::engine()->state() );
  170. connect( this, TQT_SIGNAL(activated()), EngineController::instance(), TQT_SLOT(playPause()) );
  171. }
  172. void
  173. PlayPauseAction::engineStateChanged( Engine::State state, Engine::State /*oldState*/ )
  174. {
  175. TQString text;
  176. switch( state ) {
  177. case Engine::Playing:
  178. setChecked( false );
  179. setIcon( Amarok::icon( "pause" ) );
  180. text = i18n( "Pause" );
  181. break;
  182. case Engine::Paused:
  183. setChecked( true );
  184. setIcon( Amarok::icon( "pause" ) );
  185. text = i18n( "Pause" );
  186. break;
  187. case Engine::Empty:
  188. setChecked( false );
  189. setIcon( Amarok::icon( "play" ) );
  190. text = i18n( "Play" );
  191. break;
  192. case Engine::Idle:
  193. return;
  194. }
  195. //update menu texts for this special action
  196. for( int x = 0; x < containerCount(); ++x ) {
  197. TQWidget *w = container( x );
  198. if( w->inherits( TQPOPUPMENU_OBJECT_NAME_STRING ) )
  199. static_cast<TQPopupMenu*>(w)->changeItem( itemId( x ), text );
  200. //TODO TDEToolBar sucks so much
  201. // else if( w->inherits( "TDEToolBar" ) )
  202. // static_cast<TDEToolBar*>(w)->getButton( itemId( x ) )->setText( text );
  203. }
  204. }
  205. //////////////////////////////////////////////////////////////////////////////////////////
  206. // AnalyzerAction
  207. //////////////////////////////////////////////////////////////////////////////////////////
  208. #include "analyzerbase.h"
  209. AnalyzerAction::AnalyzerAction( TDEActionCollection *ac )
  210. : TDEAction( i18n( "Analyzer" ), 0, ac, "toolbar_analyzer" )
  211. {
  212. setShortcutConfigurable( false );
  213. }
  214. int
  215. AnalyzerAction::plug( TQWidget *w, int index )
  216. {
  217. //NOTE the analyzer will be deleted when the toolbar is deleted or cleared()
  218. //we are not designed for unplugging() yet so there would be a leak if that happens
  219. //but it's a rare event and unplugging is complicated.
  220. TDEToolBar *bar = dynamic_cast<TDEToolBar*>(w);
  221. if( bar && kapp->authorizeTDEAction( name() ) )
  222. {
  223. const int id = TDEAction::getToolButtonID();
  224. addContainer( w, id );
  225. connect( w, TQT_SIGNAL( destroyed() ), TQT_SLOT( slotDestroyed() ) );
  226. TQWidget *container = new AnalyzerContainer( w );
  227. bar->insertWidget( id, 0, container, index );
  228. bar->setItemAutoSized( id, true );
  229. return containerCount() - 1;
  230. }
  231. else return -1;
  232. }
  233. AnalyzerContainer::AnalyzerContainer( TQWidget *parent )
  234. : TQWidget( parent, "AnalyzerContainer" )
  235. , m_child( 0 )
  236. {
  237. TQToolTip::add( this, i18n( "Click for more analyzers" ) );
  238. changeAnalyzer();
  239. }
  240. void
  241. AnalyzerContainer::resizeEvent( TQResizeEvent *)
  242. {
  243. m_child->resize( size() );
  244. }
  245. void AnalyzerContainer::changeAnalyzer()
  246. {
  247. delete m_child;
  248. m_child = Analyzer::Factory::createPlaylistAnalyzer( this );
  249. m_child->setName( "ToolBarAnalyzer" );
  250. m_child->resize( size() );
  251. m_child->show();
  252. }
  253. void
  254. AnalyzerContainer::mousePressEvent( TQMouseEvent *e)
  255. {
  256. if( e->button() == Qt::LeftButton ) {
  257. AmarokConfig::setCurrentPlaylistAnalyzer( AmarokConfig::currentPlaylistAnalyzer() + 1 );
  258. changeAnalyzer();
  259. }
  260. }
  261. void
  262. AnalyzerContainer::contextMenuEvent( TQContextMenuEvent *e)
  263. {
  264. #if defined HAVE_LIBVISUAL
  265. TDEPopupMenu menu;
  266. menu.insertItem( SmallIconSet( Amarok::icon( "visualizations" ) ), i18n("&Visualizations"), Menu::ID_SHOW_VIS_SELECTOR );
  267. if( menu.exec( mapToGlobal( e->pos() ) ) == Menu::ID_SHOW_VIS_SELECTOR )
  268. Menu::instance()->slotActivated( Menu::ID_SHOW_VIS_SELECTOR );
  269. #else
  270. Q_UNUSED(e);
  271. #endif
  272. }
  273. //////////////////////////////////////////////////////////////////////////////////////////
  274. // ToggleAction
  275. //////////////////////////////////////////////////////////////////////////////////////////
  276. ToggleAction::ToggleAction( const TQString &text, void ( *f ) ( bool ), TDEActionCollection* const ac, const char *name )
  277. : TDEToggleAction( text, 0, ac, name )
  278. , m_function( f )
  279. {}
  280. void ToggleAction::setChecked( bool b )
  281. {
  282. const bool announce = b != isChecked();
  283. m_function( b );
  284. TDEToggleAction::setChecked( b );
  285. AmarokConfig::writeConfig(); //So we don't lose the setting when crashing
  286. if( announce ) emit toggled( b ); //TDEToggleAction doesn't do this for us. How gay!
  287. }
  288. void ToggleAction::setEnabled( bool b )
  289. {
  290. const bool announce = b != isEnabled();
  291. if( !b )
  292. setChecked( false );
  293. TDEToggleAction::setEnabled( b );
  294. AmarokConfig::writeConfig(); //So we don't lose the setting when crashing
  295. if( announce ) emit enabled( b );
  296. }
  297. //////////////////////////////////////////////////////////////////////////////////////////
  298. // SelectAction
  299. //////////////////////////////////////////////////////////////////////////////////////////
  300. SelectAction::SelectAction( const TQString &text, void ( *f ) ( int ), TDEActionCollection* const ac, const char *name )
  301. : TDESelectAction( text, 0, ac, name )
  302. , m_function( f )
  303. { }
  304. void SelectAction::setCurrentItem( int n )
  305. {
  306. const bool announce = n != currentItem();
  307. m_function( n );
  308. TDESelectAction::setCurrentItem( n );
  309. AmarokConfig::writeConfig(); //So we don't lose the setting when crashing
  310. if( announce ) emit activated( n );
  311. }
  312. void SelectAction::setEnabled( bool b )
  313. {
  314. const bool announce = b != isEnabled();
  315. if( !b )
  316. setCurrentItem( 0 );
  317. TDESelectAction::setEnabled( b );
  318. AmarokConfig::writeConfig(); //So we don't lose the setting when crashing
  319. if( announce ) emit enabled( b );
  320. }
  321. void SelectAction::setIcons( TQStringList icons )
  322. {
  323. m_icons = icons;
  324. for( int i = 0, n = items().count(); i < n; ++i )
  325. popupMenu()->changeItem( i, kapp->iconLoader()->loadIconSet( *icons.at( i ), TDEIcon::Small ), popupMenu()->text( i ) );
  326. }
  327. TQStringList SelectAction::icons() const { return m_icons; }
  328. TQString SelectAction::currentIcon() const
  329. {
  330. if( m_icons.count() )
  331. return *m_icons.at( currentItem() );
  332. return TQString();
  333. }
  334. TQString SelectAction::currentText() const {
  335. return TDESelectAction::currentText() + "<br /><br />" + i18n("Click to change");
  336. }
  337. //////////////////////////////////////////////////////////////////////////////////////////
  338. // VolumeAction
  339. //////////////////////////////////////////////////////////////////////////////////////////
  340. VolumeAction::VolumeAction( TDEActionCollection *ac )
  341. : TDEAction( i18n( "Volume" ), 0, ac, "toolbar_volume" )
  342. , EngineObserver( EngineController::instance() )
  343. , m_slider( 0 ) //is TQGuardedPtr
  344. {}
  345. int
  346. VolumeAction::plug( TQWidget *w, int index )
  347. {
  348. //NOTE we only support one plugging currently
  349. delete static_cast<Amarok::VolumeSlider*>( m_slider ); //just in case, remember, we only support one plugging!
  350. m_slider = new Amarok::VolumeSlider( w, Amarok::VOLUME_MAX );
  351. m_slider->setName( "ToolBarVolume" );
  352. m_slider->setValue( AmarokConfig::masterVolume() );
  353. m_slider->setSizePolicy( TQSizePolicy::Fixed, TQSizePolicy::Ignored );
  354. TQToolTip::add( m_slider, i18n( "Volume control" ) );
  355. EngineController* const ec = EngineController::instance();
  356. connect( m_slider, TQT_SIGNAL(sliderMoved( int )), ec, TQT_SLOT(setVolume( int )) );
  357. connect( m_slider, TQT_SIGNAL(sliderReleased( int )), ec, TQT_SLOT(setVolume( int )) );
  358. static_cast<TDEToolBar*>(w)->insertWidget( TDEAction::getToolButtonID(), 0, m_slider, index );
  359. return 0;
  360. }
  361. void
  362. VolumeAction::engineVolumeChanged( int value )
  363. {
  364. if( m_slider ) m_slider->setValue( value );
  365. }
  366. //////////////////////////////////////////////////////////////////////////////////////////
  367. // RandomAction
  368. //////////////////////////////////////////////////////////////////////////////////////////
  369. RandomAction::RandomAction( TDEActionCollection *ac ) :
  370. SelectAction( i18n( "Ra&ndom" ), &AmarokConfig::setRandomMode, ac, "random_mode" )
  371. {
  372. setItems( TQStringList() << i18n( "&Off" ) << i18n( "&Tracks" ) << i18n( "&Albums" ) );
  373. setCurrentItem( AmarokConfig::randomMode() );
  374. setIcons( TQStringList() << Amarok::icon( "random_no" ) << Amarok::icon( "random_track" ) << Amarok::icon( "random_album" ) );
  375. }
  376. void
  377. RandomAction::setCurrentItem( int n )
  378. {
  379. if( TDEAction *a = parentCollection()->action( "favor_tracks" ) )
  380. a->setEnabled( n );
  381. SelectAction::setCurrentItem( n );
  382. }
  383. //////////////////////////////////////////////////////////////////////////////////////////
  384. // FavorAction
  385. //////////////////////////////////////////////////////////////////////////////////////////
  386. FavorAction::FavorAction( TDEActionCollection *ac ) :
  387. SelectAction( i18n( "&Favor" ), &AmarokConfig::setFavorTracks, ac, "favor_tracks" )
  388. {
  389. setItems( TQStringList() << i18n( "Off" )
  390. << i18n( "Higher &Scores" )
  391. << i18n( "Higher &Ratings" )
  392. << i18n( "Not Recently &Played" ) );
  393. setCurrentItem( AmarokConfig::favorTracks() );
  394. setEnabled( AmarokConfig::randomMode() );
  395. }
  396. //////////////////////////////////////////////////////////////////////////////////////////
  397. // RepeatAction
  398. //////////////////////////////////////////////////////////////////////////////////////////
  399. RepeatAction::RepeatAction( TDEActionCollection *ac ) :
  400. SelectAction( i18n( "&Repeat" ), &AmarokConfig::setRepeat, ac, "repeat" )
  401. {
  402. setItems( TQStringList() << i18n( "&Off" ) << i18n( "&Track" )
  403. << i18n( "&Album" ) << i18n( "&Playlist" ) );
  404. setIcons( TQStringList() << Amarok::icon( "repeat_no" ) << Amarok::icon( "repeat_track" ) << Amarok::icon( "repeat_album" ) << Amarok::icon( "repeat_playlist" ) );
  405. setCurrentItem( AmarokConfig::repeat() );
  406. }
  407. //////////////////////////////////////////////////////////////////////////////////////////
  408. // BurnMenuAction
  409. //////////////////////////////////////////////////////////////////////////////////////////
  410. BurnMenuAction::BurnMenuAction( TDEActionCollection *ac )
  411. : TDEAction( i18n( "Burn" ), 0, ac, "burn_menu" )
  412. {}
  413. int
  414. BurnMenuAction::plug( TQWidget *w, int index )
  415. {
  416. TDEToolBar *bar = dynamic_cast<TDEToolBar*>(w);
  417. if( bar && kapp->authorizeTDEAction( name() ) )
  418. {
  419. const int id = TDEAction::getToolButtonID();
  420. addContainer( bar, id );
  421. connect( bar, TQT_SIGNAL( destroyed() ), TQT_SLOT( slotDestroyed() ) );
  422. bar->insertButton( TQString(), id, true, i18n( "Burn" ), index );
  423. TDEToolBarButton* button = bar->getButton( id );
  424. button->setPopup( Amarok::BurnMenu::instance() );
  425. button->setName( "toolbutton_burn_menu" );
  426. button->setIcon( "k3b" );
  427. return containerCount() - 1;
  428. }
  429. else return -1;
  430. }
  431. BurnMenu::BurnMenu()
  432. {
  433. insertItem( i18n("Current Playlist"), CURRENT_PLAYLIST );
  434. insertItem( i18n("Selected Tracks"), SELECTED_TRACKS );
  435. //TODO add "album" and "all tracks by artist"
  436. connect( this, TQT_SIGNAL( aboutToShow() ), TQT_SLOT( slotAboutToShow() ) );
  437. connect( this, TQT_SIGNAL( activated(int) ), TQT_SLOT( slotActivated(int) ) );
  438. }
  439. TDEPopupMenu*
  440. BurnMenu::instance()
  441. {
  442. static BurnMenu menu;
  443. return &menu;
  444. }
  445. void
  446. BurnMenu::slotAboutToShow()
  447. {}
  448. void
  449. BurnMenu::slotActivated( int index )
  450. {
  451. switch( index )
  452. {
  453. case CURRENT_PLAYLIST:
  454. K3bExporter::instance()->exportCurrentPlaylist();
  455. break;
  456. case SELECTED_TRACKS:
  457. K3bExporter::instance()->exportSelectedTracks();
  458. break;
  459. }
  460. }
  461. //////////////////////////////////////////////////////////////////////////////////////////
  462. // StopMenuAction
  463. //////////////////////////////////////////////////////////////////////////////////////////
  464. StopAction::StopAction( TDEActionCollection *ac )
  465. : TDEAction( i18n( "Stop" ), Amarok::icon( "stop" ), 0, EngineController::instance(), TQT_SLOT( stop() ), ac, "stop" )
  466. {}
  467. int
  468. StopAction::plug( TQWidget *w, int index )
  469. {
  470. TDEToolBar *bar = dynamic_cast<TDEToolBar*>(w);
  471. if( bar && kapp->authorizeTDEAction( name() ) )
  472. {
  473. const int id = TDEAction::getToolButtonID();
  474. addContainer( bar, id );
  475. connect( bar, TQT_SIGNAL( destroyed() ), TQT_SLOT( slotDestroyed() ) );
  476. bar->insertButton( TQString(), id, TQT_SIGNAL( clicked() ), EngineController::instance(), TQT_SLOT( stop() ),
  477. true, i18n( "Stop" ), index );
  478. TDEToolBarButton* button = bar->getButton( id );
  479. button->setDelayedPopup( Amarok::StopMenu::instance() );
  480. button->setName( "toolbutton_stop_menu" );
  481. button->setIcon( Amarok::icon( "stop" ) );
  482. button->setEnabled( EngineController::instance()->engine()->loaded() ); // Disable button at startup
  483. return containerCount() - 1;
  484. }
  485. else return TDEAction::plug( w, index );
  486. }
  487. StopMenu::StopMenu()
  488. {
  489. insertTitle( i18n( "Stop" ) );
  490. insertItem( i18n("Now"), NOW );
  491. insertItem( i18n("After Current Track"), AFTER_TRACK );
  492. insertItem( i18n("After Queue"), AFTER_QUEUE );
  493. connect( this, TQT_SIGNAL( aboutToShow() ), TQT_SLOT( slotAboutToShow() ) );
  494. connect( this, TQT_SIGNAL( activated(int) ), TQT_SLOT( slotActivated(int) ) );
  495. }
  496. TDEPopupMenu*
  497. StopMenu::instance()
  498. {
  499. static StopMenu menu;
  500. return &menu;
  501. }
  502. void
  503. StopMenu::slotAboutToShow()
  504. {
  505. Playlist *pl = Playlist::instance();
  506. setItemEnabled( NOW, Amarok::actionCollection()->action( "stop" )->isEnabled() );
  507. setItemEnabled( AFTER_TRACK, EngineController::engine()->loaded() );
  508. setItemChecked( AFTER_TRACK, pl->stopAfterMode() == Playlist::StopAfterCurrent );
  509. setItemEnabled( AFTER_QUEUE, pl->nextTracks().count() );
  510. setItemChecked( AFTER_QUEUE, pl->stopAfterMode() == Playlist::StopAfterQueue );
  511. }
  512. void
  513. StopMenu::slotActivated( int index )
  514. {
  515. Playlist* pl = Playlist::instance();
  516. const int mode = pl->stopAfterMode();
  517. switch( index )
  518. {
  519. case NOW:
  520. Amarok::actionCollection()->action( "stop" )->activate();
  521. if( mode == Playlist::StopAfterCurrent || mode == Playlist::StopAfterQueue )
  522. pl->setStopAfterMode( Playlist::DoNotStop );
  523. break;
  524. case AFTER_TRACK:
  525. pl->setStopAfterMode( mode == Playlist::StopAfterCurrent
  526. ? Playlist::DoNotStop
  527. : Playlist::StopAfterCurrent );
  528. break;
  529. case AFTER_QUEUE:
  530. pl->setStopAfterMode( mode == Playlist::StopAfterQueue
  531. ? Playlist::DoNotStop
  532. : Playlist::StopAfterQueue );
  533. break;
  534. }
  535. }
  536. #include "actionclasses.moc"