diff --git a/src/magnatunebrowser/magnatunebrowser.cpp b/src/magnatunebrowser/magnatunebrowser.cpp index 0e9d725202..3a8ff599b2 100644 --- a/src/magnatunebrowser/magnatunebrowser.cpp +++ b/src/magnatunebrowser/magnatunebrowser.cpp @@ -1,520 +1,523 @@ /* Copyright (c) 2006 Nikolaj Hald Nielsen This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "amarok.h" #include "magnatunebrowser.h" #include "playlist.h" #include "magnatunedatabasehandler.h" #include "debug.h" #include //locate() #include #include //multiTabBar icons +#include #include #include #include MagnatuneBrowser *MagnatuneBrowser::s_instance = 0; MagnatuneBrowser::MagnatuneBrowser( const char *name ) : QVBox( 0, name ) { DEBUG_BLOCK initTopPanel( ); QSplitter *spliter = new QSplitter( Qt::Vertical, this ); debug() << "Magnatune browser starting..." << endl; m_listView = new MagnatuneListView( spliter ); m_popupMenu = new QPopupMenu( spliter, "MagnatuneMenu" ); m_artistInfobox = new MagnatuneArtistInfoBox( spliter, "ArtistInfoBox" ); initBottomPanel(); //connect (m_listView, SIGNAL(executed(KListViewItem *)), this, SLOT(itemExecuted(KListViewItem *))); connect( m_listView, SIGNAL( doubleClicked( QListViewItem * ) ), this, SLOT( itemExecuted( QListViewItem * ) ) ); connect( m_listView, SIGNAL( selectionChanged( QListViewItem * ) ), this, SLOT( selectionChanged( QListViewItem * ) ) ); connect( m_listView, SIGNAL( rightButtonClicked ( QListViewItem *, const QPoint &, int ) ), this, SLOT( showPopupMenu( QListViewItem *, const QPoint &, int ) ) ); connect( m_popupMenu, SIGNAL( aboutToShow() ), this, SLOT( menuAboutToShow() ) ); m_currentInfoUrl = ""; m_purchaseHandler = 0; m_redownloadHandler = 0; m_purchaseInProgress = false; m_polished = false; } void MagnatuneBrowser::itemExecuted( QListViewItem * item ) { DEBUG_BLOCK; switch ( item->depth() ) { case 2: addTrackToPlaylist( dynamic_cast( item ) ); break; case 1: addAlbumToPlaylist( dynamic_cast( item ) ); break; case 0: addArtistToPlaylist( dynamic_cast( item ) ); break; default: break; } } void MagnatuneBrowser::addTrackToPlaylist( MagnatuneTrack *item ) { if ( !item ) return ; // sanity check debug() << "Magnatune browser: adding single track" << endl; QString url = item->getHifiURL(); Playlist * playlist = Playlist::instance(); playlist->insertMedia( KURL( url ) ); } void MagnatuneBrowser::addAlbumToPlaylist( MagnatuneAlbum * item ) { if ( !item ) return ; // sanity check debug() << "Magnatune browser: adding album" << endl; MagnatuneTrackList tracks = MagnatuneDatabaseHandler::instance() ->getTracksByAlbumId( item->getId() ); MagnatuneTrackList::iterator it; for ( it = tracks.begin(); it != tracks.end(); ++it ) addTrackToPlaylist( &( *it ) ); } void MagnatuneBrowser::addArtistToPlaylist( MagnatuneArtist *item ) { if ( !item ) return ; // sanity check debug() << "Magnatune browser: adding artist" << endl; MagnatuneAlbumList albums = MagnatuneDatabaseHandler::instance() ->getAlbumsByArtistId( item->getId(), "" ); MagnatuneAlbumList::iterator it; for ( it = albums.begin(); it != albums.end(); ++it ) addAlbumToPlaylist( &( *it ) ); } void MagnatuneBrowser::selectionChanged( QListViewItem *item ) { if ( !item ) return ; // sanity check debug() << "Selection changed..." << endl; if ( item->depth() == 0 ) m_purchaseAlbumButton->setEnabled( false ); else if ( ! m_purchaseInProgress ) m_purchaseAlbumButton->setEnabled( true ); if ( !m_isInfoShown ) return ; switch ( item->depth() ) { case 0: { MagnatuneListViewArtistItem * artistItem = dynamic_cast( item ); if ( artistItem && m_currentInfoUrl != artistItem->getHomeURL() ) { m_currentInfoUrl = artistItem->getHomeURL(); m_artistInfobox->displayArtistInfo( KURL( m_currentInfoUrl ) ); } } break; case 1: { MagnatuneListViewAlbumItem *albumItem = dynamic_cast( item ); if ( albumItem && m_currentInfoUrl != albumItem->getCoverURL() ) { m_currentInfoUrl = albumItem->getCoverURL(); m_artistInfobox->displayAlbumInfo( albumItem ); } } break; case 2: { // a track is selected, show the corrosponding album info! MagnatuneListViewTrackItem *trackItem = dynamic_cast( item ); if (!trackItem) { debug() << "dynamic_cast to trackItem failed!" << endl; return; } int albumId = trackItem->getAlbumId(); MagnatuneAlbum album = MagnatuneDatabaseHandler::instance() ->getAlbumById( albumId ); m_artistInfobox->displayAlbumInfo( &album ); } break; default: break; } } void MagnatuneBrowser::showPopupMenu( QListViewItem * item, const QPoint & pos, int /*column*/ ) { if ( !item ) return ; m_popupMenu->exec( pos ); } void MagnatuneBrowser::addSelectionToPlaylist( ) { QListViewItem * selectedItem = m_listView->selectedItem(); switch ( selectedItem->depth() ) { case 0: addArtistToPlaylist( dynamic_cast( selectedItem ) ); break; case 1: addAlbumToPlaylist( dynamic_cast( selectedItem ) ); break; case 2: addTrackToPlaylist( dynamic_cast( selectedItem ) ); } } void MagnatuneBrowser::menuAboutToShow( ) { m_popupMenu->clear(); QListViewItem *selectedItem = m_listView->selectedItem(); if ( !selectedItem ) return ; switch ( selectedItem->depth() ) { case 0: m_popupMenu->insertItem( i18n( "Add artist to playlist" ), this, SLOT( addSelectionToPlaylist() ) ); break; case 1: m_popupMenu->insertItem( i18n( "Add album to playlist" ), this, SLOT( addSelectionToPlaylist() ) ); m_popupMenu->insertItem( i18n( "Purchase album" ), this, SLOT( purchaseSelectedAlbum() ) ); break; case 2: m_popupMenu->insertItem( i18n( "Add track to playlist" ), this, SLOT( addSelectionToPlaylist() ) ); m_popupMenu->insertItem( i18n( "Purchase album" ), this, SLOT( purchaseAlbumContainingSelectedTrack() ) ); } } void MagnatuneBrowser::purchaseButtonClicked( ) { if ( !m_purchaseInProgress ) { m_purchaseInProgress = true; m_purchaseAlbumButton->setEnabled( false ); if ( m_listView->selectedItem() ->depth() == 1 ) purchaseSelectedAlbum( ); else if ( m_listView->selectedItem() ->depth() == 2 ) purchaseAlbumContainingSelectedTrack( ); } } void MagnatuneBrowser::purchaseSelectedAlbum( ) { if ( !m_purchaseHandler ) { m_purchaseHandler = new MagnatunePurchaseHandler(); m_purchaseHandler->setParent( this ); connect( m_purchaseHandler, SIGNAL( purchaseCompleted( bool ) ), this, SLOT( purchaseCompleted( bool ) ) ); } MagnatuneListViewAlbumItem *selectedAlbum = dynamic_cast( m_listView->selectedItem() ); if (selectedAlbum) m_purchaseHandler->purchaseAlbum( *selectedAlbum ); } void MagnatuneBrowser::purchaseAlbumContainingSelectedTrack( ) { if ( !m_purchaseHandler ) { m_purchaseHandler = new MagnatunePurchaseHandler(); m_purchaseHandler->setParent( this ); connect( m_purchaseHandler, SIGNAL( purchaseCompleted( bool ) ), this, SLOT( purchaseCompleted( bool ) ) ); } MagnatuneListViewTrackItem *selectedTrack = dynamic_cast( m_listView->selectedItem() ); if (!selectedTrack) { debug() << "dynamic_cast to selected track failed!" << endl; return; } MagnatuneAlbum album( MagnatuneDatabaseHandler::instance() ->getAlbumById( selectedTrack->getAlbumId() ) ); m_purchaseHandler->purchaseAlbum( album ); } void MagnatuneBrowser::initTopPanel( ) { m_topPanel = new QHBox( this, "topPanel", 0 ); m_topPanel->setMaximumHeight( 24 ); m_topPanel->setSpacing( 2 ); m_topPanel->setMargin( 2 ); new QLabel ( i18n( "Genre: " ), m_topPanel, "genreLabel", 0 ); m_genreComboBox = new QComboBox( false, m_topPanel, "genreComboBox" ); updateGenreBox(); m_advancedFeaturesButton = new QPushButton( i18n( "Redownload" ), m_topPanel, "advancedButton" ); connect( m_advancedFeaturesButton, SIGNAL( clicked() ), this, SLOT( processRedownload() ) ); connect( m_genreComboBox, SIGNAL( activated ( int ) ), this, SLOT( genreChanged() ) ); } void MagnatuneBrowser::initBottomPanel() { m_bottomPanel = new QVBox( this, "bottomPanel", 0 ); m_bottomPanel->setMaximumHeight( 54 ); m_bottomPanel->setSpacing( 2 ); m_bottomPanel->setMargin( 2 ); QHBox *hBox = new QHBox( m_bottomPanel, "bottomHBox", 0 ); hBox->setMaximumHeight( 24 ); hBox->setSpacing( 2 ); //hBox->setMargin( 2 ); m_purchaseAlbumButton = new QPushButton( i18n( "Purchase Album" ), m_bottomPanel, "purchaseButton" ); m_purchaseAlbumButton->setIconSet( SmallIconSet( Amarok::icon( "download" ) ) ); m_purchaseAlbumButton->setEnabled( false ); m_purchaseAlbumButton->setMaximumHeight( 24 ); m_updateListButton = new QPushButton( i18n( "Update" ), hBox, "updateButton" ); m_updateListButton->setIconSet( SmallIconSet( Amarok::icon( "rescan" ) ) ); m_showInfoToggleButton = new QPushButton( i18n( "Show Info" ) , hBox, "showInfoCheckbox" ); m_showInfoToggleButton->setToggleButton( true ); m_showInfoToggleButton->setIconSet( SmallIconSet( Amarok::icon( "info" ) ) ); m_showInfoToggleButton->setOn( true ); m_isInfoShown = true; connect( m_showInfoToggleButton, SIGNAL( toggled( bool ) ), this, SLOT( showInfo( bool ) ) ); connect( m_updateListButton, SIGNAL( clicked() ), this, SLOT( updateButtonClicked() ) ); connect( m_purchaseAlbumButton, SIGNAL( clicked() ) , this, SLOT( purchaseButtonClicked() ) ); } void MagnatuneBrowser::updateButtonClicked() { m_updateListButton->setEnabled( false ); updateMagnatuneList(); } bool MagnatuneBrowser::updateMagnatuneList() { //download new list from magnatune m_listDownloadJob = KIO::storedGet( KURL( "http://magnatune.com/info/album_info.xml" ), false, false ); Amarok::StatusBar::instance() ->newProgressOperation( m_listDownloadJob ) .setDescription( i18n( "Downloading Magnatune.com Database" ) ) .setAbortSlot( this, SLOT( listDownloadCancelled() ) ); connect( m_listDownloadJob, SIGNAL( result( KIO::Job* ) ), SLOT( listDownloadComplete( KIO::Job* ) ) ); return true; } void MagnatuneBrowser::listDownloadComplete( KIO::Job * downLoadJob ) { if ( downLoadJob != m_listDownloadJob ) return ; //not the right job, so let's ignore it m_updateListButton->setEnabled( true ); if ( !downLoadJob->error() == 0 ) { //TODO: error handling here return ; } KIO::StoredTransferJob* const storedJob = static_cast( downLoadJob ); QString list = QString( storedJob->data() ); - - QFile file( "/tmp/album_info.xml" ); - - if ( file.exists() ) - file.remove(); + KTempFile tfile; + m_tempFileName = tfile.name(); + QFile file( m_tempFileName ); if ( file.open( IO_WriteOnly ) ) { QTextStream stream( &file ); stream << list; file.close(); } - MagnatuneXmlParser * parser = new MagnatuneXmlParser( "/tmp/album_info.xml" ); + MagnatuneXmlParser * parser = new MagnatuneXmlParser( m_tempFileName ); connect( parser, SIGNAL( doneParsing() ), SLOT( doneParsing() ) ); ThreadManager::instance() ->queueJob( parser ); } void MagnatuneBrowser::listDownloadCancelled( ) { Amarok::StatusBar::instance() ->endProgressOperation( m_listDownloadJob ); m_listDownloadJob->kill( true ); delete m_listDownloadJob; m_listDownloadJob = 0; debug() << "Aborted xml download" << endl; m_updateListButton->setEnabled( true ); } void MagnatuneBrowser::showInfo( bool show ) { if ( show ) { m_isInfoShown = true; m_artistInfobox->widget() ->setMaximumHeight( 2000 ); } else { m_artistInfobox->widget() ->setMaximumHeight( 0 ); m_isInfoShown = false; } } void MagnatuneBrowser::updateList() { DEBUG_BLOCK const QString genre = m_genreComboBox->currentText(); MagnatuneArtistList artists; artists = MagnatuneDatabaseHandler::instance() ->getArtistsByGenre( genre ); m_listView->clear(); MagnatuneArtistList::iterator it; for ( it = artists.begin(); it != artists.end(); ++it ) new MagnatuneListViewArtistItem( ( *it ), m_listView ); m_listView->repaintContents(); } void MagnatuneBrowser::genreChanged() { debug() << "Genre changed..." << endl; updateList( ); } void MagnatuneBrowser::doneParsing() { + DEBUG_BLOCK updateList(); updateGenreBox( ); updateList(); // stupid stupid hack.... + if( !QFile::remove( m_tempFileName ) ) + debug() << "Couldn't remove temp file at " << m_tempFileName << endl; + m_tempFileName = QString(); } void MagnatuneBrowser::updateGenreBox() { const QStringList genres = MagnatuneDatabaseHandler::instance() ->getAlbumGenres(); m_genreComboBox->clear(); m_genreComboBox->insertItem ( "All" , 0 ); // should not be i18n'ed as it is //used as a trigger in the code in the database handler. foreach( genres ) m_genreComboBox->insertItem( ( *it ), -1 ); } void MagnatuneBrowser::processRedownload( ) { if ( m_redownloadHandler == 0 ) { m_redownloadHandler = new MagnatuneRedownloadHandler( this ); } m_redownloadHandler->showRedownloadDialog(); } void MagnatuneBrowser::purchaseCompleted( bool /*success*/ ) { if ( m_purchaseHandler != 0 ) { delete m_purchaseHandler; m_purchaseHandler = 0; } m_purchaseAlbumButton->setEnabled( true ); m_purchaseInProgress = false; debug() << "Purchase operation complete" << endl; //TODO: display some kind of success dialog here? } void MagnatuneBrowser::polish( ) { DEBUG_BLOCK; if (!m_polished) { m_polished = true; updateList( ); m_artistInfobox->begin( KURL( locate( "data", "amarok/data/" ) ) ); m_artistInfobox->write( "" "
" "" "

" + i18n( "Welcome to Amarok's integrated Magnatune.com store. If this is the " "first time you run it, you must update the database by pressing the " "'Update' button below." ) + "
" ); m_artistInfobox->end(); } } #include "magnatunebrowser.moc" diff --git a/src/magnatunebrowser/magnatunebrowser.h b/src/magnatunebrowser/magnatunebrowser.h index 1c145ffea7..1a37430854 100644 --- a/src/magnatunebrowser/magnatunebrowser.h +++ b/src/magnatunebrowser/magnatunebrowser.h @@ -1,251 +1,253 @@ /* Copyright (c) 2006 Nikolaj Hald Nielsen This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef AMAROKMAGNATUNEBROWSER_H #define AMAROKMAGNATUNEBROWSER_H #include "amarok.h" #include "magnatuneartistinfobox.h" #include "magnatunelistview.h" #include "magnatunelistviewitems.h" #include "magnatunepurchasedialog.h" #include "magnatunepurchasehandler.h" #include "magnatuneredownloadhandler.h" #include "magnatunexmlparser.h" #include #include #include #include #include #include #include #include /** Amarok browser that displays all the music available at magnatune.com and makes it available for previewing and purchasing. Implemented as a singleton @author Nikolaj Hald Nielsen */ class MagnatuneBrowser : public QVBox { Q_OBJECT public: /** * Destructor */ ~MagnatuneBrowser() { } /** * Retrieves the class instance (Singleton pattern) * @return pointer to the class instance */ static MagnatuneBrowser *instance() { if(!s_instance) s_instance = new MagnatuneBrowser("MagnatuneBrowser"); return s_instance; } private slots: /** * Slot for recieving aboutToShow signals from the right click menu. * Inserts items in the menu based on the type of the current selection */ void menuAboutToShow(); /** * Slot called when the purchase album button is clicked. Starts a purchase */ void purchaseButtonClicked(); /** * Slot for recieving notification from the right click menu that the user * has chosen to purchase an album. Starts a purchase */ void purchaseSelectedAlbum(); /** * Slot for recieving notification from the right click menu that the user * has chosen to purchase the album contining the selected track. * Starts a purchase */ void purchaseAlbumContainingSelectedTrack(); /** * Slot for recieving notification from the right click menu that the user * has selected "add to playlist" for the currently selected item, */ void addSelectionToPlaylist(); /** * Slot for recieving notification that the user has double clicked an * item in the list view. Ads item to playlist. * @param item The item that was double clicked */ void itemExecuted( QListViewItem * item); /** * Slot for recieving notification when a new item in the list is selected. * Adds the corrosponding artist or album info to the info view (if visible) * @param item The selected item */ void selectionChanged( QListViewItem * item); /** * Slot for recieving notifications about right clicks in the list view. * if selection is valid the popup menu is shown * @param item The item that was right clicked * @param pos The position of the cursor at the time of thre right click * @param column The column of the item that was right clicked (unused) */ void showPopupMenu( QListViewItem * item, const QPoint & pos, int column ); /** * Slot for recieving notification that the update button has been clicked. */ void updateButtonClicked(); /** * Toggles the info area on and off * @param show If true the info box is shown, if false it is hidden */ void showInfo(bool show); /** * Slot for recieving notification when the Magnatune xml file has been downloaded. * Triggers a parse of the file to get the info added to the databse * @param downLoadJob The calling download Job */ void listDownloadComplete( KIO::Job* downLoadJob); /** * Slot for catching cancelled list downloads */ void listDownloadCancelled(); /** * Slot called when the genre combo box selection changes. Triggers an update of the list view. */ void genreChanged(); /** * Slot called when the parsing of the Magnatuin xml file is completed. * Triggers an update of the list view and the genre combo box */ void doneParsing(); /** * Starts the process of redownloading a previously bought album */ void processRedownload(); /** * Slot for recieving notifications of completed purchase operations * @param success Was the operation a success? */ void purchaseCompleted( bool success ); /** * Don not do expensive initializations before we are actually shown */ void polish(); private: MagnatuneBrowser( const char *name ); /** * Helper function that initializes the button panel below the list view */ void initBottomPanel(); /** * Helper function that initializes the genre selection panel above the list view */ void initTopPanel(); /** * Starts downloading an updated track list xml file from * http://magnatune.com/info/album_info.xml * @return Currently always returns true */ bool updateMagnatuneList(); /** * Adds a magnatune preview track to the playlist. * @param item The track to add */ void addTrackToPlaylist ( MagnatuneTrack *item ); /** * Adds all preview tracks on a magnatune album to the playlist * @param item The album to add */ void addAlbumToPlaylist ( MagnatuneAlbum *item ); /** * Adds all preview tracks on all albums by a given artist to the playlist * @param item the artist to add */ void addArtistToPlaylist( MagnatuneArtist *item ); /** * Clears the list view and inserts artists based on the currently selected genre */ void updateList(); /** * Clears the genre combo box and inserts all genres from the database */ void updateGenreBox(); static MagnatuneBrowser *s_instance; MagnatuneListView *m_listView; MagnatuneArtistInfoBox *m_artistInfobox; QString m_currentInfoUrl; QPopupMenu *m_popupMenu; MagnatunePurchaseHandler *m_purchaseHandler; MagnatuneRedownloadHandler *m_redownloadHandler; QHBox *m_topPanel; QVBox *m_bottomPanel; QPushButton *m_advancedFeaturesButton; QPushButton *m_updateListButton; QPushButton *m_purchaseAlbumButton; QPushButton *m_showInfoToggleButton; QComboBox *m_genreComboBox; bool m_isInfoShown; bool m_purchaseInProgress; bool m_polished; + QString m_tempFileName; + KIO::TransferJob * m_listDownloadJob; }; #endif