123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173 |
- #include "ArtistAlbumLists.h"
- #include "Filters.h"
- #include "api__ml_pmp.h"
- #include "resource1.h"
- #include "metadata_utils.h"
- extern winampMediaLibraryPlugin plugin;
- #define SKIP_THE_AND_WHITESPACE(x) { while (!iswalnum(*x) && *x) x++; if (!_wcsnicmp(x,L"the ",4)) x+=4; while (*x == L' ') x++; }
- int STRCMP_NULLOK(const wchar_t *pa, const wchar_t *pb) {
- if (!pa) pa=L"";
- else SKIP_THE_AND_WHITESPACE(pa)
- if (!pb) pb=L"";
- else SKIP_THE_AND_WHITESPACE(pb)
- return lstrcmpi(pa,pb);
- }
- #undef SKIP_THE_AND_WHITESPACE
- Filter * getFilter(wchar_t *name);
- #define RETIFNZ(v) if ((v)<0) return use_dir?1:-1; if ((v)>0) return use_dir?-1:1;
- typedef struct
- {
- songid_t songid;
- Device * dev;
- } SortSongItem;
- int thread_killed = 0;
- static int useby, usedir, usecloud;
- static Device * currentDev;
- static int sortFunc(const void *elem1, const void *elem2)
- {
- int use_by=useby;
- int use_dir=usedir;
- songid_t a=(songid_t)*(void **)elem1;
- songid_t b=(songid_t)*(void **)elem2;
- wchar_t bufa[2048] = {0}, bufb[2048] = {0};
- // this might be too slow, but it'd be nice
- for (int x = 0; x < 5; x ++)
- {
- if (thread_killed) break;
- bufa[0]=bufb[0]=0;
- if (use_by == (7+usecloud)) // year -> artist -> album -> track
- {
- int v1=currentDev->getTrackYear(a);
- int v2=currentDev->getTrackYear(b);
- if (v1<0)v1=0;
- if (v2<0)v2=0;
- RETIFNZ(v1-v2)
- use_by=0;
- }
- else if (use_by == 4 && usecloud) // cloud -> artist -> album -> track
- {
- currentDev->getTrackExtraInfo(a,L"cloud",bufa,ARRAYSIZE(bufa));
- currentDev->getTrackExtraInfo(b,L"cloud",bufb,ARRAYSIZE(bufb));
- int v=STRCMP_NULLOK(bufa,bufb);
- RETIFNZ(v)
- use_by=0;
- }
- else if (use_by == 1) // title -> artist -> album -> disc -> track
- {
- currentDev->getTrackTitle(a,bufa,2048);
- currentDev->getTrackTitle(b,bufb,2048);
- int v=STRCMP_NULLOK(bufa,bufb);
- RETIFNZ(v)
- use_by=0;
- }
- else if (use_by == 0) // artist -> album -> disc -> track -> title
- {
- currentDev->getTrackArtist(a,bufa,2048);
- currentDev->getTrackArtist(b,bufb,2048);
- int v=STRCMP_NULLOK(bufa,bufb);
- RETIFNZ(v)
- use_by=2;
- }
- else if (use_by == 2) // album -> disc -> track -> title -> artist
- {
- currentDev->getTrackAlbum(a,bufa,2048);
- currentDev->getTrackAlbum(b,bufb,2048);
- int v=STRCMP_NULLOK(bufa,bufb);
- RETIFNZ(v)
- use_dir=0;
- use_by=5;
- }
- else if (use_by == 5+usecloud) // disc -> track -> title -> artist -> album
- {
- int v1=currentDev->getTrackDiscNum(a);
- int v2=currentDev->getTrackDiscNum(b);
- if (v1<0)v1=0;
- if (v2<0)v2=0;
- RETIFNZ(v1-v2)
- use_by=4;
- }
- else if (use_by == 4+usecloud) // track -> title -> artist -> album -> disc
- {
- int v1=currentDev->getTrackTrackNum(a);
- int v2=currentDev->getTrackTrackNum(b);
- if (v1<0)v1=0;
- if (v2<0)v2=0;
- RETIFNZ(v1-v2)
- use_by=1;
- }
- else if (use_by == 6+usecloud) // genre -> artist -> album -> disc -> track
- {
- currentDev->getTrackGenre(a,bufa,2048);
- currentDev->getTrackGenre(b,bufb,2048);
- int v=STRCMP_NULLOK(bufa,bufb);
- RETIFNZ(v)
- use_by=0;
- }
- else if (use_by == 3) // length -> artist -> album -> disc -> track
- {
- int v1=currentDev->getTrackLength(a);
- int v2=currentDev->getTrackLength(b);
- if (v1<0)v1=0;
- if (v2<0)v2=0;
- RETIFNZ(v1-v2)
- use_by=0;
- }
- else if (use_by == (8+usecloud)) // bitrate -> artist -> album -> disc -> track
- {
- int v1=currentDev->getTrackBitrate(a);
- int v2=currentDev->getTrackBitrate(b);
- if (v1<0)v1=0;
- if (v2<0)v2=0;
- RETIFNZ(v1-v2)
- use_by=0;
- }
- else if (use_by == (9+usecloud)) // size -> artist -> album -> disc -> track
- {
- __int64 v1=currentDev->getTrackSize(a);
- __int64 v2=currentDev->getTrackSize(b);
- if (v1<0)v1=0;
- if (v2<0)v2=0;
- RETIFNZ(v1-v2)
- use_by=0;
- }
- else if (use_by == (10+usecloud)) // playcount -> artist -> album -> disc -> track
- {
- int v1=currentDev->getTrackPlayCount(a);
- int v2=currentDev->getTrackPlayCount(b);
- if (v1<0)v1=0;
- if (v2<0)v2=0;
- RETIFNZ(v1-v2)
- use_by=0;
- }
- else if (use_by == (11+usecloud)) // rating -> artist -> album -> disc -> track
- {
- int v1=currentDev->getTrackRating(a);
- int v2=currentDev->getTrackRating(b);
- if (v1<0)v1=0;
- if (v2<0)v2=0;
- RETIFNZ(v1-v2)
- use_by=0;
- }
- else if (use_by == (12+usecloud))
- {
- double v = difftime((time_t)currentDev->getTrackLastPlayed(a),(time_t)currentDev->getTrackLastPlayed(b));
- RETIFNZ(v);
- use_by=0;
- }
- else if (use_by == (13+usecloud)) // album artist -> album
- {
- currentDev->getTrackAlbumArtist(a,bufa,ARRAYSIZE(bufa));
- currentDev->getTrackAlbumArtist(b,bufb,ARRAYSIZE(bufb));
- int v=STRCMP_NULLOK(bufa,bufb);
- RETIFNZ(v)
- use_by=2;
- }
- else if (use_by == (14+usecloud)) // publisher -> album
- {
- currentDev->getTrackPublisher(a,bufa,ARRAYSIZE(bufa));
- currentDev->getTrackPublisher(b,bufb,ARRAYSIZE(bufb));
- int v=STRCMP_NULLOK(bufa,bufb);
- RETIFNZ(v)
- use_by=2;
- }
- else if (use_by == (15+usecloud)) // composer -> album
- {
- currentDev->getTrackComposer(a,bufa,ARRAYSIZE(bufa));
- currentDev->getTrackComposer(b,bufb,ARRAYSIZE(bufb));
- int v=STRCMP_NULLOK(bufa,bufb);
- RETIFNZ(v)
- use_by=2;
- }
- else if (use_by == (16+usecloud)) // mime -> artist -> album -> disc -> track
- {
- currentDev->getTrackMimeType(a,bufa,ARRAYSIZE(bufa));
- currentDev->getTrackMimeType(b,bufb,ARRAYSIZE(bufb));
- int v=STRCMP_NULLOK(bufa,bufb);
- RETIFNZ(v)
- use_by=2;
- }
- else if (use_by == (17+usecloud)) // date added -> artist -> album -> disc -> track
- {
- double v = difftime((time_t)currentDev->getTrackDateAdded(a),(time_t)currentDev->getTrackDateAdded(b));
- RETIFNZ(v);
- use_by=0;
- }
- else break; // no sort order?
- if (thread_killed) break;
- }
- return 0;
- }
- static int sortFunc_filteritems(const void *elem1, const void *elem2) {
- FilterItem *a=(FilterItem *)*(void **)elem1;
- FilterItem *b=(FilterItem *)*(void **)elem2;
- return a->compareTo2(b,useby,usedir);
- }
- class FilterList : public ListContents {
- public:
- Filter * filter;
- C_ItemList * items;
- ArtistAlbumLists * aaList;
- wchar_t topString[128];
- int nextFilterNum;
- int tracks;
- int sortcol;
- int sortdir;
- int id;
- FilterList(int id, Device * dev0, C_Config * config, Filter * filter, ArtistAlbumLists * aaList, bool cloud) :
- id(id), filter(filter), sortcol(0), sortdir(0), aaList(aaList), tracks(0), nextFilterNum(0), items(0) {
- this->topString[0] = 0;
- this->config = config;
- this->dev = dev0;
- this->cloud = cloud;
- this->cloudcol = -1;
- filter->AddColumns(dev, &fields, config, !!this->cloud);
- for(int i = 0; i < fields.GetSize(); i++) {
- if (!lstrcmpi(((ListField *)fields.Get(i))->name, L"cloud"))
- {
- this->cloudcol = ((ListField *)fields.Get(i))->pos;
- break;
- }
- }
- wchar_t temp[16] = {0};
- wsprintf(temp, L"filter%d_sortcol", id);
- this->sortcol = config->ReadInt(temp, 0);
- wsprintf(temp, L"filter%d_sortdir", id);
- this->sortdir = config->ReadInt(temp, 0);
- this->SortColumns();
- }
- virtual ~FilterList() {
- wchar_t temp[16] = {0};
- wsprintf(temp, L"filter%d_sortcol", id);
- config->WriteInt(temp, sortcol);
- wsprintf(temp, L"filter%d_sortdir", id);
- config->WriteInt(temp, sortdir);
- }
- virtual int GetNumColumns() { return fields.GetSize(); }
- virtual int GetNumRows() { return items->GetSize() + (filter->HaveTopItem()?1:0); }
- virtual wchar_t * GetColumnTitle(int num) {
- if(num >=0 && num < fields.GetSize())
- return ((ListField *)fields.Get(num))->name;
- return L"";
- }
- virtual int GetColumnWidth(int num) {
- if(num >=0 && num < fields.GetSize())
- return ((ListField *)fields.Get(num))->width;
- return 0;
- }
- virtual void GetCellText(int row, int col, wchar_t * buf, int buflen) {
- buf[0]=0;
- if(col >= fields.GetSize() || aaList->bgThread_Handle) return;
- int colid = ((ListField*)fields.Get(col))->field;
- if(filter->HaveTopItem()) {
- if(row) ((FilterItem*)items->Get(row-1))->GetCellText(colid,buf,buflen);
- else {
- if(colid%100 == 0) lstrcpyn(buf,topString,buflen);
- else if(colid%100 == 41) wsprintf(buf,L"%d",tracks);
- else if(colid%100 == 40 && filter->nextFilter) wsprintf(buf,L"%d",nextFilterNum);
- }
- } else ((FilterItem*)items->Get(row))->GetCellText(colid,buf,buflen);
- }
- virtual void SortList() {
- if (sortcol > fields.GetSize()) return;
- useby=((ListField*)fields.Get(sortcol))->field;
- usedir=sortdir;
- qsort(items->GetAll(),items->GetSize(),sizeof(void*),sortFunc_filteritems);
- }
- virtual int GetSortDirection() { return sortdir; }
- virtual int GetSortColumn() { return sortcol; }
- virtual void ColumnClicked(int col) {
- if(col == sortcol)
- sortdir = sortdir?0:1;
- else {
- sortdir=0;
- sortcol=col;
- }
- SortList();
- }
- virtual void ColumnResize(int col, int newWidth) {
- if(col >=0 && col < fields.GetSize()) {
- ListField * lf = (ListField *)fields.Get(col);
- lf->width = newWidth;
- wchar_t buf[100] = {0};
- wsprintf(buf,L"colWidth_%d",lf->field);
- config->WriteInt(buf,newWidth);
- }
- }
- virtual pmpart_t GetArt(int row) { return ((FilterItem*)items->Get(row))->GetArt(); }
- virtual void SetMode(int mode) {
- filter->SetMode(mode);
- int i=fields.GetSize();
- while(i>=0) { i--; delete (ListField*)fields.Get(i); fields.Del(i); }
- filter->AddColumns(dev, &fields, config, !!this->cloud);
- SortColumns();
- }
- virtual songid_t GetTrack(int pos) { return 0; }
- };
- static void getStars(int stars, wchar_t * buf, int buflen) {
- wchar_t * r=L"";
- switch(stars) {
- case 1: r=L"\u2605"; break;
- case 2: r=L"\u2605\u2605"; break;
- case 3: r=L"\u2605\u2605\u2605"; break;
- case 4: r=L"\u2605\u2605\u2605\u2605"; break;
- case 5: r=L"\u2605\u2605\u2605\u2605\u2605"; break;
- }
- lstrcpyn(buf,r,buflen);
- }
- extern void timeToString(__time64_t time, wchar_t * buf, int buflen);
- static void timeValue(int totalsecs, wchar_t *dest)
- {
- int secs=totalsecs%60;
- int mins=(totalsecs/60)%60;
- int hours=(totalsecs/3600)%24;
- int days=(totalsecs/86400);
- if(days==0) {
- wsprintf(dest,L"%d:%02d:%02d",hours,mins,secs);
- } else if(days==1) {
- wsprintf(dest,L"%d day+%d:%02d:%02d",days,hours,mins,secs);
- } else {
- wsprintf(dest,L"%d days+%d:%02d:%02d",days,hours,mins,secs);
- }
- }
- void GetInfoString(wchar_t * buf, Device * dev, int numTracks, __int64 totalSize, int totalPlayLength, int cloud) {
- wchar_t lengthStr[100]=L"";
- wchar_t sizeStr[100]=L"";
- wchar_t availStr[100]=L"";
- wchar_t devCapacityStr[100]=L"";
- int usedPercent;
- int fieldsBits = (int)dev->extraActions(DEVICE_SUPPORTED_METADATA,0,0,0);
- if(!fieldsBits || (fieldsBits & SUPPORTS_LENGTH)) {
- lengthStr[0] = L'[';
- timeValue(totalPlayLength,&lengthStr[1]);
- wcscat_s(lengthStr,100,L"] ");
- }
- __int64 available = dev->getDeviceCapacityAvailable();
- WASABI_API_LNG->FormattedSizeString(sizeStr, ARRAYSIZE(sizeStr), totalSize);
- WASABI_API_LNG->FormattedSizeString(availStr, ARRAYSIZE(availStr), available);
- __int64 capacity = dev->getDeviceCapacityTotal();
- WASABI_API_LNG->FormattedSizeString(devCapacityStr, ARRAYSIZE(devCapacityStr), capacity);
- if(capacity > 0) usedPercent = (int)((((__int64)100)*available) / capacity);
- else usedPercent = 0;
- if (!cloud || cloud && available > 0)
- wsprintf(buf, WASABI_API_LNGSTRINGW(IDS_X_ITEMS_X_AVAILABLE), numTracks, lengthStr, sizeStr, availStr, usedPercent, devCapacityStr);
- else
- wsprintf(buf, WASABI_API_LNGSTRINGW(IDS_X_ITEMS_X_AVAILABLE_SLIM), numTracks, lengthStr, sizeStr);
- }
- class TracksList : public PrimaryListContents {
- public:
- __int64 totalSize;
- int totalPlayLength;
- int sortcol;
- int sortdir;
- C_ItemList * tracks;
- Device * dev;
- ArtistAlbumLists * aaList;
- TracksList(Device * dev,C_Config * config, ArtistAlbumLists * aaList, bool cloud) :
- dev(dev), aaList(aaList), totalSize(0), totalPlayLength(0), tracks(0) {
- this->config = config;
- this->cloud = cloud;
- this->cloudcol = -1;
- this->sortcol = config->ReadInt(L"sortcol", 0);
- this->sortdir = config->ReadInt(L"sortdir", 0);
- int fieldsBits = (int)dev->extraActions(DEVICE_SUPPORTED_METADATA,0,0,0);
- if (!fieldsBits) fieldsBits = -1;
- if (fieldsBits & SUPPORTS_ARTIST) fields.Add(new ListField(0, 200, WASABI_API_LNGSTRINGW(IDS_ARTIST), config));
- if (fieldsBits & SUPPORTS_TITLE) fields.Add(new ListField(1, 200, WASABI_API_LNGSTRINGW(IDS_TITLE), config));
- if (fieldsBits & SUPPORTS_ALBUM) fields.Add(new ListField(2, 200, WASABI_API_LNGSTRINGW(IDS_ALBUM), config));
- if (fieldsBits & SUPPORTS_LENGTH) fields.Add(new ListField(3, 64, WASABI_API_LNGSTRINGW(IDS_LENGTH), config));
- if (cloud) fields.Add(new ListField(3+cloud, 27, WASABI_API_LNGSTRINGW(IDS_CLOUD), config));
- if (fieldsBits & SUPPORTS_TRACKNUM) fields.Add(new ListField(4+cloud, 50, WASABI_API_LNGSTRINGW(IDS_TRACK_NUMBER), config));
- if (fieldsBits & SUPPORTS_DISCNUM) fields.Add(new ListField(5+cloud, 38, WASABI_API_LNGSTRINGW(IDS_DISC), config));
- if (fieldsBits & SUPPORTS_GENRE) fields.Add(new ListField(6+cloud, 100, WASABI_API_LNGSTRINGW(IDS_GENRE), config));
- if (fieldsBits & SUPPORTS_YEAR) fields.Add(new ListField(7+cloud, 38, WASABI_API_LNGSTRINGW(IDS_YEAR), config));
- if (fieldsBits & SUPPORTS_BITRATE) fields.Add(new ListField(8+cloud, 45, WASABI_API_LNGSTRINGW(IDS_BITRATE), config));
- if (fieldsBits & SUPPORTS_SIZE) fields.Add(new ListField(9+cloud, 90, WASABI_API_LNGSTRINGW(IDS_SIZE), config));
- if (fieldsBits & SUPPORTS_PLAYCOUNT) fields.Add(new ListField(10+cloud, 64, WASABI_API_LNGSTRINGW(IDS_PLAY_COUNT), config));
- if (fieldsBits & SUPPORTS_RATING) fields.Add(new ListField(11+cloud, 64, WASABI_API_LNGSTRINGW(IDS_RATING), config));
- if (fieldsBits & SUPPORTS_LASTPLAYED) fields.Add(new ListField(12+cloud, 120, WASABI_API_LNGSTRINGW(IDS_LAST_PLAYED), config));
- if (fieldsBits & SUPPORTS_ALBUMARTIST) fields.Add(new ListField(13+cloud, 200, WASABI_API_LNGSTRINGW(IDS_ALBUM_ARTIST), config, true));
- if (fieldsBits & SUPPORTS_PUBLISHER) fields.Add(new ListField(14+cloud, 200, WASABI_API_LNGSTRINGW(IDS_PUBLISHER), config, true));
- if (fieldsBits & SUPPORTS_COMPOSER) fields.Add(new ListField(15+cloud, 200, WASABI_API_LNGSTRINGW(IDS_COMPOSER), config, true));
- if (fieldsBits & SUPPORTS_MIMETYPE) fields.Add(new ListField(16+cloud, 100, WASABI_API_LNGSTRINGW(IDS_MIME_TYPE), config, true));
- if (fieldsBits & SUPPORTS_DATEADDED) fields.Add(new ListField(17+cloud, 120, WASABI_API_LNGSTRINGW(IDS_DATE_ADDED), config, true));
- this->SortColumns();
- if (cloud)
- {
- // not pretty but it'll allow us to know the current
- // position of the cloud column for drawing purposes
- for(int i = 0; i < fields.GetSize(); i++) {
- if (!lstrcmpi(((ListField *)fields.Get(i))->name, L"cloud"))
- {
- this->cloudcol = ((ListField *)fields.Get(i))->pos;
- break;
- }
- }
- }
- }
- virtual ~TracksList() {
- config->WriteInt(L"sortcol", sortcol);
- config->WriteInt(L"sortdir", sortdir);
- }
- virtual int GetNumColumns() { return fields.GetSize(); }
- virtual int GetNumRows() { return (tracks ? tracks->GetSize() : 0); }
- virtual int GetColumnWidth(int num) {
- if(num >=0 && num < fields.GetSize())
- return ((ListField *)fields.Get(num))->width;
- return 0;
- }
- virtual wchar_t * GetColumnTitle(int num) {
- if(num >=0 && num < fields.GetSize())
- return ((ListField *)fields.Get(num))->name;
- return L"";
- }
- virtual void GetCellText(int row, int col, wchar_t * buf, int buflen) {
- buf[0]=0;
- if(row >= tracks->GetSize() || aaList->bgThread_Handle) return;
- songid_t s = (songid_t)tracks->Get(row);
- if(col >=0 && col < fields.GetSize()) {
- if (cloud)
- {
- switch(((ListField *)fields.Get(col))->field) {
- case 0: dev->getTrackArtist(s,buf,buflen); return;
- case 1: dev->getTrackTitle(s,buf,buflen); return;
- case 2: dev->getTrackAlbum(s,buf,buflen); return;
- case 3: { int l=dev->getTrackLength(s); if (l>=0) wsprintf(buf,L"%d:%02d",l/1000/60,(l/1000)%60); return; }
- case 4: { dev->getTrackExtraInfo(s,L"cloud",buf,buflen); return; }
- case 5: { int t=dev->getTrackTrackNum(s); if (t>0) wsprintf(buf,L"%d",t); return; }
- case 6: { int d = dev->getTrackDiscNum(s); if(d>0) wsprintf(buf,L"%d",d); return; }
- case 7: dev->getTrackGenre(s,buf,buflen); return;
- case 8: { int d = dev->getTrackYear(s); if(d>0) wsprintf(buf,L"%d",d); return; }
- case 9: { int d = dev->getTrackBitrate(s); if(d>0) wsprintf(buf,WASABI_API_LNGSTRINGW(IDS_KBPS),d); return; }
- case 10: WASABI_API_LNG->FormattedSizeString(buf, buflen, dev->getTrackSize(s)); return;
- case 11: { int d = dev->getTrackPlayCount(s); if(d>=0) wsprintf(buf,L"%d",d); return; }
- case 12: getStars(dev->getTrackRating(s),buf,buflen); return;
- case 13: timeToString(dev->getTrackLastPlayed(s),buf,buflen); return;
- case 14: dev->getTrackAlbumArtist(s,buf,buflen); return;
- case 15: dev->getTrackPublisher(s,buf,buflen); return;
- case 16: dev->getTrackComposer(s,buf,buflen); return;
- case 17: dev->getTrackMimeType(s,buf,buflen); return;
- case 18: timeToString(dev->getTrackDateAdded(s),buf,buflen); return;
- }
- }
- else
- {
- switch(((ListField *)fields.Get(col))->field) {
- case 0: dev->getTrackArtist(s,buf,buflen); return;
- case 1: dev->getTrackTitle(s,buf,buflen); return;
- case 2: dev->getTrackAlbum(s,buf,buflen); return;
- case 3: { int l=dev->getTrackLength(s); wsprintf(buf,L"%d:%02d",l/1000/60,(l/1000)%60); return; }
- case 4: { int t=dev->getTrackTrackNum(s); if (t>0) wsprintf(buf,L"%d",t); return; }
- case 5: { int d = dev->getTrackDiscNum(s); if(d>0) wsprintf(buf,L"%d",d); return; }
- case 6: dev->getTrackGenre(s,buf,buflen); return;
- case 7: { int d = dev->getTrackYear(s); if(d>0) wsprintf(buf,L"%d",d); return; }
- case 8: { int d = dev->getTrackBitrate(s); if(d>0) wsprintf(buf,WASABI_API_LNGSTRINGW(IDS_KBPS),d); return; }
- case 9: WASABI_API_LNG->FormattedSizeString(buf, buflen, dev->getTrackSize(s)); return;
- case 10: { int d = dev->getTrackPlayCount(s); if(d>=0) wsprintf(buf,L"%d",d); return; }
- case 11: getStars(dev->getTrackRating(s),buf,buflen); return;
- case 12: timeToString(dev->getTrackLastPlayed(s),buf,buflen); return;
- case 13: dev->getTrackAlbumArtist(s,buf,buflen); return;
- case 14: dev->getTrackPublisher(s,buf,buflen); return;
- case 15: dev->getTrackComposer(s,buf,buflen); return;
- case 16: dev->getTrackMimeType(s,buf,buflen); return;
- case 17: timeToString(dev->getTrackDateAdded(s),buf,buflen); return;
- }
- }
- }
- }
- virtual void SortList() {
- useby = ((ListField*)fields.Get(sortcol))->field;
- usedir = sortdir;
- // if a cloud item then adjust things as needed
- // since we're inserting between genre and year
- usecloud = cloud;
- thread_killed = 0;
- currentDev = dev;
- qsort(tracks->GetAll(),tracks->GetSize(),sizeof(void*),sortFunc);
- }
- virtual void ColumnResize(int col, int newWidth) {
- if(col >=0 && col < fields.GetSize()) {
- ListField * lf = (ListField *)fields.Get(col);
- lf->width = newWidth;
- wchar_t buf[100] = {0};
- wsprintf(buf,L"colWidth_%d",lf->field);
- config->WriteInt(buf,newWidth);
- }
- }
- virtual int GetSortColumn() { return sortcol; }
- virtual int GetSortDirection() { return sortdir; }
- virtual void ColumnClicked(int col) {
- if(col == sortcol)
- sortdir = sortdir?0:1;
- else {
- sortdir=0;
- sortcol=col;
- }
- SortList();
- }
- virtual void GetInfoString(wchar_t * buf) {
- ::GetInfoString(buf, dev, tracks->GetSize(), totalSize, totalPlayLength, cloud);
- }
- virtual songid_t GetTrack(int pos) { return (songid_t)tracks->Get(pos); }
- virtual void RemoveTrack(songid_t song) {
- for(int i=0; i<tracks->GetSize(); i++) {
- if((songid_t)tracks->Get(i) == song) tracks->Del(i--);
- }
- }
- };
- static void FreeFilterItemList(C_ItemList * list) {
- if(!list) return;
- for(int i=0; i < list->GetSize(); i++) {
- FilterItem * a = (FilterItem*)list->Get(i);
- if(a->nextFilter) FreeFilterItemList(a->nextFilter); a->nextFilter=0;
- delete a;
- }
- delete list;
- }
- static DWORD WINAPI bgThreadSearchProc(void *tmp)
- {
- ArtistAlbumLists *aacList = (ArtistAlbumLists *)tmp;
- return (aacList ? aacList->bgSearchThreadProc(tmp) : 0);
- }
- static DWORD WINAPI bgThreadLoadProc(void *tmp)
- {
- ArtistAlbumLists *aacList = (ArtistAlbumLists *)tmp;
- return (aacList ? aacList->bgLoadThreadProc(tmp) : 0);
- }
- static DWORD WINAPI bgThreadRefineProc(void *tmp)
- {
- ArtistAlbumLists *aacList = (ArtistAlbumLists *)tmp;
- return (aacList ? aacList->bgRefineThreadProc(tmp) : 0);
- }
- extern HWND hwndMediaView;
- DWORD WINAPI ArtistAlbumLists::bgLoadThreadProc(void *tmp)
- {
- int l = dev->getPlaylistLength(playlistId);
- for(int i=0; i<l; i++) {
- songid_t x=dev->getPlaylistTrack(playlistId,i);
- int t = dev->getTrackType(x);
- if(type != -1 && t != type) continue;
- searchedTracks->Add((void*)x);
- trackList->Add((void*)x);
- unrefinedTracks->Add((void*)x);
- }
- for(int i=0; i<numFilters; i++) {
- if(i==0) {
- if (filters[0]) FreeFilterItemList(filters[0]->items);
- filters[0]->items = CompilePrimaryList(searchedTracks);
- }
- else {
- delete filters[i]->items;
- filters[i]->items = CompileSecondaryList(filters[i-1]->items,i,true);
- }
- filters[i]->SortList();
- }
- SetRefine(L"");
- if (!bgThread_Kill) PostMessage(hwndMediaView, WM_APP + 3, 0x69, 0);
- return 0;
- }
- DWORD WINAPI ArtistAlbumLists::bgSearchThreadProc(void *tmp)
- {
- int l = dev->getPlaylistLength(playlistId);
- C_ItemList allTracks;
- for(int i=0; i<l; i++) {
- songid_t x=dev->getPlaylistTrack(playlistId,i);
- int t = dev->getTrackType(x);
- if(type != -1 && t != type) continue;
- allTracks.Add((void*)x);
- }
- searchedTracks = FilterSongs(lastSearch, &allTracks);
- delete unrefinedTracks;
- unrefinedTracks = new C_ItemList;
- l=searchedTracks->GetSize();
- for(int i=0; i<l; i++) unrefinedTracks->Add(searchedTracks->Get(i));
- for(int i=0; i<numFilters; i++) {
- if(i==0) {
- FreeFilterItemList(filters[0]->items);
- filters[0]->items = CompilePrimaryList(searchedTracks);
- }
- else {
- delete filters[i]->items;
- filters[i]->items = CompileSecondaryList(filters[i-1]->items,i,true);
- }
- }
- SetRefine(L"");
- for(int i=0; i<numFilters; i++) filters[i]->SortList();
- if (!bgThread_Kill) PostMessage(hwndMediaView, WM_APP + 3, 0x69, 0);
- return 0;
- }
- DWORD WINAPI ArtistAlbumLists::bgRefineThreadProc(void *tmp)
- {
- SetRefine(lastRefine);
- if (!bgThread_Kill) PostMessage(hwndMediaView, WM_APP + 3, 0x69, 0);
- return 0;
- }
- void ArtistAlbumLists::bgQuery_Stop() // exported for other people to call since it is useful (eventually
- {
- KillTimer(hwndMediaView, 123);
- if (bgThread_Handle)
- {
- thread_killed = bgThread_Kill = 1;
- WaitForSingleObject(bgThread_Handle, INFINITE);
- CloseHandle(bgThread_Handle);
- bgThread_Handle = 0;
- }
- }
- void ArtistAlbumLists::bgQuery(int mode) // only internal used
- {
- bgQuery_Stop();
- // TODO cache the HWND to avoid confusion
- SetTimer(hwndMediaView, 123, 200, NULL);
- DWORD id;
- bgThread_Kill = 0;
- bgThread_Handle = CreateThread(NULL, 0, (!mode ? bgThreadLoadProc : (mode == 1 ? bgThreadSearchProc : bgThreadRefineProc)), (LPVOID)this, 0, &id);
- }
- ArtistAlbumLists::ArtistAlbumLists(Device * dev, int playlistId, C_Config * config, wchar_t ** filterNames, int numFilters0, int type, bool async) {
- this->type = type;
- this->dev = dev;
- this->playlistId = playlistId;
- this->numFilters = numFilters0;
- this->bgThread_Handle = 0;
- this->async = async;
- this->lastSearch = 0;
- this->lastRefine = 0;
- ZeroMemory(&filters, sizeof(filters));
- if (config->ReadInt(L"savefilter", 1))
- {
- lastSearch = wcsdup(config->ReadString(L"savedfilter", L""));
- lastRefine = wcsdup(config->ReadString(L"savedrefinefilter", L""));
- }
- Filter * f = NULL;
- for(int i = 0; i < numFilters; i++) {
- if(!i) { f = firstFilter = getFilter(filterNames[i]); }
- else { f->nextFilter = getFilter(filterNames[i]); f = f->nextFilter; }
- }
- f = firstFilter;
- for(int i=0; i<numFilters; i++) {
- filters[i] = new FilterList(i,dev,config,f,this,async);
- f = f->nextFilter;
- }
- tracksLC = new TracksList(dev,config,this,async);
- searchedTracks = new C_ItemList;
- trackList = new C_ItemList;
- unrefinedTracks = new C_ItemList;
- if (!async && (!lastSearch || lastSearch && !*lastSearch))
- {
- int l = dev->getPlaylistLength(playlistId);
- for(int i=0; i<l; i++) {
- songid_t x=dev->getPlaylistTrack(playlistId,i);
- int t = dev->getTrackType(x);
- if(type != -1 && t != type) continue;
- searchedTracks->Add((void*)x);
- trackList->Add((void*)x);
- unrefinedTracks->Add((void*)x);
- }
- }
- for(int i=0; i<numFilters; i++) {
- if(i==0) filters[i]->items = CompilePrimaryList(searchedTracks);
- else filters[i]->items = CompileSecondaryList(filters[i-1]->items,i,true);
- filters[i]->SortList();
- }
- tracksLC->tracks = trackList;
- tracksLC->dev=dev;
- if (async) bgQuery();
- else SetRefine((lastRefine ? lastRefine : L""));
- }
- ArtistAlbumLists::~ArtistAlbumLists() {
- if(numFilters && filters[0]) FreeFilterItemList(filters[0]->items);
- for(int i=0; i<numFilters; i++) {
- delete filters[i]->filter;
- if(i!=0) delete filters[i]->items;
- delete filters[i];
- }
- delete trackList;
- delete searchedTracks;
- delete unrefinedTracks;
- delete tracksLC;
- if (lastSearch) free(lastSearch);
- if (lastRefine) free(lastRefine);
- }
- static void parsequicksearch(wchar_t *out, wchar_t *in) // parses a list into a list of terms that we are searching for
- {
- int inquotes=0, neednull=0;
- while (in && *in)
- {
- wchar_t c=*in++;
- if (c != L' ' && c != L'\t' && c != L'\"')
- {
- neednull=1;
- *out++=c;
- }
- else if (c == L'\"')
- {
- inquotes=!inquotes;
- if (!inquotes)
- {
- *out++=0;
- neednull=0;
- }
- }
- else
- {
- if (inquotes) *out++=c;
- else if (neednull)
- {
- *out++=0;
- neednull=0;
- }
- }
- }
- *out++=0;
- *out++=0;
- }
- static int in_string(wchar_t *string, wchar_t *substring)
- {
- if (!string) return 0;
- if (!*substring) return 1;
- int l=lstrlen(substring);
- while (string[0]) if (!_wcsnicmp(string++,substring,l)) return 1;
- return 0;
- }
- C_ItemList * FilterSongs(const wchar_t * filter, const C_ItemList * songs, Device * dev, bool cloud)
- {
- wchar_t filterstr[256] = {0}, filteritems[300] = {0};
- lstrcpyn(filterstr,filter,256);
- parsequicksearch(filteritems,filterstr);
- C_ItemList * filtered = new C_ItemList;
- int l = songs->GetSize();
- for(int i=0; i<l; i++) {
- songid_t s = (songid_t)songs->Get(i);
- wchar_t *p=filteritems;
- if(p && *p) {
- while(p && *p) {
- bool in=false;
- for(int j=0; j<15; j++) {
- wchar_t buf[2048] = {0};
- int buflen=2048;
- if (cloud)
- {
- switch(j) {
- case 0: dev->getTrackArtist(s,buf,buflen); break;
- case 1: dev->getTrackTitle(s,buf,buflen); break;
- case 2: dev->getTrackAlbum(s,buf,buflen); break;
- case 3: { int l=dev->getTrackLength(s); wsprintf(buf,L"%d:%02d",l/1000/60,(l/1000)%60); break; }
- case 4: { dev->getTrackExtraInfo(s,L"cloud",buf,buflen); break; }
- case 5: wsprintf(buf,L"%d",dev->getTrackTrackNum(s)); break;
- case 6: wsprintf(buf,L"%d",dev->getTrackDiscNum(s)); break;
- case 7: dev->getTrackGenre(s,buf,buflen); break;
- case 8: wsprintf(buf,L"%d",dev->getTrackYear(s)); break;
- case 9: wsprintf(buf,WASABI_API_LNGSTRINGW(IDS_KBPS),dev->getTrackBitrate(s)); break;
- case 10: WASABI_API_LNG->FormattedSizeString(buf, buflen, dev->getTrackSize(s)); break;
- case 11: wsprintf(buf,L"%d",dev->getTrackPlayCount(s)); break;
- case 12: getStars(dev->getTrackRating(s),buf,buflen); break;
- case 13: timeToString(dev->getTrackLastPlayed(s),buf,buflen); break;
- case 14: dev->getTrackAlbumArtist(s,buf,buflen); break;
- case 15: dev->getTrackPublisher(s,buf,buflen); break;
- case 16: dev->getTrackComposer(s,buf,buflen); break;
- case 17: dev->getTrackMimeType(s,buf,buflen); break;
- case 18: timeToString(dev->getTrackDateAdded(s),buf,buflen); break;
- default: lstrcpyn(buf,L"",buflen); break;
- }
- }
- else
- {
- switch(j) {
- case 0: dev->getTrackArtist(s,buf,buflen); break;
- case 1: dev->getTrackTitle(s,buf,buflen); break;
- case 2: dev->getTrackAlbum(s,buf,buflen); break;
- case 3: { int l=dev->getTrackLength(s); wsprintf(buf,L"%d:%02d",l/1000/60,(l/1000)%60); break; }
- case 4: wsprintf(buf,L"%d",dev->getTrackTrackNum(s)); break;
- case 5: wsprintf(buf,L"%d",dev->getTrackDiscNum(s)); break;
- case 6: dev->getTrackGenre(s,buf,buflen); break;
- case 7: wsprintf(buf,L"%d",dev->getTrackYear(s)); break;
- case 8: wsprintf(buf,WASABI_API_LNGSTRINGW(IDS_KBPS),dev->getTrackBitrate(s)); break;
- case 9: WASABI_API_LNG->FormattedSizeString(buf, buflen, dev->getTrackSize(s)); break;
- case 10: wsprintf(buf,L"%d",dev->getTrackPlayCount(s)); break;
- case 11: getStars(dev->getTrackRating(s),buf,buflen); break;
- case 12: timeToString(dev->getTrackLastPlayed(s),buf,buflen); break;
- case 13: dev->getTrackAlbumArtist(s,buf,buflen); break;
- case 14: dev->getTrackPublisher(s,buf,buflen); break;
- case 15: dev->getTrackComposer(s,buf,buflen); break;
- case 16: dev->getTrackMimeType(s,buf,buflen); break;
- case 17: timeToString(dev->getTrackDateAdded(s),buf,buflen); break;
- default: lstrcpyn(buf,L"",buflen); break;
- }
- }
- if(in_string(buf,p)) { in=true; break;}
- }
- if(in) p+=lstrlen(p)+1;
- else break;
- }
- }
- if(p && *p) continue;
- filtered->Add((void*)s);
- }
- return filtered;
- }
- C_ItemList * ArtistAlbumLists::FilterSongs(const wchar_t * filter, const C_ItemList * songs)
- {
- return ::FilterSongs(filter,songs,dev,this->async);
- }
- static Filter * firstFil;
- static int sortFunc_ssi(const void *elem1, const void *elem2)
- {
- SortSongItem * a = (SortSongItem *)elem1;
- SortSongItem * b = (SortSongItem *)elem2;
- Filter * f = firstFil;
- while(f) {
- int r = f->sortFunc(a->dev,a->songid,b->songid);
- if(r) return r;
- f = f->nextFilter;
- }
- return 0;
- }
- C_ItemList * ArtistAlbumLists::CompilePrimaryList(const C_ItemList * songs) {
- C_ItemList * list = new C_ItemList;
- SortSongItem *songList = (SortSongItem*)calloc(songs->GetSize(), sizeof(SortSongItem));
- int l=songs->GetSize();
- for(int i=0; i<l; i++) { songList[i].songid = (songid_t)songs->Get(i); songList[i].dev = dev; }
- firstFil = firstFilter;
- qsort(songList,l,sizeof(SortSongItem),sortFunc_ssi); //sort it
- FilterItem * items[MAX_FILTERS]={0};
- Filter * filters[MAX_FILTERS]={0};
- Filter * f = firstFilter;
- int numFilters=0;
- while(f) {filters[numFilters++] = f; f=f->nextFilter;}
- for(int i=0; i<l; i++) {
- songid_t s = songList[i].songid;
- for(int j=0; j<numFilters; j++) {
- if(items[j] && filters[j]->isInGroup(dev,s,items[j])) filters[j]->addToGroup(dev,s,items[j]);
- else {
- for(int k=j; k<numFilters; k++) {
- items[k] = filters[k]->newGroup(dev,s);
- items[k]->nextFilter = new C_ItemList;
- if(k==0) list->Add(items[k]);
- else {
- items[k-1]->nextFilter->Add(items[k]);
- items[k-1]->numNextFilter++;
- }
- }
- break;
- }
- }
- }
- if (songList)
- {
- free(songList);
- songList = 0;
- }
- if(list->GetSize() && ((FilterItem*)list->Get(0))->isWithoutGroup()) {
- wsprintf(this->filters[0]->topString,WASABI_API_LNGSTRINGW(IDS_ALL_X_WITHOUT_X),
- list->GetSize()-1,(list->GetSize()==2)?this->filters[0]->filter->name:this->filters[0]->filter->namePlural,((FilterItem*)list->Get(0))->numTracks,this->filters[0]->filter->name);
- }
- else
- wsprintf(this->filters[0]->topString,WASABI_API_LNGSTRINGW(IDS_ALL_X),
- list->GetSize(),(list->GetSize()==1)?this->filters[0]->filter->name:this->filters[0]->filter->namePlural);
- CharLower(this->filters[0]->topString+3);
- this->filters[0]->tracks = songs->GetSize();
- return list;
- }
- static int sortFunc_filters(const void *elem1, const void *elem2) {
- FilterItem *a=(FilterItem *)*(void **)elem1;
- FilterItem *b=(FilterItem *)*(void **)elem2;
- return a->compareTo(b);
- }
- C_ItemList * ArtistAlbumLists::CompileSecondaryList(const C_ItemList * selectedItems, int level, bool updateTopArtist) {
- int totalTracks=0;
- C_ItemList * list = new C_ItemList;
- C_ItemList * collatedlist = new C_ItemList;
- for(int i=0; i < selectedItems->GetSize(); i++) {
- FilterItem * item = (FilterItem*)selectedItems->Get(i);
- if (item) {
- C_ItemList *nf = item->independentNextFilter?item->independentNextFilter:item->nextFilter;
- for(int j=0; j < nf->GetSize(); j++) list->Add(nf->Get(j));
- }
- }
- qsort(list->GetAll(),list->GetSize(),sizeof(void*),sortFunc_filters);
- FilterItem * curItem=0;
- for(int i=0; i < list->GetSize(); i++) {
- FilterItem * item = (FilterItem*)list->Get(i);
- if(curItem && !curItem->compareTo(item)) {
- curItem->independentTracks += item->numTracks;
- curItem->independentSize += item->size;
- curItem->independentLength += item->length;
- curItem->independentCloudState += item->cloudState;
- } else {
- curItem = item;
- collatedlist->Add(item);
- item->independentTracks = item->numTracks;
- curItem->independentSize = item->size;
- curItem->independentLength = item->length;
- curItem->independentCloudState = item->cloudState;
- if(item->independentNextFilter) delete item->independentNextFilter;
- item->independentNextFilter = new C_ItemList;
- }
- totalTracks+=item->numTracks;
- for(int k=0; k<item->nextFilter->GetSize(); k++) curItem->independentNextFilter->Add(item->nextFilter->Get(k));
- }
- delete list;
- if(updateTopArtist) this->filters[level-1]->nextFilterNum = collatedlist->GetSize();
- if(collatedlist->GetSize() && ((FilterItem*)collatedlist->Get(0))->isWithoutGroup()) {
- wsprintf(this->filters[level]->topString,WASABI_API_LNGSTRINGW(IDS_ALL_X_WITHOUT_X),
- collatedlist->GetSize(),(collatedlist->GetSize()==1)?this->filters[level]->filter->name:this->filters[level]->filter->namePlural,((FilterItem*)collatedlist->Get(0))->numTracks,this->filters[level]->filter->name);
- }
- else {
- wsprintf(this->filters[level]->topString,WASABI_API_LNGSTRINGW(IDS_ALL_X),
- collatedlist->GetSize(),(collatedlist->GetSize()==1)?this->filters[level]->filter->name:this->filters[level]->filter->namePlural);
- }
- CharLower(this->filters[level]->topString+3);
- this->filters[level]->tracks=totalTracks;
- return collatedlist;
- }
- // removes song from all relevant lists
- void ArtistAlbumLists::RemoveTrack(songid_t song)
- {
- if (searchedTracks)
- {
- for (int i=0;i<searchedTracks->GetSize();i++)
- {
- if (searchedTracks->Get(i) == (void *) song)
- {
- searchedTracks->Del(i--);
- }
- }
- }
- }
- void ArtistAlbumLists::SelectionChanged(int filterNum, SkinnedListView **listview) {
- for(int i=filterNum; i<numFilters-1; i++) {
- int l = listview[i]->listview.GetCount();
- bool all = (i != filterNum || (ListView_GetSelectedCount(listview[i]->listview.getwnd())==0));
- if(listview[i]->listview.GetSelected(0) && filters[i]->filter->HaveTopItem()) all=true;
- C_ItemList selectedItems;
- int j=0,f=0;
- if(filters[i]->filter->HaveTopItem()) { j=1; f=1; }
- for(; j<l; j++) {
- if(all || listview[i]->listview.GetSelected(j))
- selectedItems.Add(filters[i]->items->Get(j-f));
- }
- delete filters[i+1]->items;
- filters[i+1]->items = CompileSecondaryList(&selectedItems,i+1,false);
- filters[i+1]->SortList();
- listview[i+1]->UpdateList();
- }
- C_ItemList * tracks = new C_ItemList;
- C_ItemList * selectedItems[MAX_FILTERS]={0};
- for(int i=0; i<=filterNum; i++) {
- bool all = (ListView_GetSelectedCount(listview[i]->listview.getwnd())==0);
- if(listview[i]->listview.GetSelected(0) && filters[i]->filter->HaveTopItem()) all=true;
- if(all) selectedItems[i] = NULL;
- else {
- selectedItems[i] = new C_ItemList;
- int m = filters[i]->items->GetSize();
- int offset = filters[i]->filter->HaveTopItem()?1:0;
- for(int k=0; k<m; k++) if(listview[i]->listview.GetSelected(k+offset)) selectedItems[i]->Add(filters[i]->items->Get(k));
- }
- }
- int l=searchedTracks->GetSize();
- for(int j=0; j<l; j++) {
- songid_t track = (songid_t)searchedTracks->Get(j);
- bool matches=true;
- for(int i=0; i<=filterNum; i++) {
- matches=false;
- if(selectedItems[i]) {
- for(int k=0; k<selectedItems[i]->GetSize(); k++)
- if(filters[i]->filter->isInGroup(dev,track,(FilterItem*)selectedItems[i]->Get(k))) { matches=true; break; }
- }
- else matches=true;
- if(!matches) break;
- }
- if(matches) //woo hoo, its in!
- tracks->Add((void*)track);
- }
- delete unrefinedTracks;
- unrefinedTracks = tracks;
- SetRefine(L"");
- for(int i=0; i<=filterNum; i++)
- {
- delete selectedItems[i];
- }
- }
- void ArtistAlbumLists::SetRefine(const wchar_t * str, bool async) {
- if (!async)
- {
- C_ItemList * refinedTracks = FilterSongs(str,unrefinedTracks);
- C_ItemList * oldTrackList = trackList;
- trackList = refinedTracks;
- tracksLC->tracks = trackList;
- delete oldTrackList;
- tracksLC->SortList();
- // get stats
- __int64 fileSize=0;
- int playLength=0;
- int millis=0;
- for(int i=0; i < trackList->GetSize(); i++) {
- songid_t s = (songid_t)trackList->Get(i);
- fileSize += (__int64)dev->getTrackSize(s);
- playLength += dev->getTrackLength(s)/1000;
- millis += dev->getTrackLength(s)%1000;
- }
- playLength += millis/1000;
- tracksLC->totalPlayLength=playLength;
- tracksLC->totalSize=fileSize;
- }
- else
- {
- if (lastRefine)
- {
- free(lastRefine);
- lastRefine = 0;
- }
- lastRefine = wcsdup(str);
- bgQuery(2);
- }
- }
- void ArtistAlbumLists::SetSearch(const wchar_t * str, bool async) {
- bgQuery_Stop();
- if (!async)
- {
- delete searchedTracks; searchedTracks = NULL;
- C_ItemList allTracks;
- int l = dev->getPlaylistLength(playlistId);
- for(int i=0; i<l; i++) {
- songid_t x = dev->getPlaylistTrack(playlistId,i);
- if(type != -1 && dev->getTrackType(x) != type) continue;
- allTracks.Add((void*)x);
- }
- searchedTracks = FilterSongs(str,&allTracks);
- delete unrefinedTracks;
- unrefinedTracks = new C_ItemList;
- l=searchedTracks->GetSize();
- for(int i=0; i<l; i++) unrefinedTracks->Add(searchedTracks->Get(i));
- for(int i=0; i<numFilters; i++) {
- if(i==0) {
- FreeFilterItemList(filters[0]->items);
- filters[0]->items = CompilePrimaryList(searchedTracks);
- }
- else {
- delete filters[i]->items;
- filters[i]->items = CompileSecondaryList(filters[i-1]->items,i,true);
- }
- }
- SetRefine(L"");
- for(int i=0; i<numFilters; i++) filters[i]->SortList();
- }
- else
- {
- if (lastSearch)
- {
- free(lastSearch);
- lastSearch = 0;
- }
- if (!(str && *str))
- {
- if (unrefinedTracks) delete unrefinedTracks;
- if (searchedTracks) delete searchedTracks;
- if (trackList) delete trackList;
- searchedTracks = new C_ItemList;
- trackList = new C_ItemList;
- unrefinedTracks = new C_ItemList;
- }
- else
- {
- lastSearch = wcsdup(str);
- }
- bgQuery((str && *str));
- }
- }
- ListContents * ArtistAlbumLists::GetFilterList(int i) { return filters[i]; }
- PrimaryListContents * ArtistAlbumLists::GetTracksList() { return this->tracksLC; }
|