/***************************************************************************
begin : Fre Nov 15 2002
copyright : ( C ) Mark Kretschmann < markey @ web . de >
: ( C ) Max Howell < max . howell @ methylblue . com >
: ( C ) G ? ? bor Lehel < illissius @ gmail . com >
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/***************************************************************************
* *
* 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 . *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include "config.h" //HAVE_LIBVISUAL definition
# include "actionclasses.h" //see toolbar construction
# include "amarok.h"
# include "amarokconfig.h"
# include "browserbar.h"
# include "clicklineedit.h" //m_lineEdit
# include "collectionbrowser.h"
# include "contextbrowser.h"
# include "debug.h"
# include "mediadevicemanager.h"
# include "editfilterdialog.h"
# include "enginecontroller.h" //for actions in ctor
# include "filebrowser.h"
# include "k3bexporter.h"
# include "lastfm.h" //check credentials when adding lastfm streams
# include "mediabrowser.h"
# include "dynamicmode.h"
# include "playlist.h"
# include "playlistbrowser.h"
# include "playlistwindow.h"
# include "scriptmanager.h"
# include "statistics.h"
# include "statusbar.h"
# include "threadmanager.h"
# include "magnatunebrowser/magnatunebrowser.h"
# include <tqevent.h> //eventFilter()
# include <tqfont.h>
# include <tqheader.h>
# include <tqlayout.h>
# include <tqlabel.h> //search filter label
# include <tqpainter.h> //dynamic title
# include <tqpen.h>
# include <tqsizepolicy.h> //qspaceritem in dynamic bar
# include <tqtimer.h> //search filter timer
# include <tqtooltip.h> //TQToolTip::add()
# include <tqvbox.h> //contains the playlist
# include <kaction.h> //m_actionCollection
# include <kapplication.h> //kapp
# include <kfiledialog.h> //savePlaylist(), openPlaylist()
# include <kglobal.h>
# include <khtml_part.h> //Welcome Tab
# include <kiconloader.h> //ClearFilter button
# include <kinputdialog.h> //slotAddStream()
# include <klocale.h>
# include <kmenubar.h>
# include <kmessagebox.h> //savePlaylist()
# include <kpopupmenu.h>
# include <kpushbutton.h>
# include <kstandarddirs.h> //Welcome Tab, locate welcome.html
# include <ktoolbar.h>
# include <ktoolbarbutton.h> //createGUI()
# include <kxmlguibuilder.h> //XMLGUI
# include <kxmlguifactory.h> //XMLGUI
# include <fixx11h.h>
//////////////////////////////////////////////////////////////////////////////////////////
/// CLASS Amarok::ToolBar
//////////////////////////////////////////////////////////////////////////////////////////
namespace Amarok
{
class ToolBar : public KToolBar
{
public :
ToolBar ( TQWidget * parent , const char * name )
: KToolBar ( parent , name )
{ }
protected :
virtual void
contextMenuEvent ( TQContextMenuEvent * e ) {
Amarok : : Menu : : instance ( ) - > popup ( e - > globalPos ( ) ) ;
}
virtual void
wheelEvent ( TQWheelEvent * e ) {
EngineController : : instance ( ) - > increaseVolume ( e - > delta ( ) / Amarok : : VOLUME_SENSITIVITY ) ;
}
} ;
}
PlaylistWindow * PlaylistWindow : : s_instance = 0 ;
PlaylistWindow : : PlaylistWindow ( )
: TQWidget ( 0 , " PlaylistWindow " , TQt : : WGroupLeader )
, KXMLGUIClient ( )
, m_lastBrowser ( 0 )
{
s_instance = this ;
// Sets caption and icon correctly (needed e.g. for GNOME)
kapp - > setTopWidget ( this ) ;
KActionCollection * const ac = actionCollection ( ) ;
const EngineController * const ec = EngineController : : instance ( ) ;
ac - > setAutoConnectShortcuts ( false ) ;
ac - > setWidget ( this ) ;
new K3bExporter ( ) ;
KStdAction : : configureToolbars ( TQT_TQOBJECT ( kapp ) , TQT_SLOT ( slotConfigToolBars ( ) ) , ac ) ;
KStdAction : : keyBindings ( TQT_TQOBJECT ( kapp ) , TQT_SLOT ( slotConfigShortcuts ( ) ) , ac ) ;
KStdAction : : keyBindings ( TQT_TQOBJECT ( kapp ) , TQT_SLOT ( slotConfigGlobalShortcuts ( ) ) , ac , " options_configure_globals " ) ;
KStdAction : : preferences ( TQT_TQOBJECT ( kapp ) , TQT_SLOT ( slotConfigAmarok ( ) ) , ac ) ;
ac - > action ( " options_configure_globals " ) - > setIcon ( Amarok : : icon ( " configure " ) ) ;
ac - > action ( KStdAction : : name ( KStdAction : : KeyBindings ) ) - > setIcon ( Amarok : : icon ( " configure " ) ) ;
ac - > action ( KStdAction : : name ( KStdAction : : ConfigureToolbars ) ) - > setIcon ( Amarok : : icon ( " configure " ) ) ;
ac - > action ( KStdAction : : name ( KStdAction : : Preferences ) ) - > setIcon ( Amarok : : icon ( " configure " ) ) ;
KStdAction : : quit ( TQT_TQOBJECT ( kapp ) , TQT_SLOT ( quit ( ) ) , ac ) ;
KStdAction : : open ( TQT_TQOBJECT ( this ) , TQT_SLOT ( slotAddLocation ( ) ) , ac , " playlist_add " ) - > setText ( i18n ( " &Add Media... " ) ) ;
ac - > action ( " playlist_add " ) - > setIcon ( Amarok : : icon ( " files " ) ) ;
KStdAction : : open ( TQT_TQOBJECT ( this ) , TQT_SLOT ( slotAddStream ( ) ) , ac , " stream_add " ) - > setText ( i18n ( " &Add Stream... " ) ) ;
ac - > action ( " stream_add " ) - > setIcon ( Amarok : : icon ( " files " ) ) ;
KStdAction : : save ( TQT_TQOBJECT ( this ) , TQT_SLOT ( savePlaylist ( ) ) , ac , " playlist_save " ) - > setText ( i18n ( " &Save Playlist As... " ) ) ;
ac - > action ( " playlist_save " ) - > setIcon ( Amarok : : icon ( " save " ) ) ;
# ifndef TQ_WS_MAC
KStdAction : : showMenubar ( TQT_TQOBJECT ( this ) , TQT_SLOT ( slotToggleMenu ( ) ) , ac ) ;
# endif
//FIXME: after string freeze rename to "Burn Current Playlist"?
new KAction ( i18n ( " Burn to CD " ) , Amarok : : icon ( " burn " ) , 0 , TQT_TQOBJECT ( this ) , TQT_SLOT ( slotBurnPlaylist ( ) ) , ac , " playlist_burn " ) ;
actionCollection ( ) - > action ( " playlist_burn " ) - > setEnabled ( K3bExporter : : isAvailable ( ) ) ;
new KAction ( i18n ( " Play Media... " ) , Amarok : : icon ( " files " ) , 0 , TQT_TQOBJECT ( this ) , TQT_SLOT ( slotPlayMedia ( ) ) , ac , " playlist_playmedia " ) ;
new KAction ( i18n ( " Play Audio CD " ) , Amarok : : icon ( " album " ) , 0 , TQT_TQOBJECT ( this ) , TQT_SLOT ( playAudioCD ( ) ) , ac , " play_audiocd " ) ;
KAction * playPause = new KAction ( i18n ( " &Play/Pause " ) , Amarok : : icon ( " play " ) , Key_Space , ec , TQT_SLOT ( playPause ( ) ) , ac , " play_pause " ) ;
new KAction ( i18n ( " Script Manager " ) , Amarok : : icon ( " scripts " ) , 0 , TQT_TQOBJECT ( this ) , TQT_SLOT ( showScriptSelector ( ) ) , ac , " script_manager " ) ;
new KAction ( i18n ( " Queue Manager " ) , Amarok : : icon ( " queue " ) , 0 , TQT_TQOBJECT ( this ) , TQT_SLOT ( showQueueManager ( ) ) , ac , " queue_manager " ) ;
KAction * seekForward = new KAction ( i18n ( " &Seek Forward " ) , Amarok : : icon ( " fastforward " ) , Key_Right , ec , TQT_SLOT ( seekForward ( ) ) , ac , " seek_forward " ) ;
KAction * seekBackward = new KAction ( i18n ( " &Seek Backward " ) , Amarok : : icon ( " rewind " ) , Key_Left , ec , TQT_SLOT ( seekBackward ( ) ) , ac , " seek_backward " ) ;
new KAction ( i18n ( " Statistics " ) , Amarok : : icon ( " info " ) , 0 , TQT_TQOBJECT ( this ) , TQT_SLOT ( showStatistics ( ) ) , ac , " statistics " ) ;
new KAction ( i18n ( " Update Collection " ) , Amarok : : icon ( " refresh " ) , 0 , CollectionDB : : instance ( ) , TQT_SLOT ( scanModifiedDirs ( ) ) , actionCollection ( ) , " update_collection " ) ;
m_lastfmTags < < " Alternative " < < " Ambient " < < " Chill Out " < < " Classical " < < " Dance "
< < " Electronica " < < " Favorites " < < " Heavy Metal " < < " Hip Hop " < < " Indie Rock "
< < " Industrial " < < " Japanese " < < " Pop " < < " Psytrance " < < " Rap " < < " Rock "
< < " Soundtrack " < < " Techno " < < " Trance " ;
KPopupMenu * playTagRadioMenu = new KPopupMenu ( this ) ;
int id = 0 ;
foreach ( m_lastfmTags ) {
playTagRadioMenu - > insertItem ( * it , this , TQT_SLOT ( playLastfmGlobaltag ( int ) ) , 0 , id ) ;
+ + id ;
}
KPopupMenu * addTagRadioMenu = new KPopupMenu ( this ) ;
id = 0 ;
foreach ( m_lastfmTags ) {
addTagRadioMenu - > insertItem ( * it , this , TQT_SLOT ( addLastfmGlobaltag ( int ) ) , 0 , id ) ;
+ + id ;
}
KActionMenu * playLastfm = new KActionMenu ( i18n ( " Play las&t.fm Stream " ) , Amarok : : icon ( " audioscrobbler " ) , ac , " lastfm_play " ) ;
TQPopupMenu * playLastfmMenu = playLastfm - > popupMenu ( ) ;
playLastfmMenu - > insertItem ( i18n ( " Personal Radio " ) , this , TQT_SLOT ( playLastfmPersonal ( ) ) ) ;
playLastfmMenu - > insertItem ( i18n ( " Neighbor Radio " ) , this , TQT_SLOT ( playLastfmNeighbor ( ) ) ) ;
playLastfmMenu - > insertItem ( i18n ( " Custom Station " ) , this , TQT_SLOT ( playLastfmCustom ( ) ) ) ;
playLastfmMenu - > insertItem ( i18n ( " Global Tag Radio " ) , playTagRadioMenu ) ;
KActionMenu * addLastfm = new KActionMenu ( i18n ( " Add las&t.fm Stream " ) , Amarok : : icon ( " audioscrobbler " ) , ac , " lastfm_add " ) ;
TQPopupMenu * addLastfmMenu = addLastfm - > popupMenu ( ) ;
addLastfmMenu - > insertItem ( i18n ( " Personal Radio " ) , this , TQT_SLOT ( addLastfmPersonal ( ) ) ) ;
addLastfmMenu - > insertItem ( i18n ( " Neighbor Radio " ) , this , TQT_SLOT ( addLastfmNeighbor ( ) ) ) ;
addLastfmMenu - > insertItem ( i18n ( " Custom Station " ) , this , TQT_SLOT ( addLastfmCustom ( ) ) ) ;
addLastfmMenu - > insertItem ( i18n ( " Global Tag Radio " ) , addTagRadioMenu ) ;
ac - > action ( " options_configure_globals " ) - > setText ( i18n ( " Configure &Global Shortcuts... " ) ) ;
new KAction ( i18n ( " Previous Track " ) , Amarok : : icon ( " back " ) , 0 , ec , TQT_SLOT ( previous ( ) ) , ac , " prev " ) ;
new KAction ( i18n ( " Play " ) , Amarok : : icon ( " play " ) , 0 , ec , TQT_SLOT ( play ( ) ) , ac , " play " ) ;
new KAction ( i18n ( " Pause " ) , Amarok : : icon ( " pause " ) , 0 , ec , TQT_SLOT ( pause ( ) ) , ac , " pause " ) ;
new KAction ( i18n ( " Next Track " ) , Amarok : : icon ( " next " ) , 0 , ec , TQT_SLOT ( next ( ) ) , ac , " next " ) ;
KAction * toggleFocus = new KAction ( i18n ( " Toggle Focus " ) , " reload " , CTRL + Key_Tab , TQT_TQOBJECT ( this ) , TQT_SLOT ( slotToggleFocus ( ) ) , ac , " toggle_focus " ) ;
{ // KAction idiocy -- shortcuts don't work until they've been plugged into a menu
KPopupMenu asdf ;
playPause - > plug ( & asdf ) ;
seekForward - > plug ( & asdf ) ;
seekBackward - > plug ( & asdf ) ;
toggleFocus - > plug ( & asdf ) ;
playPause - > unplug ( & asdf ) ;
seekForward - > unplug ( & asdf ) ;
seekBackward - > unplug ( & asdf ) ;
toggleFocus - > unplug ( & asdf ) ;
}
new Amarok : : MenuAction ( ac ) ;
new Amarok : : StopAction ( ac ) ;
new Amarok : : PlayPauseAction ( ac ) ;
new Amarok : : AnalyzerAction ( ac ) ;
new Amarok : : RepeatAction ( ac ) ;
new Amarok : : RandomAction ( ac ) ;
new Amarok : : FavorAction ( ac ) ;
new Amarok : : VolumeAction ( ac ) ;
if ( K3bExporter : : isAvailable ( ) )
new Amarok : : BurnMenuAction ( ac ) ;
if ( AmarokConfig : : playlistWindowSize ( ) . isValid ( ) ) {
// if first ever run, use sizeHint(), and let
// KWin place us otherwise use the stored values
resize ( AmarokConfig : : playlistWindowSize ( ) ) ;
move ( AmarokConfig : : playlistWindowPos ( ) ) ;
}
}
PlaylistWindow : : ~ PlaylistWindow ( )
{
Amarok : : config ( " PlaylistWindow " ) - > writeEntry ( " showMenuBar " , m_menubar - > isShown ( ) ) ;
AmarokConfig : : setPlaylistWindowPos ( pos ( ) ) ; //TODO de XT?
AmarokConfig : : setPlaylistWindowSize ( size ( ) ) ; //TODO de XT?
}
///////// public interface
/**
* This function will initialize the playlist window .
*/
void PlaylistWindow : : init ( )
{
DEBUG_BLOCK
//this function is necessary because Amarok::actionCollection() returns our actionCollection
//via the App::m_pPlaylistWindow pointer since App::m_pPlaylistWindow is not defined until
//the above ctor returns it causes a crash unless we do the initialisation in 2 stages.
m_browsers = new BrowserBar ( this ) ;
//<Dynamic Mode Status Bar />
DynamicBar * dynamicBar = new DynamicBar ( m_browsers - > container ( ) ) ;
TQFrame * playlist ;
{ //<Search LineEdit>
KToolBar * bar = new KToolBar ( m_browsers - > container ( ) , " NotMainToolBar " ) ;
bar - > setIconSize ( 22 , false ) ; //looks more sensible
bar - > setFlat ( true ) ; //removes the ugly frame
bar - > setMovingEnabled ( false ) ; //removes the ugly frame
playlist = new Playlist ( m_browsers - > container ( ) ) ;
actionCollection ( ) - > action ( " playlist_clear " ) - > plug ( bar ) ;
actionCollection ( ) - > action ( " playlist_save " ) - > plug ( bar ) ;
bar - > addSeparator ( ) ;
actionCollection ( ) - > action ( " playlist_undo " ) - > plug ( bar ) ;
actionCollection ( ) - > action ( " playlist_redo " ) - > plug ( bar ) ;
bar - > boxLayout ( ) - > addStretch ( ) ;
TQWidget * button = new KToolBarButton ( " locationbar_erase " , 1 , bar ) ;
TQLabel * filter_label = new TQLabel ( i18n ( " S&earch: " ) + ' ' , bar ) ;
m_lineEdit = new ClickLineEdit ( i18n ( " Playlist Search " ) , bar ) ;
filter_label - > setBuddy ( m_lineEdit ) ;
bar - > setStretchableWidget ( m_lineEdit ) ;
KPushButton * filterButton = new KPushButton ( " ... " , bar , " filter " ) ;
filterButton - > setSizePolicy ( TQSizePolicy : : Preferred , TQSizePolicy : : Fixed ) ;
m_lineEdit - > setFrame ( TQFrame : : Sunken ) ;
m_lineEdit - > installEventFilter ( this ) ; //we intercept keyEvents
connect ( button , TQT_SIGNAL ( clicked ( ) ) , m_lineEdit , TQT_SLOT ( clear ( ) ) ) ;
connect ( m_lineEdit , TQT_SIGNAL ( textChanged ( const TQString & ) ) ,
playlist , TQT_SLOT ( setFilterSlot ( const TQString & ) ) ) ;
connect ( filterButton , TQT_SIGNAL ( clicked ( ) ) , TQT_SLOT ( slotEditFilter ( ) ) ) ;
TQToolTip : : add ( button , i18n ( " Clear search field " ) ) ;
TQString filtertip = i18n ( " Enter space-separated terms to search in the playlist. \n \n "
" Advanced, Google-esque syntax is also available; \n "
" see the handbook (The Playlist section of chapter 4) for details. " ) ;
TQToolTip : : add ( m_lineEdit , filtertip ) ;
TQToolTip : : add ( filterButton , i18n ( " Click to edit playlist filter " ) ) ;
} //</Search LineEdit>
dynamicBar - > init ( ) ;
m_toolbar = new Amarok : : ToolBar ( m_browsers - > container ( ) , " mainToolBar " ) ;
# ifndef TQ_WS_MAC
m_toolbar - > setShown ( AmarokConfig : : showToolbar ( ) ) ;
# endif
TQWidget * statusbar = new Amarok : : StatusBar ( this ) ;
KAction * repeatAction = Amarok : : actionCollection ( ) - > action ( " repeat " ) ;
connect ( repeatAction , TQT_SIGNAL ( activated ( int ) ) , playlist , TQT_SLOT ( slotRepeatTrackToggled ( int ) ) ) ;
m_menubar = new KMenuBar ( this ) ;
# ifndef TQ_WS_MAC
m_menubar - > setShown ( AmarokConfig : : showMenuBar ( ) ) ;
# endif
//BEGIN Actions menu
KPopupMenu * actionsMenu = new KPopupMenu ( m_menubar ) ;
actionCollection ( ) - > action ( " playlist_playmedia " ) - > plug ( actionsMenu ) ;
actionCollection ( ) - > action ( " lastfm_play " ) - > plug ( actionsMenu ) ;
actionCollection ( ) - > action ( " play_audiocd " ) - > plug ( actionsMenu ) ;
actionsMenu - > insertSeparator ( ) ;
actionCollection ( ) - > action ( " prev " ) - > plug ( actionsMenu ) ;
actionCollection ( ) - > action ( " play_pause " ) - > plug ( actionsMenu ) ;
actionCollection ( ) - > action ( " stop " ) - > plug ( actionsMenu ) ;
actionCollection ( ) - > action ( " next " ) - > plug ( actionsMenu ) ;
actionsMenu - > insertSeparator ( ) ;
actionCollection ( ) - > action ( KStdAction : : name ( KStdAction : : Quit ) ) - > plug ( actionsMenu ) ;
connect ( actionsMenu , TQT_SIGNAL ( aboutToShow ( ) ) , TQT_SLOT ( actionsMenuAboutToShow ( ) ) ) ;
//END Actions menu
//BEGIN Playlist menu
KPopupMenu * playlistMenu = new KPopupMenu ( m_menubar ) ;
actionCollection ( ) - > action ( " playlist_add " ) - > plug ( playlistMenu ) ;
actionCollection ( ) - > action ( " stream_add " ) - > plug ( playlistMenu ) ;
actionCollection ( ) - > action ( " lastfm_add " ) - > plug ( playlistMenu ) ;
actionCollection ( ) - > action ( " playlist_save " ) - > plug ( playlistMenu ) ;
actionCollection ( ) - > action ( " playlist_burn " ) - > plug ( playlistMenu ) ;
playlistMenu - > insertSeparator ( ) ;
actionCollection ( ) - > action ( " playlist_undo " ) - > plug ( playlistMenu ) ;
actionCollection ( ) - > action ( " playlist_redo " ) - > plug ( playlistMenu ) ;
playlistMenu - > insertSeparator ( ) ;
actionCollection ( ) - > action ( " playlist_clear " ) - > plug ( playlistMenu ) ;
actionCollection ( ) - > action ( " playlist_shuffle " ) - > plug ( playlistMenu ) ;
//this one has no real context with regard to the menu
//actionCollection()->action("playlist_copy")->plug( playlistMenu );
playlistMenu - > insertSeparator ( ) ;
actionCollection ( ) - > action ( " queue_selected " ) - > plug ( playlistMenu ) ;
actionCollection ( ) - > action ( " playlist_remove_duplicates " ) - > plug ( playlistMenu ) ;
actionCollection ( ) - > action ( " playlist_select_all " ) - > plug ( playlistMenu ) ;
//END Playlist menu
//BEGIN Mode menu
KPopupMenu * modeMenu = new KPopupMenu ( m_menubar ) ;
actionCollection ( ) - > action ( " repeat " ) - > plug ( modeMenu ) ;
KSelectAction * random = static_cast < KSelectAction * > ( actionCollection ( ) - > action ( " random_mode " ) ) ;
random - > plug ( modeMenu ) ;
random - > popupMenu ( ) - > insertSeparator ( ) ;
actionCollection ( ) - > action ( " favor_tracks " ) - > plug ( random - > popupMenu ( ) ) ;
//END Mode menu
//BEGIN Tools menu
m_toolsMenu = new KPopupMenu ( m_menubar ) ;
m_toolsMenu - > insertItem ( SmallIconSet ( Amarok : : icon ( " covermanager " ) ) , i18n ( " &Cover Manager " ) , Amarok : : Menu : : ID_SHOW_COVER_MANAGER ) ;
actionCollection ( ) - > action ( " queue_manager " ) - > plug ( m_toolsMenu ) ;
m_toolsMenu - > insertItem ( SmallIconSet ( Amarok : : icon ( " visualizations " ) ) , i18n ( " &Visualizations " ) , Amarok : : Menu : : ID_SHOW_VIS_SELECTOR ) ;
m_toolsMenu - > insertItem ( SmallIconSet ( Amarok : : icon ( " equalizer " ) ) , i18n ( " &Equalizer " ) , TQT_TQOBJECT ( kapp ) , TQT_SLOT ( slotConfigEqualizer ( ) ) , 0 , Amarok : : Menu : : ID_CONFIGURE_EQUALIZER ) ;
actionCollection ( ) - > action ( " script_manager " ) - > plug ( m_toolsMenu ) ;
actionCollection ( ) - > action ( " statistics " ) - > plug ( m_toolsMenu ) ;
m_toolsMenu - > insertSeparator ( ) ;
actionCollection ( ) - > action ( " update_collection " ) - > plug ( m_toolsMenu ) ;
m_toolsMenu - > insertItem ( SmallIconSet ( Amarok : : icon ( " rescan " ) ) , i18n ( " &Rescan Collection " ) , Amarok : : Menu : : ID_RESCAN_COLLECTION ) ;
# if defined HAVE_LIBVISUAL
m_toolsMenu - > setItemEnabled ( Amarok : : Menu : : ID_SHOW_VIS_SELECTOR , true ) ;
# else
m_toolsMenu - > setItemEnabled ( Amarok : : Menu : : ID_SHOW_VIS_SELECTOR , false ) ;
# endif
connect ( m_toolsMenu , TQT_SIGNAL ( aboutToShow ( ) ) , TQT_SLOT ( toolsMenuAboutToShow ( ) ) ) ;
connect ( m_toolsMenu , TQT_SIGNAL ( activated ( int ) ) , TQT_SLOT ( slotMenuActivated ( int ) ) ) ;
//END Tools menu
//BEGIN Settings menu
m_settingsMenu = new KPopupMenu ( m_menubar ) ;
//TODO use KStdAction or KMainWindow
# ifndef TQ_WS_MAC
static_cast < KToggleAction * > ( actionCollection ( ) - > action ( KStdAction : : name ( KStdAction : : ShowMenubar ) ) ) - > setChecked ( AmarokConfig : : showMenuBar ( ) ) ;
actionCollection ( ) - > action ( KStdAction : : name ( KStdAction : : ShowMenubar ) ) - > plug ( m_settingsMenu ) ;
m_settingsMenu - > insertItem ( AmarokConfig : : showToolbar ( ) ? i18n ( " Hide Toolbar " ) : i18n ( " Show Toolbar " ) , ID_SHOW_TOOLBAR ) ;
m_settingsMenu - > insertItem ( AmarokConfig : : showPlayerWindow ( ) ? i18n ( " Hide Player &Window " ) : i18n ( " Show Player &Window " ) , ID_SHOW_PLAYERWINDOW ) ;
m_settingsMenu - > insertSeparator ( ) ;
# endif
# ifdef TQ_WS_MAC
// plug it first, as this item will be moved to the applications first menu
actionCollection ( ) - > action ( KStdAction : : name ( KStdAction : : Preferences ) ) - > plug ( m_settingsMenu ) ;
# endif
actionCollection ( ) - > action ( " options_configure_globals " ) - > plug ( m_settingsMenu ) ;
actionCollection ( ) - > action ( KStdAction : : name ( KStdAction : : KeyBindings ) ) - > plug ( m_settingsMenu ) ;
actionCollection ( ) - > action ( KStdAction : : name ( KStdAction : : ConfigureToolbars ) ) - > plug ( m_settingsMenu ) ;
actionCollection ( ) - > action ( KStdAction : : name ( KStdAction : : Preferences ) ) - > plug ( m_settingsMenu ) ;
connect ( m_settingsMenu , TQT_SIGNAL ( activated ( int ) ) , TQT_SLOT ( slotMenuActivated ( int ) ) ) ;
//END Settings menu
m_menubar - > insertItem ( i18n ( " E&ngage " ) , actionsMenu ) ;
m_menubar - > insertItem ( i18n ( " &Playlist " ) , playlistMenu ) ;
m_menubar - > insertItem ( i18n ( " &Mode " ) , modeMenu ) ;
m_menubar - > insertItem ( i18n ( " &Tools " ) , m_toolsMenu ) ;
m_menubar - > insertItem ( i18n ( " &Settings " ) , m_settingsMenu ) ;
m_menubar - > insertItem ( i18n ( " &Help " ) , Amarok : : Menu : : helpMenu ( ) ) ;
TQBoxLayout * layV = new TQVBoxLayout ( this ) ;
layV - > addWidget ( m_menubar ) ;
layV - > addWidget ( m_browsers , 1 ) ;
layV - > addWidget ( m_toolbar ) ;
layV - > addSpacing ( 2 ) ;
layV - > addWidget ( statusbar ) ;
//The volume slider later becomes our FocusProxy, so all wheelEvents get redirected to it
m_toolbar - > setFocusPolicy ( TQ_WheelFocus ) ;
m_toolbar - > setFlat ( true ) ;
m_toolbar - > setMovingEnabled ( false ) ;
playlist - > setMargin ( 2 ) ;
playlist - > installEventFilter ( this ) ; //we intercept keyEvents
//<XMLGUI>
{
TQString xmlFile = Amarok : : config ( ) - > readEntry ( " XMLFile " , " amarokui.rc " ) ;
// this bug can bite you if you are a pre 1.2 user, we
// deleted amarokui_first.rc, but we must still support it
// NOTE 1.4.1 we remove amarokui_xmms.rc too, so we can only be this ui.rc
xmlFile = " amarokui.rc " ;
setXMLFile ( xmlFile ) ;
createGUI ( ) ; //NOTE we implement this
}
//</XMLGUI>
//<Browsers>
{
Debug : : Block block ( " Creating browsers. Please report long start times! " ) ;
# define addBrowserMacro( Type, name, text, icon ) { \
Debug : : Block block ( name ) ; \
m_browsers - > addBrowser ( name , new Type ( name ) , text , icon ) ; }
# define addInstBrowserMacro( Type, name, text, icon ) { \
Debug : : Block block ( name ) ; \
m_browsers - > addBrowser ( name , Type : : instance ( ) , text , icon ) ; }
addBrowserMacro ( ContextBrowser , " ContextBrowser " , i18n ( " Context " ) , Amarok : : icon ( " info " ) )
addBrowserMacro ( CollectionBrowser , " CollectionBrowser " , i18n ( " Collection " ) , Amarok : : icon ( " collection " ) )
m_browsers - > makeDropProxy ( " CollectionBrowser " , CollectionView : : instance ( ) ) ;
addInstBrowserMacro ( PlaylistBrowser , " PlaylistBrowser " , i18n ( " Playlists " ) , Amarok : : icon ( " playlist " ) )
//DEBUG: Comment out the addBrowserMacro line and uncomment the m_browsers line (passing in a vfat device name) to see the "virtual root" functionality
addBrowserMacro ( FileBrowser , " FileBrowser " , i18n ( " Files " ) , Amarok : : icon ( " files " ) )
//Add Magnatune browser
addInstBrowserMacro ( MagnatuneBrowser , " MagnatuneBrowser " , i18n ( " Magnatune " ) , Amarok : : icon ( " magnatune " ) )
new MediaBrowser ( " MediaBrowser " ) ;
if ( MediaBrowser : : isAvailable ( ) )
{
addInstBrowserMacro ( MediaBrowser , " MediaBrowser " , i18n ( " Devices " ) , Amarok : : icon ( " device " ) )
//to re-enable mediabrowser hiding, uncomment this:
//connect( MediaBrowser::instance(), TQT_SIGNAL( availabilityChanged( bool ) ),
// this, TQT_SLOT( mbAvailabilityChanged( bool ) ) );
m_browsers - > makeDropProxy ( " MediaBrowser " , MediaBrowser : : queue ( ) ) ;
}
# undef addBrowserMacro
# undef addInstBrowserMacro
}
//</Browsers>
connect ( Playlist : : instance ( ) - > qscrollview ( ) , TQT_SIGNAL ( dynamicModeChanged ( const DynamicMode * ) ) ,
PlaylistBrowser : : instance ( ) , TQT_SLOT ( loadDynamicItems ( ) ) ) ;
tqApp - > installEventFilter ( this ) ; // keyboards shortcuts for the browsers
connect ( playlist , TQT_SIGNAL ( itemCountChanged ( int , int , int , int , int , int ) ) ,
statusbar , TQT_SLOT ( slotItemCountChanged ( int , int , int , int , int , int ) ) ) ;
connect ( playlist , TQT_SIGNAL ( queueChanged ( const PLItemList & , const PLItemList & ) ) ,
statusbar , TQT_SLOT ( updateQueueLabel ( ) ) ) ;
connect ( playlist , TQT_SIGNAL ( aboutToClear ( ) ) , m_lineEdit , TQT_SLOT ( clear ( ) ) ) ;
Amarok : : MessageQueue : : instance ( ) - > sendMessages ( ) ;
}
void PlaylistWindow : : slotSetFilter ( const TQString & filter ) //SLOT
{
m_lineEdit - > setText ( filter ) ;
}
void PlaylistWindow : : slotEditFilter ( ) //SLOT
{
EditFilterDialog * fd = new EditFilterDialog ( this , true , m_lineEdit - > text ( ) ) ;
connect ( fd , TQT_SIGNAL ( filterChanged ( const TQString & ) ) , TQT_SLOT ( slotSetFilter ( const TQString & ) ) ) ;
if ( fd - > exec ( ) )
m_lineEdit - > setText ( fd - > filter ( ) ) ;
delete fd ;
}
void PlaylistWindow : : addBrowser ( const TQString & name , TQWidget * browser , const TQString & text , const TQString & icon )
{
if ( ! m_browsers - > browser ( name ) )
m_browsers - > addBrowser ( name , browser , text , icon ) ;
if ( name = = " MediaBrowser " )
{
m_browsers - > makeDropProxy ( " MediaBrowser " , MediaBrowser : : queue ( ) ) ;
}
}
/**
* Reload the amarokui . rc xml file .
* mainly just used by amarok : : Menu
*/
void PlaylistWindow : : recreateGUI ( )
{
reloadXML ( ) ;
createGUI ( ) ;
}
/**
* Create the amarok gui from the xml file .
*/
void PlaylistWindow : : createGUI ( )
{
setUpdatesEnabled ( false ) ;
LastFm : : Controller : : instance ( ) ; // create love/ban/skip actions
m_toolbar - > clear ( ) ;
//KActions don't unplug themselves when the widget that is plugged is deleted!
//we need to unplug to detect if the menu is plugged in App::applySettings()
//TODO report to bugs.kde.org
//we unplug after clear as otherwise it crashes! dunno why..
KActionPtrList actions = actionCollection ( ) - > actions ( ) ;
for ( KActionPtrList : : Iterator it = actions . begin ( ) , end = actions . end ( ) ; it ! = end ; + + it )
( * it ) - > unplug ( m_toolbar ) ;
KXMLGUIBuilder builder ( this ) ;
KXMLGUIFactory factory ( & builder , TQT_TQOBJECT ( this ) ) ;
//build Toolbar, plug actions
factory . addClient ( this ) ;
//TEXT ON RIGHT HACK
//KToolBarButtons have independent settings for their appearance.
//KToolBarButton::modeChange() causes that button to set its mode to that of its parent KToolBar
//KToolBar::setIconText() calls modeChange() for children, unless 2nd param is false
TQStringList list ;
list < < " toolbutton_playlist_add "
// << "toolbutton_playlist_clear"
// << "toolbutton_playlist_shuffle"
// << "toolbutton_playlist_show"
< < " toolbutton_burn_menu "
< < " toolbutton_amarok_menu " ;
m_toolbar - > setIconText ( KToolBar : : IconTextRight , false ) ; //we want some buttons to have text on right
const TQStringList : : ConstIterator end = list . constEnd ( ) ;
const TQStringList : : ConstIterator last = list . fromLast ( ) ;
for ( TQStringList : : ConstIterator it = list . constBegin ( ) ; it ! = end ; + + it )
{
KToolBarButton * const button = static_cast < KToolBarButton * > ( TQT_TQWIDGET ( m_toolbar - > child ( ( * it ) . latin1 ( ) ) ) ) ;
if ( it = = last ) {
//if the user has no PlayerWindow, he MUST have the menu action plugged
//NOTE this is not saved to the local XMLFile, which is what the user will want
if ( ! AmarokConfig : : showPlayerWindow ( ) & & ! AmarokConfig : : showMenuBar ( ) & & ! button )
actionCollection ( ) - > action ( " amarok_menu " ) - > plug ( m_toolbar ) ;
}
if ( button ) {
button - > modeChange ( ) ;
button - > setFocusPolicy ( TQ_NoFocus ) ;
}
}
m_toolbar - > setIconText ( KToolBar : : IconOnly , false ) ; //default appearance
conserveMemory ( ) ;
setUpdatesEnabled ( true ) ;
}
/**
* Apply the loaded settings on the playlist window .
* this function loads the custom fonts ( if chosen ) and than calls PlayList : : instance ( ) - > applySettings ( ) ;
*/
void PlaylistWindow : : applySettings ( )
{
switch ( AmarokConfig : : useCustomFonts ( ) )
{
case true :
Playlist : : instance ( ) - > setFont ( AmarokConfig : : playlistWindowFont ( ) ) ;
ContextBrowser : : instance ( ) - > setFont ( AmarokConfig : : contextBrowserFont ( ) ) ;
break ;
case false :
Playlist : : instance ( ) - > unsetFont ( ) ;
ContextBrowser : : instance ( ) - > unsetFont ( ) ;
break ;
}
}
/**
* @ param o The object
* @ param e The event
*
* Here we filter some events for the Playlist Search LineEdit and the Playlist . @ n
* this makes life easier since we have more useful functions available from this class
*/
bool PlaylistWindow : : eventFilter ( TQObject * o , TQEvent * e )
{
Playlist * const pl = Playlist : : instance ( ) ;
typedef TQListViewItemIterator It ;
switch ( e - > type ( ) )
{
case 6 /*TQEvent::KeyPress*/ :
//there are a few keypresses that we intercept
# define e TQT_TQKEYEVENT(e)
if ( e - > key ( ) = = Key_F2 )
{
// currentItem is ALWAYS visible.
TQListViewItem * item = pl - > currentItem ( ) ;
// intercept F2 for inline tag renaming
// NOTE: tab will move to the next tag
// NOTE: if item is still null don't select first item in playlist, user wouldn't want that. It's silly.
// TODO: berkus has solved the "inability to cancel" issue with KListView, but it's not in kdelibs yet..
// item may still be null, but this is safe
// NOTE: column 0 cannot be edited currently, hence we pick column 1
pl - > rename ( item , 1 ) ; //TODO what if this column is hidden?
return true ;
}
if ( e - > state ( ) & ControlButton )
{
int n = - 1 ;
switch ( e - > key ( ) )
{
case Key_0 : n = 0 ; break ;
case Key_1 : n = 1 ; break ;
case Key_2 : n = 2 ; break ;
case Key_3 : n = 3 ; break ;
case Key_4 : n = 4 ; break ;
case Key_5 : n = 5 ; break ;
}
if ( n = = 0 )
{
m_browsers - > closeCurrentBrowser ( ) ;
return true ;
}
else if ( n > 0 & & n < = m_browsers - > visibleCount ( ) )
{
m_browsers - > showHideVisibleBrowser ( n - 1 ) ;
return true ;
}
}
if ( TQT_BASE_OBJECT ( o ) = = TQT_BASE_OBJECT ( m_lineEdit ) ) //the search lineedit
{
TQListViewItem * item ;
switch ( e - > key ( ) )
{
case Key_Up :
case Key_Down :
case Key_PageDown :
case Key_PageUp :
pl - > setFocus ( ) ;
TQApplication : : sendEvent ( pl , e ) ;
return true ;
case Key_Return :
case Key_Enter :
item = * It ( pl , It : : Visible ) ;
m_lineEdit - > clear ( ) ;
pl - > m_filtertimer - > stop ( ) ; //HACK HACK HACK
if ( e - > state ( ) & ControlButton )
{
PLItemList in , out ;
if ( e - > state ( ) & ShiftButton )
for ( It it ( pl , It : : Visible ) ; PlaylistItem * x = static_cast < PlaylistItem * > ( * it ) ; + + it )
{
pl - > queue ( x , true ) ;
( pl - > m_nextTracks . contains ( x ) ? in : out ) . append ( x ) ;
}
else
{
It it ( pl , It : : Visible ) ;
pl - > activate ( * it ) ;
+ + it ;
for ( int i = 0 ; PlaylistItem * x = static_cast < PlaylistItem * > ( * it ) ; + + i , + + it )
{
in . append ( x ) ;
pl - > m_nextTracks . insert ( i , x ) ;
}
}
if ( ! in . isEmpty ( ) | | ! out . isEmpty ( ) )
emit pl - > queueChanged ( in , out ) ;
pl - > setFilter ( " " ) ;
pl - > ensureItemCentered ( ( e - > state ( ) & ShiftButton ) ? item : pl - > currentTrack ( ) ) ;
}
else
{
pl - > setFilter ( " " ) ;
if ( ( e - > state ( ) & ShiftButton ) & & item )
{
pl - > queue ( item ) ;
pl - > ensureItemCentered ( item ) ;
}
else
{
pl - > activate ( item ) ;
pl - > showCurrentTrack ( ) ;
}
}
return true ;
case Key_Escape :
m_lineEdit - > clear ( ) ;
return true ;
default :
return false ;
}
}
//following are for Playlist::instance() only
//we don't handle these in the playlist because often we manipulate the lineEdit too
if ( TQT_BASE_OBJECT ( o ) = = TQT_BASE_OBJECT ( pl ) )
{
if ( pl - > currentItem ( ) & & ( e - > key ( ) = = Key_Up & & pl - > currentItem ( ) - > itemAbove ( ) = = 0 & & ! ( e - > state ( ) & TQt : : ShiftButton ) ) )
{
TQListViewItem * lastitem = * It ( pl , It : : Visible ) ;
if ( ! lastitem )
return false ;
while ( lastitem - > itemBelow ( ) )
lastitem = lastitem - > itemBelow ( ) ;
pl - > currentItem ( ) - > setSelected ( false ) ;
pl - > setCurrentItem ( lastitem ) ;
lastitem - > setSelected ( true ) ;
pl - > ensureItemVisible ( lastitem ) ;
return true ;
}
if ( pl - > currentItem ( ) & & ( e - > key ( ) = = Key_Down & & pl - > currentItem ( ) - > itemBelow ( ) = = 0 & & ! ( e - > state ( ) & TQt : : ShiftButton ) ) )
{
pl - > currentItem ( ) - > setSelected ( false ) ;
pl - > setCurrentItem ( * It ( pl , It : : Visible ) ) ;
( * It ( pl , It : : Visible ) ) - > setSelected ( true ) ;
pl - > ensureItemVisible ( * It ( pl , It : : Visible ) ) ;
return true ;
}
if ( e - > key ( ) = = Key_Delete )
{
pl - > removeSelectedItems ( ) ;
return true ;
}
if ( ( ( e - > key ( ) > = Key_0 & & e - > key ( ) < = Key_Z ) | | e - > key ( ) = = Key_Backspace | | e - > key ( ) = = Key_Escape ) & & ( ! e - > state ( ) | | e - > state ( ) = = TQt : : ShiftButton ) ) //only if shift or no modifier key is pressed and 0-Z or backspace or escape
{
m_lineEdit - > setFocus ( ) ;
TQApplication : : sendEvent ( m_lineEdit , e ) ;
return true ;
}
}
# undef e
break ;
default :
break ;
}
return TQWidget : : eventFilter ( o , e ) ;
}
void PlaylistWindow : : closeEvent ( TQCloseEvent * e )
{
# ifdef TQ_WS_MAC
Q_UNUSED ( e ) ;
hide ( ) ;
# else
Amarok : : genericEventHandler ( TQT_TQWIDGET ( this ) , TQT_TQEVENT ( e ) ) ;
# endif
}
void PlaylistWindow : : showEvent ( TQShowEvent * )
{
static bool firstTime = true ;
if ( firstTime )
Playlist : : instance ( ) - > setFocus ( ) ;
firstTime = false ;
}
# include <tqdesktopwidget.h>
TQSize PlaylistWindow : : sizeHint ( ) const
{
return TQApplication : : desktop ( ) - > screenGeometry ( ( TQWidget * ) this ) . size ( ) / 1.5 ;
}
void PlaylistWindow : : savePlaylist ( ) const //SLOT
{
Playlist * pl = Playlist : : instance ( ) ;
PlaylistItem * item = pl - > firstChild ( ) ;
if ( item & & ! item - > isVisible ( ) )
item = static_cast < PlaylistItem * > ( item - > itemBelow ( ) ) ;
TQString title = pl - > playlistName ( ) ;
if ( item & & title = = i18n ( " Untitled " ) )
{
TQString artist = item - > artist ( ) ;
TQString album = item - > album ( ) ;
bool useArtist = true , useAlbum = true ;
item = static_cast < PlaylistItem * > ( item - > itemBelow ( ) ) ;
for ( ; item ; item = static_cast < PlaylistItem * > ( item - > itemBelow ( ) ) )
{
if ( artist ! = item - > artist ( ) )
useArtist = false ;
if ( album ! = item - > album ( ) )
useAlbum = false ;
if ( ! useArtist & & ! useAlbum )