Merge doep branch to trunk.

This commit is contained in:
Daniel Önnerby 2008-04-18 07:45:02 +00:00
parent c547063578
commit 6d479c3d13
22 changed files with 7211 additions and 2695 deletions

File diff suppressed because it is too large Load Diff

View File

@ -15,7 +15,7 @@
** as extensions by SQLite should #include this file instead of
** sqlite3.h.
**
** @(#) $Id: sqlite3ext.h,v 1.17 2007/08/31 16:11:36 drh Exp $
** @(#) $Id: sqlite3ext.h,v 1.21 2008/03/19 21:45:51 drh Exp $
*/
#ifndef _SQLITE3EXT_H_
#define _SQLITE3EXT_H_
@ -24,13 +24,13 @@
typedef struct sqlite3_api_routines sqlite3_api_routines;
/*
** The following structure hold pointers to all of the SQLite API
** The following structure holds pointers to all of the SQLite API
** routines.
**
** WARNING: In order to maintain backwards compatibility, add new
** interfaces to the end of this structure only. If you insert new
** interfaces in the middle of this structure, then older different
** versions of SQLite will not be able to load each others shared
** versions of SQLite will not be able to load each others' shared
** libraries!
*/
struct sqlite3_api_routines {
@ -182,6 +182,12 @@ struct sqlite3_api_routines {
sqlite3_vfs *(*vfs_find)(const char*);
int (*vfs_register)(sqlite3_vfs*,int);
int (*vfs_unregister)(sqlite3_vfs*);
int (*xthreadsafe)(void);
void (*result_zeroblob)(sqlite3_context*,int);
void (*result_error_code)(sqlite3_context*,int);
int (*test_control)(int, ...);
void (*randomness)(int,void*);
sqlite3 *(*context_db_handle)(sqlite3_context*);
};
/*
@ -342,6 +348,12 @@ struct sqlite3_api_routines {
#define sqlite3_vfs_find sqlite3_api->vfs_find
#define sqlite3_vfs_register sqlite3_api->vfs_register
#define sqlite3_vfs_unregister sqlite3_api->vfs_unregister
#define sqlite3_threadsafe sqlite3_api->xthreadsafe
#define sqlite3_result_zeroblob sqlite3_api->result_zeroblob
#define sqlite3_result_error_code sqlite3_api->result_error_code
#define sqlite3_test_control sqlite3_api->test_control
#define sqlite3_randomness sqlite3_api->randomness
#define sqlite3_context_db_handle sqlite3_api->context_db_handle
#endif /* SQLITE_CORE */
#define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api;

File diff suppressed because it is too large Load Diff

View File

@ -143,7 +143,7 @@ bool TagReaderTaglib::GetGenericTag(musik::core::Track *track){
// ALBUM
this->SetTagValue("album",tag->album(),track);
// ARTISTS
this->SetSlashSeparatedValues("artist",tag->album(),track);
this->SetSlashSeparatedValues("artist",tag->artist(),track);
// GENRES
this->SetTagValue("genre",tag->genre(),track);
// COMMENT
@ -422,3 +422,4 @@ void TagReaderTaglib::SetAudioProperties(TagLib::AudioProperties *audioPropertie
}
}

View File

@ -245,15 +245,12 @@ bool Library::Base::AddQuery( const Query::Base &query,unsigned int options ){
boost::mutex::scoped_lock lock(this->libraryMutex);
// wait for the query to be finished or canceled
while( !(queryCopy->status&Query::Base::Status::Ended) ){
while( !(queryCopy->status&Query::Base::Status::Ended) && !(queryCopy->status&Query::Base::Status::Canceled) ){
this->waitCondition.wait(lock);
}
if( options & Query::Options::AutoCallback ){ // Should the callbacks be involved?
if( !(queryCopy->status&Query::Base::Status::Canceled) ){ // If not canceled
queryCopy->RunCallbacks(this); // Run the callbacks.
queryCopy->status |= Query::Base::Status::Finished; // Set to finished for removal.
}
queryCopy->status |= Query::Base::Status::Finished; // Set to finished for removal.
}
}
@ -261,6 +258,13 @@ bool Library::Base::AddQuery( const Query::Base &query,unsigned int options ){
// Finaly, remove old, finished queries
this->ClearFinishedQueries();
if( options & Query::Options::AutoCallback ){ // Should the callbacks be involved?
if( !(queryCopy->status&Query::Base::Status::Canceled) ){ // If not canceled
queryCopy->RunCallbacks(this); // Run the callbacks.
}
}
}
return true;

View File

@ -31,7 +31,11 @@
//
//////////////////////////////////////////////////////////////////////////////
#include "pch.hpp"
#include "PlaybackQueue.h"
#include "core/PlaybackQueue.h"
#include "core/LibraryFactory.h"
#include <boost/algorithm/string.hpp>
using namespace musik::core;
@ -41,12 +45,24 @@ PlaybackQueue PlaybackQueue::sInstance;
PlaybackQueue::PlaybackQueue(void) :
nowPlaying( new musik::core::tracklist::Standard() )
nowPlaying( new musik::core::tracklist::Standard() ),
signalDisabled(false),
playing(false)
{
this->transport.MixpointReached.connect(this,&PlaybackQueue::OnPlaybackEndOrFail);
// this->transport.PlaybackStoppedFail.connect(this,&PlaybackQueue::OnPlaybackEndOrFail);
}
PlaybackQueue::~PlaybackQueue(void)
{
this->transport.Stop(0);
}
void PlaybackQueue::OnPlaybackEndOrFail(){
this->playing = false;
if(!this->signalDisabled){
this->Next();
}
}
tracklist::IRandomAccessPtr PlaybackQueue::NowPlayingTracklist(){
@ -59,15 +75,46 @@ void PlaybackQueue::Play(){
if(track){
// If current track exists
this->transport.Start(track->GetValue("path"));
utfstring path(track->GetValue("path"));
this->Stop();
this->playing = true;
this->transport.Start(path);
}
}
void PlaybackQueue::Next(){
musik::core::TrackPtr track( this->nowPlaying->NextTrack() );
if(track){
this->SetCurrentTrack(track->Copy());
this->Play();
}
}
void PlaybackQueue::Previous(){
musik::core::TrackPtr track( this->nowPlaying->PreviousTrack() );
if(track){
this->SetCurrentTrack(track->Copy());
this->Play();
}
}
void PlaybackQueue::Stop(){
this->signalDisabled = true;
if( this->playing ){
this->transport.Stop(0);
}
this->signalDisabled = false;
}
TrackPtr PlaybackQueue::CurrentTrack(){
if(!this->currentTrack){
// If the current track is empty, get a track from the nowPlaying tracklist
this->SetCurrentTrack( this->nowPlaying->CurrentTrack() );
this->SetCurrentTrack( this->nowPlaying->CurrentTrack()->Copy() );
}
return this->currentTrack;
}
@ -76,8 +123,23 @@ void PlaybackQueue::SetCurrentTrack(TrackPtr track){
if(this->currentTrack!=track){
this->currentTrack = track;
// Get all metadata to the track
if(this->currentTrack){
this->metadataQuery.Clear();
this->metadataQuery.RequestAllMetakeys();
this->metadataQuery.RequestTrack(this->currentTrack);
this->nowPlaying->Library()->AddQuery(this->metadataQuery,musik::core::Query::Wait|musik::core::Query::AutoCallback|musik::core::Query::UnCanceable|musik::core::Query::Prioritize);
}
// Call the signal if track updates
this->CurrentTrackChanged(track);
}
}
void PlaybackQueue::Play(tracklist::IRandomAccess &tracklist){
this->currentTrack.reset();
this->nowPlaying->CopyTracks(tracklist);
this->Play();
}

View File

@ -46,7 +46,7 @@ namespace musik { namespace core {
//////////////////////////////////////////////////////////////////////////////
class PlaybackQueue{
class PlaybackQueue : public sigslot::has_slots<>{
private:
PlaybackQueue(void);
static PlaybackQueue sInstance;
@ -54,6 +54,8 @@ class PlaybackQueue{
audio::Transport transport;
tracklist::IRandomAccessPtr nowPlaying;
bool playing;
public:
~PlaybackQueue(void);
static PlaybackQueue& Instance(){ return sInstance; };
@ -66,7 +68,7 @@ class PlaybackQueue{
// Playback Control
void Play();
void Next();
void Previos();
void Previous();
void Stop();
musik::core::TrackPtr CurrentTrack();
@ -77,6 +79,11 @@ class PlaybackQueue{
private:
TrackPtr currentTrack;
void SetCurrentTrack(TrackPtr track);
musik::core::Query::Tracks metadataQuery;
void OnPlaybackEndOrFail();
bool signalDisabled;
};

View File

@ -141,6 +141,11 @@ bool Tracks::ParseQuery(Library::Base *oLibrary,db::Connection &db){
std::string sql=this->sSQL+this->sSQLTables+this->sSQLWhere;
if(sql.empty()){
// ERROR.. SOMETHING IS WRONG HERE
return true;
}
db::CachedStatement trackData(sql.c_str(),db);
bool bCancel(false);

View File

@ -531,3 +531,7 @@ void Track::SetThumbnail(const char *data,unsigned int size){
this->meta->SetThumbnail(data,size);
}
}
TrackPtr Track::Copy(){
return TrackPtr(new Track(this->id));
}

View File

@ -50,6 +50,22 @@
namespace musik{ namespace core{
// Forward declare
class Track;
/*!
* \brief
* shared pointer to a track.
*
* The TrackPtr is used almost everywhere since the Tracks can be
* shared between different threads.
*
* \remarks
* For the Tracks to be thread-safe, you need to pass the ThreadHelper object when required.
*
* \see
* Track|TrackVector
*/
typedef boost::shared_ptr<Track> TrackPtr;
/*!
* \brief
@ -82,6 +98,8 @@ namespace musik{ namespace core{
DBINT id;
void ClearMeta();
TrackPtr Copy();
private:
// const TrackMeta::Value& GetValue(const TrackMeta::Key &key) const;
@ -109,20 +127,6 @@ namespace musik{ namespace core{
DBINT _GetArtist(db::Connection &dbConnection,utfstring artist,bool addRelation,bool aggregated=false);
};
/*!
* \brief
* shared pointer to a track.
*
* The TrackPtr is used almost everywhere since the Tracks can be
* shared between different threads.
*
* \remarks
* For the Tracks to be thread-safe, you need to pass the ThreadHelper object when required.
*
* \see
* Track|TrackVector
*/
typedef boost::shared_ptr<Track> TrackPtr;
/*!
* \brief

View File

@ -37,6 +37,7 @@
#pragma once
#include "core/tracklist/IBase.h"
#include <core/Library/Base.h>
#include <boost/shared_ptr.hpp>
namespace musik{ namespace core{
@ -49,6 +50,13 @@ namespace musik{ namespace core{
virtual int Size() = 0;
virtual void SetCurrentPosition(int position) = 0;
virtual int CurrentPosition() = 0;
virtual void SetLibrary(musik::core::LibraryPtr setLibrary) = 0;
virtual musik::core::LibraryPtr Library() = 0;
virtual void CopyTracks(musik::core::tracklist::IRandomAccess &tracklist) = 0;
virtual void AppendTracks(musik::core::tracklist::IRandomAccess &tracklist) = 0;
virtual musik::core::TrackPtr Track(int position)=0;
};
typedef boost::shared_ptr<IRandomAccess> IRandomAccessPtr;
@ -56,3 +64,4 @@ namespace musik{ namespace core{
}
} }

View File

@ -50,7 +50,7 @@ Standard::~Standard(void){
}
musik::core::TrackPtr Standard::CurrentTrack(){
return (*this)[this->currentPosition];
return this->Track(this->currentPosition);
}
@ -79,7 +79,7 @@ musik::core::TrackPtr Standard::operator [](int position){
return musik::core::TrackPtr();
}
musik::core::TrackPtr Standard::at(int position){
musik::core::TrackPtr Standard::Track(int position){
if(position>=0 && position<this->tracks.size())
return this->tracks[position];
@ -100,7 +100,7 @@ void Standard::SetCurrentPosition(int position){
if(position<-1){
this->currentPosition = -1;
}else{
if(position>=this->tracks.size()){
if(position >= (int)this->tracks.size()){
this->currentPosition = this->tracks.size()-1;
}else{
this->currentPosition = position;
@ -113,7 +113,7 @@ int Standard::CurrentPosition(){
if(this->currentPosition<0)
return -1;
if(this->currentPosition>=this->tracks.size())
if(this->currentPosition >= (int)this->tracks.size())
return this->tracks.size()-1;
return this->currentPosition;
@ -124,10 +124,14 @@ void Standard::ConnectToQuery(musik::core::Query::ListBase &listQuery){
}
void Standard::ConnectToLibrary(musik::core::LibraryPtr setLibrary){
void Standard::SetLibrary(musik::core::LibraryPtr setLibrary){
this->library = setLibrary;
}
musik::core::LibraryPtr Standard::Library(){
return this->library;
}
void Standard::OnTracksFromQuery(musik::core::TrackVector *newTracks,bool clear){
@ -152,7 +156,7 @@ void Standard::LoadTrack(int position){
for(int i(position);i<position+this->hintedRows;++i){
if(!this->InCache(i)){
// Not in cache, load the track and add to Cache
musik::core::TrackPtr track = this->at(i);
musik::core::TrackPtr track = this->Track(i);
if(track){
this->trackCache.insert(CacheTrack(track,i));
++trackCount;
@ -161,7 +165,7 @@ void Standard::LoadTrack(int position){
}
}
if(trackCount){
if(trackCount && this->library){
this->library->AddQuery(this->trackQuery,musik::core::Query::Prioritize);
this->trackQuery.Clear();
}
@ -218,5 +222,26 @@ void Standard::RemoveRequestedMetakey(const char* metakey){
this->trackQuery.RequestMetakeys(this->requestedMetaKeys);
}
void Standard::CopyTracks(musik::core::tracklist::IRandomAccess &tracklist){
this->SetLibrary(tracklist.Library());
this->tracks.clear();
this->tracks.reserve(tracklist.Size());
for(int i(0);i<tracklist.Size();++i){
this->tracks.push_back(tracklist.Track(i)->Copy());
}
this->SetCurrentPosition(tracklist.CurrentPosition());
}
void Standard::AppendTracks(musik::core::tracklist::IRandomAccess &tracklist){
if(!this->library){
this->SetLibrary(tracklist.Library());
}
this->tracks.reserve(this->tracks.size()+tracklist.Size());
for(int i(0);i<tracklist.Size();++i){
this->tracks.push_back(tracklist.Track(i)->Copy());
}
}

View File

@ -44,6 +44,7 @@
#include <core/Library/Base.h>
#include <sigslot/sigslot.h>
#include <boost/shared_ptr.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
@ -59,6 +60,9 @@ namespace musik{ namespace core{
class Standard : public IRandomAccess, public sigslot::has_slots<> {
public:
typedef boost::shared_ptr<Standard> Ptr;
Standard(void);
~Standard(void);
@ -72,7 +76,8 @@ namespace musik{ namespace core{
int CurrentPosition();
void ConnectToQuery(musik::core::Query::ListBase &listQuery);
void ConnectToLibrary(musik::core::LibraryPtr setLibrary);
void SetLibrary(musik::core::LibraryPtr setLibrary);
musik::core::LibraryPtr Library();
typedef sigslot::signal1<bool> TracksEvent;
@ -87,9 +92,11 @@ namespace musik{ namespace core{
void AddRequestedMetakey(const char* metakey);
void RemoveRequestedMetakey(const char* metakey);
void CopyTracks(musik::core::tracklist::IRandomAccess &tracklist);
void AppendTracks(musik::core::tracklist::IRandomAccess &tracklist);
protected:
musik::core::TrackPtr at(int position);
musik::core::TrackPtr Track(int position);
std::set<std::string> requestedMetaKeys;

View File

@ -68,8 +68,6 @@ using namespace musik::cube;
musik::core::LibraryFactory::GetCurrentLibrary()->OnQueryQueueStart.connect(this,&MainWindowController::QueryQueueStart);
musik::core::LibraryFactory::GetCurrentLibrary()->OnQueryQueueEnd.connect(this,&MainWindowController::QueryQueueEnd);
musik::core::LibraryPtr lib = musik::core::LibraryFactory::GetCurrentLibrary();
((musik::core::Library::LocalDB*)lib.get())->indexer.AddPath(_T("X:/musik/"));
}
MainWindowController::~MainWindowController()

View File

@ -73,15 +73,22 @@ void TracklistController::OnViewCreated()
//
listView->EnableStripedBackground(true);
listView->SetModel(this->model);
listView->RowDoubleClick.connect(this,&TracklistController::OnRowDoubleClick);
}
void TracklistController::OnResized(Size size)
{
}
void TracklistController::OnRowDoubleClick(int row)
{
((TracklistModel*)this->model.get())->OnRowDoubleClick(row);
}
void TracklistController::AddColumn(const utfchar *name,const char *metakey,int size){
this->view.listView->AddColumn(ListView::ColumnRef(new TracklistColumn(metakey,name, size)));
((TracklistModel*)this->model.get())->tracklist.AddRequestedMetakey(metakey);
((TracklistModel*)this->model.get())->tracklist->AddRequestedMetakey(metakey);
}

View File

@ -66,6 +66,7 @@ public: /*ctor*/ TracklistController(TracklistView& listView,musik::core:
protected: void OnViewCreated();
protected: void OnResized(Size size);
protected: void OnRowDoubleClick(int row);
protected: void AddColumn(const utfchar *name,const char *metakey,int size);
protected: ModelRef model;

View File

@ -43,6 +43,8 @@
#include <pch.hpp>
#include <core/LibraryFactory.h>
#include <core/PlaybackQueue.h>
#include <cube/TracklistModel.hpp>
#include <cube/TracklistColumn.hpp>
@ -50,16 +52,17 @@ using namespace musik::cube;
//////////////////////////////////////////////////////////////////////////////
/*ctor*/ TracklistModel::TracklistModel(musik::core::Query::ListBase *connectedQuery)
/*ctor*/ TracklistModel::TracklistModel(musik::core::Query::ListBase *connectedQuery) :
tracklist(new musik::core::tracklist::Standard())
{
this->SetRowCount(0);
this->tracklist.OnTracks.connect(this,&TracklistModel::OnTracks);
this->tracklist.OnTrackMeta.connect(this,&TracklistModel::OnTrackMeta);
this->tracklist.ConnectToLibrary(musik::core::LibraryFactory::GetCurrentLibrary());
this->tracklist->OnTracks.connect(this,&TracklistModel::OnTracks);
this->tracklist->OnTrackMeta.connect(this,&TracklistModel::OnTrackMeta);
this->tracklist->SetLibrary(musik::core::LibraryFactory::GetCurrentLibrary());
if(connectedQuery){
this->tracklist.ConnectToQuery(*connectedQuery);
this->tracklist->ConnectToQuery(*connectedQuery);
}
}
@ -71,7 +74,7 @@ uistring TracklistModel::CellValueToString(int rowIndex, ColumnRef co
typedef boost::basic_format<uichar> format;
// return (format(_T("%1% %2%")) % column->Name() % (rowIndex + 1)).str();
musik::core::TrackPtr track = this->tracklist[rowIndex];
musik::core::TrackPtr track = (*this->tracklist)[rowIndex];
if(!track){
return _T("");
}else{
@ -92,7 +95,11 @@ void TracklistModel::OnTracks(bool cleared){
if(cleared){
this->SetRowCount(0);
}
this->SetRowCount(this->tracklist.Size());
this->SetRowCount(this->tracklist->Size());
}
void TracklistModel::OnRowDoubleClick(int row){
this->tracklist->SetCurrentPosition(row);
musik::core::PlaybackQueue::Instance().Play(*this->tracklist);
}

View File

@ -67,7 +67,8 @@ public: virtual uistring CellValueToString(int rowIndex, ColumnRef column);
// instance data
protected: void OnTrackMeta(std::vector<int> &trackPositions);
protected: void OnTracks(bool cleared);
public: musik::core::tracklist::Standard tracklist;
public: musik::core::tracklist::Standard::Ptr tracklist;
public: void OnRowDoubleClick(int row);
};
//////////////////////////////////////////////////////////////////////////////

View File

@ -63,9 +63,15 @@ void TransportController::OnViewCreated()
this->transportView.stopButton->Pressed.connect(
this, &TransportController::OnStopPressed);
this->transportView.volumeSlider->Repositioned.connect(
this->transportView.nextButton->Pressed.connect(
this, &TransportController::OnNextPressed);
this->transportView.prevButton->Pressed.connect(
this, &TransportController::OnPreviousPressed);
/* this->transportView.volumeSlider->Repositioned.connect(
this, &TransportController::OnVolumeSliderChange);
this->transportView.volumeSlider->SetPosition(transport.Volume());
this->transportView.volumeSlider->SetPosition(transport.Volume());*/
}
void TransportController::OnViewResized(Size size)
@ -74,15 +80,25 @@ void TransportController::OnViewResized(Size size)
void TransportController::OnPlayPressed()
{
transport.Start(_T("d:\\musik\\test.mp3"));
musik::core::PlaybackQueue::Instance().Play();
}
void TransportController::OnStopPressed()
{
transport.Stop(0);
musik::core::PlaybackQueue::Instance().Stop();
}
void TransportController::OnNextPressed()
{
musik::core::PlaybackQueue::Instance().Next();
}
void TransportController::OnPreviousPressed()
{
musik::core::PlaybackQueue::Instance().Previous();
}
void TransportController::OnVolumeSliderChange()
{
transport.ChangeVolume(transportView.volumeSlider->Position()/100.0f);
// transport.ChangeVolume(transportView.volumeSlider->Position()/100.0f);
}

View File

@ -40,7 +40,7 @@
//////////////////////////////////////////////////////////////////////////////
#include <core/audio/Transport.h>
#include <core/PlaybackQueue.h>
#include <cube/TransportView.hpp>
//////////////////////////////////////////////////////////////////////////////
@ -63,9 +63,11 @@ protected: musik::core::audio::Transport transport;
protected: void OnPlayPressed();
protected: void OnStopPressed();
protected: void OnNextPressed();
protected: void OnPreviousPressed();
protected: void OnVolumeSliderChange();
};
//////////////////////////////////////////////////////////////////////////////
} } // musik::cube
} } // musik::cube

View File

@ -449,6 +449,22 @@ void ListView::OnMouseMoved(MouseEventFlags flags, const Point& location)
this->SetHotCell(rowIndex, column);
}
void ListView::OnMouseButtonDoubleClicked(MouseEventFlags flags, const Point& location)
{
int rowIndex(0);
ColumnRef column = ColumnRef();
//
if ( ! this->CellAtPoint(location, rowIndex, column))
{
rowIndex = -1;
column = ColumnRef();
}else{
this->RowDoubleClick(rowIndex);
}
//
}
void ListView::OnMouseExit()
{
this->SetHotCell(-1, ColumnRef());

View File

@ -123,11 +123,14 @@ public: typedef boost::shared_ptr<Model> ModelRef;
public: /*! */ typedef sigslot::signal1<int /*row*/> HotRowChangedEvent;
public: /*! */ typedef sigslot::signal1<int /*row*/> RowDoubleClickEvent;
public: /*! */ typedef sigslot::signal2<int /*row*/, ColumnRef> HotCellChangedEvent;
public: /*! */ typedef sigslot::signal0<> SelectionChangedEvent;
///\brief Emitted when the the mouse cursor has entered a new row
public: HotRowChangedEvent HotRowChanged;
///\brief Emitted when the the mousebutton doubleclicks on a row
public: RowDoubleClickEvent RowDoubleClick;
///\brief Emitted when the the mouse cursor has entered a new cell
public: HotCellChangedEvent HotCellChanged;
///\brief Emitted when the selection has changed
@ -184,6 +187,7 @@ protected: virtual void OnRowCountChanged();
protected: virtual void OnDataChanged(int rowIndex);
protected: virtual void OnMeasureItem(MEASUREITEMSTRUCT* measureItemStruct);
protected: virtual void OnMouseMoved(MouseEventFlags flags, const Point& location);
protected: virtual void OnMouseButtonDoubleClicked(MouseEventFlags flags, const Point& location);
protected: virtual void OnMouseExit();
private: typedef Window base;