Ejemplo n.º 1
0
int CrateDAO::addTracksToCrate(const int crateId, QList<int>* trackIdList) {
    ScopedTransaction transaction(m_database);
    QSqlQuery query(m_database);
    query.prepare("INSERT INTO " CRATE_TRACKS_TABLE " (crate_id, track_id) VALUES (:crate_id, :track_id)");

    for (int i = 0; i < trackIdList->size(); ++i) {
        query.bindValue(":crate_id", crateId);
        query.bindValue(":track_id", trackIdList->at(i));
        if (!query.exec()) {
            LOG_FAILED_QUERY(query);
            // We must emit only those trackID that were added so we need to
            // remove the failed ones.
            trackIdList->removeAt(i);
            --i; // account for reduced size of list
        }
    }
    transaction.commit();

    // Emitting the trackAdded signals for each trackID outside the transaction
    foreach(int trackId, *trackIdList) {
        emit(trackAdded(crateId, trackId));
    }

    emit(changed(crateId));

    // Return the number of tracks successfully added
    return trackIdList->size();
}
Ejemplo n.º 2
0
void TrackContainer::addTrack( track * _track )
{
	if( _track->type() != track::HiddenAutomationTrack )
	{
		_track->lock();
		m_tracksMutex.lockForWrite();
		m_tracks.push_back( _track );
		m_tracksMutex.unlock();
		_track->unlock();
		emit trackAdded( _track );
	}
}
Ejemplo n.º 3
0
bool CrateDAO::addTrackToCrate(int trackId, int crateId) {
    QSqlQuery query(m_database);
    query.prepare("INSERT INTO " CRATE_TRACKS_TABLE
                  " (crate_id, track_id) VALUES (:crate_id, :track_id)");
    query.bindValue(":crate_id", crateId);
    query.bindValue(":track_id", trackId);

    if (!query.exec()) {
        // It's normal for this query to fail with a constraint violation
        // (e.g. the track is already in the crate)
        LOG_FAILED_QUERY(query);
        return false;
    }
    updateCratesTitleNum();
    emit(trackAdded(crateId, trackId));
    emit(changed(crateId));
    return true;
}
Ejemplo n.º 4
0
void Playlist::addTrack(Track *track)
{
    track->setParent(this);
    connect(track, SIGNAL(playState()), SLOT(setLastTrack()));

    m_tList.insert(m_tList.end(), track);
    int trackIndex = m_tList.size()-1;
    track->setIndex(trackIndex);

    for(int i=0; i<5; i++) {
         m_Model->setItem(trackIndex, i, m_tList.at(trackIndex)->mitem().at(i));
    }

    connect(track, SIGNAL(playState()), SLOT(trackSelfActivate()));
    connect(track, SIGNAL(updated(bool)), SLOT(save()));
    connect(track, SIGNAL(updateMe()), m_Parser, SLOT(updateTrack()));

    Q_EMIT trackAdded();

    if(m_listType == PlaylistWidget::LocalList || m_listType == PlaylistWidget::DbSearch)
        if(!m_bLoadingState)
            save();
}
Ejemplo n.º 5
0
LibraryScanner::LibraryScanner(QWidget* pParentWidget, TrackCollection* collection)
              : m_pCollection(collection),
                m_libraryHashDao(m_database),
                m_cueDao(m_database),
                m_playlistDao(m_database),
                m_crateDao(m_database),
                m_directoryDao(m_database),
                m_analysisDao(m_database, collection->getConfig()),
                m_trackDao(m_database, m_cueDao, m_playlistDao,
                           m_crateDao, m_analysisDao, m_libraryHashDao,
                           collection->getConfig()) {
    // Don't initialize m_database here, we need to do it in run() so the DB
    // conn is in the right thread.
    qDebug() << "Starting LibraryScanner thread.";

    // Move LibraryScanner to its own thread so that our signals/slots will
    // queue to our event loop.
    moveToThread(this);
    m_pool.moveToThread(this);

    unsigned static id = 0; // the id of this LibraryScanner, for debugging purposes
    setObjectName(QString("LibraryScanner %1").arg(++id));

    m_pool.setMaxThreadCount(kScannerThreadPoolSize);

    // Listen to signals from our public methods (invoked by other threads) and
    // connect them to our slots to run the command on the scanner thread.
    connect(this, SIGNAL(startScan()),
            this, SLOT(slotStartScan()));

    // Force the GUI thread's TrackInfoObject cache to be cleared when a library
    // scan is finished, because we might have modified the database directly
    // when we detected moved files, and the TIOs corresponding to the moved
    // files would then have the wrong track location.
    connect(this, SIGNAL(scanFinished()),
            &(collection->getTrackDAO()), SLOT(clearCache()));
    connect(this, SIGNAL(trackAdded(TrackPointer)),
            &(collection->getTrackDAO()), SLOT(databaseTrackAdded(TrackPointer)));
    connect(this, SIGNAL(tracksMoved(QSet<int>, QSet<int>)),
            &(collection->getTrackDAO()), SLOT(databaseTracksMoved(QSet<int>, QSet<int>)));
    connect(this, SIGNAL(tracksChanged(QSet<int>)),
            &(collection->getTrackDAO()), SLOT(databaseTracksChanged(QSet<int>)));

    // Parented to pParentWidget so we don't need to delete it.
    LibraryScannerDlg* pProgress = new LibraryScannerDlg(pParentWidget);
    connect(this, SIGNAL(progressLoading(QString)),
            pProgress, SLOT(slotUpdate(QString)));
    connect(this, SIGNAL(progressHashing(QString)),
            pProgress, SLOT(slotUpdate(QString)));
    connect(this, SIGNAL(scanStarted()),
            pProgress, SLOT(slotScanStarted()));
    connect(this, SIGNAL(scanFinished()),
            pProgress, SLOT(slotScanFinished()));
    connect(pProgress, SIGNAL(scanCancelled()),
            this, SLOT(cancel()));
    connect(&m_trackDao, SIGNAL(progressVerifyTracksOutside(QString)),
            pProgress, SLOT(slotUpdate(QString)));
    connect(&m_trackDao, SIGNAL(progressCoverArt(QString)),
            pProgress, SLOT(slotUpdateCover(QString)));

    start();
}
Ejemplo n.º 6
0
 foreach (int trackId, trackIds) {
     // TODO(XXX) don't emit if the track didn't add successfully.
     emit(trackAdded(playlistId, trackId, insertPosition++));
 }
Ejemplo n.º 7
0
void
ITunesImporterWorker::readTrackElement()
{
    QString title, artist, album, url;
    int year = -1, bpm = -1, playcount = -1, rating = -1;
    QDateTime lastplayed;
    
    while( !( isEndElement() && name() == "dict" ) )
    {
        readNext();
        QString text = readElementText();
        if( name() == "key" && text == "Name" )
        {
            readNext(); // skip past the </key> and to the data tag
            QString text = readElementText();
            title = text;
        } else if( name() == "key" && text == "Artist" )
        {
            readNext(); // skip past the </key> and to the data tag
            artist = readElementText();
        } else if( isStartElement() && name() == "key" && text == "Album" )
        {
            readNext(); // skip past the </key> and to the data tag
            album = readElementText();
        } else if( name() == "key" && text == "Year" )
        {
            readNext(); // skip past the </key> and to the data tag
            year = readElementText().toInt();
        } else if( name() == "key" && text == "BPM" )
        {
            readNext(); // skip past the </key> and to the data tag
            bpm = readElementText().toInt();
        } else if( name() == "key" && text == "Play Count" )
        { 
            readNext(); // skip past the </key> and to the data tag
            playcount = readElementText().toInt();
        } else if( name() == "key" && text == "Rating" )
          { 
            readNext(); // skip past the </key> and to the data tag
            rating = readElementText().toInt() / 10; // itunes rates 0-100
        } else if( name() == "key" && text == "Play Date" )
        { 
            readNext(); // skip past the </key> and to the data tag
            lastplayed = QDateTime::fromTime_t(readElementText().toInt());
        } else if( name() == "key" && text == "Location" )
        {
            readNext(); // skip past the </key> and to the data tag
            url = readElementText();
        }
    }
    
    //split the file://localhost/path/to/track   to just file:///path/to/track
    if( url.indexOf( "file://localhost" ) == 0 )
        url = url.remove( 7, 9 );
    
    debug() << "got track info:" << title << artist << album << year << bpm << url;
    
    Meta::TrackPtr track = CollectionManager::instance()->trackForUrl( KUrl( url ) );
    if( track )
    {
        QScopedPointer<Capabilities::StatisticsCapability> ec( track->create<Capabilities::StatisticsCapability>() );
        if( ec )
        {   
            ec->beginStatisticsUpdate();
            if( rating != -1 ) 
                ec->setRating( rating );
            if( lastplayed.isValid() )
                ec->setLastPlayed( lastplayed );
            if( playcount != -1 ) 
                ec->setPlayCount( playcount );
            ec->endStatisticsUpdate();
        
            if( !track->inCollection() )
            {
                m_tracksForInsert.insert( track, track->playableUrl().url() );
                debug() << " inserting track:" << track->playableUrl();
            }
            else {
                Collections::Collection* collection = track->collection();
                if (collection)
                    debug() << "track in collection (" << collection->location()->prettyLocation() << "):" << track->playableUrl();
            }

            emit trackAdded( track );
        }
    }
    
}
Ejemplo n.º 8
0
Playlist::Playlist(PlaylistWidget::ListTypes listType, QString title, quint64 hash, QObject *parent) :
    QObject(parent)
{
    m_listType = listType;
    m_sTitle = title;
    m_bCustomTitle = false;

    m_Settings = Settings::instance();
    connect(m_Settings, SIGNAL(changed()), SLOT(onSettingsChanged()));

    m_bLoadingState = false;
    m_bShuffleList = m_Settings->getValue("player/shuffle").toInt() > 1 ? true : false;

    m_LastTrack = 0;

    m_bLoadMeta = false;
    m_bUseMeta = false;

    m_bTitleByContent = m_Settings->getValue("playlist/tabs_by_content").toBool();

    m_Auth = Auth::instance();
    connect(m_Auth, SIGNAL(authComplete()), SLOT(update()));


    // Set hash
    if(hash == 0) {
        QDateTime *time = new QDateTime(QDateTime::currentDateTime());
        m_Hash = time->toMSecsSinceEpoch();
        m_bNewly = true;
    } else {
        m_Hash = hash;
        m_bNewly = false;
    }

    // Create playlist widget
    m_listWidget = new PlaylistWidget(m_listType);
    connect(this, SIGNAL(trackAdded()), m_listWidget, SLOT(trackAdded()));
    connect(m_listWidget, SIGNAL(trackActivate(Track*)), SLOT(trackActivate(Track*)));

    // Connect key events
    connect(m_listWidget, SIGNAL(skQueue()), SLOT(addToQueue()));
    connect(m_listWidget, SIGNAL(skRemove()), SLOT(removeTrack()));
    connect(m_listWidget, SIGNAL(skDownload()), SLOT(downloadTrack()));

    // Create object of parser
    m_Parser = new Parser(this);
    connect(m_Parser, SIGNAL(newTrack(Track*)), SLOT(addTrack(Track*)));
    connect(m_Parser, SIGNAL(busy()), SLOT(parserBusy()));
    connect(m_Parser, SIGNAL(free()), SLOT(parserFree()));
    connect(m_Parser, SIGNAL(savePlaylist()), SLOT(save()));
    connect(m_Parser, SIGNAL(busy()), m_listWidget, SLOT(showLoading()));
    connect(m_Parser, SIGNAL(free()), m_listWidget, SLOT(hideLoading()));

    // Create actions parser
    m_vkActions = VkActions::instance();
    connect(m_vkActions, SIGNAL(message(QString,QString)), SIGNAL(message(QString,QString)));

    switch(m_listType) {
        case PlaylistWidget::Search:
            connect(m_listWidget, SIGNAL(searchChanged(QString)), SLOT(searchChanged(QString)));
            connect(m_listWidget, SIGNAL(loadMore()), m_Parser, SLOT(loadMoreResults()));
        break;
        case PlaylistWidget::AudioLib:
            connect(m_listWidget->friendsList(), SIGNAL(friendSelected(QString,QString,QString)), SLOT(librarySelected(QString,QString,QString)));
            connect(m_listWidget, SIGNAL(refresh()), SLOT(refresh()));
        break;
        case PlaylistWidget::Suggestions:
            connect(m_listWidget, SIGNAL(loadMore()), m_Parser, SLOT(loadMoreResults()));
            connect(m_listWidget, SIGNAL(refresh()), SLOT(refresh()));
        break;
        case PlaylistWidget::DbSearch:
            connect(m_listWidget, SIGNAL(searchChanged(QString)), SLOT(searchChanged(QString)));
            connect(m_listWidget, SIGNAL(newTrack(Track*)), SLOT(addTrack(Track*)));
            connect(m_listWidget, SIGNAL(clearList()), SLOT(clearList()));
        break;
    }

    m_Model = new QStandardItemModel(this);

    m_ProxyModel = new QSortFilterProxyModel(this);
    m_ProxyModel->setSourceModel(m_Model);
    m_ProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
    m_ProxyModel->setFilterKeyColumn(2);

    m_listWidget->setModel(m_ProxyModel);

    connect(m_listWidget, SIGNAL(listSearchChanged(QString)), SLOT(setListSearch(QString)));

    createMenus();

    load();

    if(type() == PlaylistWidget::AudioLib &&
       m_bNewly &&
       m_Settings->getValue("playlist/autoload_library").toBool()
       )
        librarySelected(m_Auth->vkId(), "0", tr("My Library"));

    // Actions on newly created plalylists
    if(m_bNewly) {
        switch(m_listType) {
            case PlaylistWidget::Search:
                m_listWidget->focusOnSearch();
            break;
            case PlaylistWidget::AudioLib:
            if(m_Settings->getValue("playlist/autoload_library").toBool())
                librarySelected(m_Auth->vkId(), "0", tr("My Library"));
            break;
            case PlaylistWidget::Suggestions:
                refresh();
            break;
            case PlaylistWidget::DbSearch:
                // Unused
            break;
        }
    }
}