Amarok – versatile and easy to use audio player
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 
 
 
 
 

666 řádky
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"