1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051 |
- #include "main.h"
- #include "ml_local.h"
- #include <windowsx.h>
- #include "../nu/listview.h"
- #include "..\..\General\gen_ml/config.h"
- #include "resource.h"
- #include <time.h>
- #include "..\..\General\gen_ml/ml_ipc.h"
- #include "../ml_pmp/pmp.h"
- #include "..\..\General\gen_ml/gaystring.h"
- #include "../nde/nde.h"
- #include "../replicant/nu/AutoWide.h"
- #include "../replicant/nu/AutoChar.h"
- #include "..\..\General\gen_ml/ml_ipc_0313.h"
- #include <math.h>
- #include <shlwapi.h>
- #include <strsafe.h>
- #include "..\..\General\gen_ml/menufucker.h"
- #include "api_mldb.h"
- #include "../replicant/foundation/error.h"
- static wchar_t oldText[4096];
- static int IPC_LIBRARY_SENDTOMENU;
- static HINSTANCE cloud_hinst;
- const int ML_MSG_PDXS_STATUS = 0x1001;
- const int ML_MSG_PDXS_MIX = 0x1002;
- void RefreshMetadata(HWND parent);
- static HRGN g_rgnUpdate = NULL;
- static int offsetX, offsetY, customAllowed;
- int groupBtn = 1, enqueuedef = 0;
- static viewButtons view;
- HWND hwndSearchGlobal = 0;
- //timers
- #define TIMER_RATINGAUTOUNHOVER_ID 65520
- #define TIMER_RATINGAUTOUNHOVER_DELAY 200
- void FixAmps(wchar_t *str, size_t len)
- {
- size_t realSize = 0;
- size_t extra = 0;
- wchar_t *itr = str;
- while (itr && *itr)
- {
- if (itr && *itr == L'&')
- extra++;
- itr++;
- realSize++;
- }
- extra = min(len - (realSize + 1), extra);
- while (extra)
- {
- str[extra+realSize] = str[realSize];
- if (str[realSize] == L'&')
- {
- extra--;
- str[extra+realSize] = L'&';
- }
- realSize--;
- }
- }
- void MakeDateString(__time64_t convertTime, wchar_t *dest, size_t destlen)
- {
- SYSTEMTIME sysTime;
- tm *newtime = _localtime64(&convertTime);
- if (newtime)
- {
- sysTime.wYear = (WORD)(newtime->tm_year + 1900);
- sysTime.wMonth = (WORD)(newtime->tm_mon + 1);
- sysTime.wDayOfWeek = (WORD)newtime->tm_wday;
- sysTime.wDay = (WORD)newtime->tm_mday;
- sysTime.wHour = (WORD)newtime->tm_hour;
- sysTime.wMinute = (WORD)newtime->tm_min;
- sysTime.wSecond = (WORD)newtime->tm_sec;
- sysTime.wMilliseconds = 0;
- GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &sysTime, NULL, dest, destlen);
- size_t dateSize = lstrlenW(dest);
- dest += dateSize;
- destlen -= dateSize;
- if (destlen)
- {
- *dest++ = L' ';
- destlen--;
- }
- GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &sysTime, NULL, dest, destlen);
- //wcsftime(expire_time, 63, L"%b %d, %Y", _localtime64(&convertTime));
- }
- else
- dest[0] = 0;
- }
- #define MAINTABLE_ID_CLOUD (unsigned char)-1
- const unsigned char extra_idsW[] =
- {
- MAINTABLE_ID_ISPODCAST,
- MAINTABLE_ID_PODCASTCHANNEL,
- MAINTABLE_ID_PODCASTPUBDATE,
- MAINTABLE_ID_GRACENOTEFILEID,
- MAINTABLE_ID_GRACENOTEEXTDATA,
- MAINTABLE_ID_LOSSLESS,
- MAINTABLE_ID_CODEC,
- MAINTABLE_ID_DIRECTOR,
- MAINTABLE_ID_PRODUCER,
- MAINTABLE_ID_WIDTH,
- MAINTABLE_ID_HEIGHT,
- MAINTABLE_ID_MIMETYPE,
- 0,
- MAINTABLE_ID_DATEADDED,
- MAINTABLE_ID_CLOUD,
- };
- const ExtendedFields extended_fields =
- {
- L"ispodcast",
- L"podcastchannel",
- L"podcastpubdate",
- L"GracenoteFileID",
- L"GracenoteExtData",
- L"lossless",
- L"codec",
- L"director",
- L"producer",
- L"width",
- L"height",
- L"mime",
- L"realsize",
- L"dateadded",
- L"cloud",
- };
- const wchar_t *extra_strsW[] =
- {
- extended_fields.ispodcast,
- extended_fields.podcastchannel,
- extended_fields.podcastpubdate,
- extended_fields.GracenoteFileID,
- extended_fields.GracenoteExtData,
- extended_fields.lossless,
- extended_fields.codec,
- extended_fields.director,
- extended_fields.producer,
- extended_fields.width,
- extended_fields.height,
- extended_fields.mimetype,
- extended_fields.realsize,
- extended_fields.dateadded,
- extended_fields.cloud,
- };
- const int NUM_EXTRA_COLSW = sizeof(extra_idsW) / sizeof(*extra_idsW);
- bool isMixable(itemRecordW &song);
- static int predixisExist;
- static BOOL g_displaysearch = TRUE;
- static BOOL g_displaycontrols = TRUE;
- nde_scanner_t m_media_scanner = 0;
- W_ListView resultlist;
- static int resultSkin;
- void fileInfoDialogs(HWND hwndParent);
- void editInfo(HWND hwndParent);
- void customizeColumnsDialog(HWND hwndParent);
- static HWND m_hwnd;
- itemRecordListW itemCache;
- static int bgThread_Kill = 0;
- static HANDLE bgThread_Handle;
- static bool isMixablePresent = true;
- CloudFiles cloudFiles, cloudUploading;
- typedef struct
- {
- UINT column_id;
- char *config_name;
- WORD defWidth;
- WORD minWidth;
- WORD maxWidth;
- }
- headerColumn;
- #define UNLIMITED_WIDTH ((WORD)-1)
- #define COLUMN_DEFMINWIDTH 12
- #define COLUMN_DEFMAXWIDTH UNLIMITED_WIDTH
- #define MAX_COLUMN_ORDER (MEDIAVIEW_COL_NUMS+1)
- static headerColumn columnList[MAX_COLUMN_ORDER - 1] =
- {
- {IDS_ARTIST, "mv_col_artist", 140, COLUMN_DEFMINWIDTH, COLUMN_DEFMAXWIDTH},
- {IDS_TITLE, "mv_col_title", 140, COLUMN_DEFMINWIDTH, COLUMN_DEFMAXWIDTH},
- {IDS_ALBUM, "mv_col_album", 140, COLUMN_DEFMINWIDTH, COLUMN_DEFMAXWIDTH},
- {IDS_LENGTH, "mv_col_length", 55, COLUMN_DEFMINWIDTH, COLUMN_DEFMAXWIDTH},
- {IDS_TRACK_NUMBER, "mv_col_track", 55, COLUMN_DEFMINWIDTH, COLUMN_DEFMAXWIDTH},
- {IDS_GENRE, "mv_col_genre", 75, COLUMN_DEFMINWIDTH, COLUMN_DEFMAXWIDTH},
- {IDS_YEAR, "mv_col_year", 55, COLUMN_DEFMINWIDTH, COLUMN_DEFMAXWIDTH},
- {IDS_FILENAME, "mv_col_fn", 140, COLUMN_DEFMINWIDTH, COLUMN_DEFMAXWIDTH},
- {IDS_RATING, "mv_col_rating", 65, COLUMN_DEFMINWIDTH, COLUMN_DEFMAXWIDTH},
- {IDS_PLAY_COUNT, "mv_col_playcount", 70, COLUMN_DEFMINWIDTH, COLUMN_DEFMAXWIDTH},
- {IDS_PLAYED_LAST, "mv_col_lastplay", 115, COLUMN_DEFMINWIDTH, COLUMN_DEFMAXWIDTH},
- {IDS_LAST_UPDATED, "mv_col_lastupd", 115, COLUMN_DEFMINWIDTH, COLUMN_DEFMAXWIDTH},
- {IDS_FILE_TIME, "mv_col_filetime", 115, COLUMN_DEFMINWIDTH, COLUMN_DEFMAXWIDTH},
- {IDS_COMMENT, "mv_col_comment", 140, COLUMN_DEFMINWIDTH, COLUMN_DEFMAXWIDTH},
- {IDS_FILE_SIZE, "mb_col_filesize", 100, COLUMN_DEFMINWIDTH, COLUMN_DEFMAXWIDTH},
- {IDS_BITRATE, "mb_col_bitrate", 100, COLUMN_DEFMINWIDTH, COLUMN_DEFMAXWIDTH},
- {IDS_TYPE, "mb_col_type", 100, COLUMN_DEFMINWIDTH, COLUMN_DEFMAXWIDTH},
- {IDS_DISC, "mb_col_disc", 55, COLUMN_DEFMINWIDTH, COLUMN_DEFMAXWIDTH},
- {IDS_ALBUM_ARTIST, "mb_col_albumartist", 100, COLUMN_DEFMINWIDTH, COLUMN_DEFMAXWIDTH},
- {IDS_FILE_PATH, "mb_col_filepath", 140, COLUMN_DEFMINWIDTH, COLUMN_DEFMAXWIDTH},
- {IDS_ALBUM_GAIN, "mb_col_albumgain", 100, COLUMN_DEFMINWIDTH, COLUMN_DEFMAXWIDTH},
- {IDS_TRACK_GAIN, "mb_col_trackgain", 100, COLUMN_DEFMINWIDTH, COLUMN_DEFMAXWIDTH},
- {IDS_PUBLISHER, "mb_col_publisher", 100, COLUMN_DEFMINWIDTH, COLUMN_DEFMAXWIDTH},
- {IDS_COMPOSER, "mb_col_composer", 100, COLUMN_DEFMINWIDTH, COLUMN_DEFMAXWIDTH},
- {IDS_EXTENSION, "mb_col_extension", 55, COLUMN_DEFMINWIDTH, COLUMN_DEFMAXWIDTH},
- {IDS_IS_PODCAST, "mb_col_ispodcast", 100, COLUMN_DEFMINWIDTH, COLUMN_DEFMAXWIDTH},
- {IDS_PODCAST_CHANNEL, "mb_col_podcastchannel", 100, COLUMN_DEFMINWIDTH, COLUMN_DEFMAXWIDTH},
- {IDS_PODCAST_PUBLISH_DATE, "mb_col_podcastpubdate", 115, COLUMN_DEFMINWIDTH, COLUMN_DEFMAXWIDTH},
- {IDS_BPM, "mb_col_bpm", 55, COLUMN_DEFMINWIDTH, COLUMN_DEFMAXWIDTH},
- {IDS_CATEGORY, "mb_col_category", 75, COLUMN_DEFMINWIDTH, COLUMN_DEFMAXWIDTH},
- {IDS_DIRECTOR, "mb_col_director", 100, COLUMN_DEFMINWIDTH, COLUMN_DEFMAXWIDTH},
- {IDS_PRODUCER, "mb_col_producer", 100, COLUMN_DEFMINWIDTH, COLUMN_DEFMAXWIDTH},
- {IDS_DIMENSION, "mb_col_dimension", 100, COLUMN_DEFMINWIDTH, COLUMN_DEFMAXWIDTH},
- {IDS_DATE_ADDED, "mb_col_dateadded", 115, COLUMN_DEFMINWIDTH, COLUMN_DEFMAXWIDTH},
- {IDS_CLOUD, "mv_col_cloud", 27, COLUMN_DEFMINWIDTH, COLUMN_DEFMAXWIDTH},
- };
- //default column order
- static signed char defColumnOrderCloud[MAX_COLUMN_ORDER] =
- {
- MEDIAVIEW_COL_ARTIST,
- MEDIAVIEW_COL_ALBUM,
- MEDIAVIEW_COL_TRACK,
- MEDIAVIEW_COL_CLOUD,
- MEDIAVIEW_COL_TITLE,
- MEDIAVIEW_COL_LENGTH,
- MEDIAVIEW_COL_GENRE,
- MEDIAVIEW_COL_RATING,
- MEDIAVIEW_COL_PLAYCOUNT,
- MEDIAVIEW_COL_LASTPLAY,
- MEDIAVIEW_COL_YEAR,
- -1
- };
- static signed char defColumnOrder[MAX_COLUMN_ORDER] =
- {
- MEDIAVIEW_COL_ARTIST,
- MEDIAVIEW_COL_ALBUM,
- MEDIAVIEW_COL_TRACK,
- MEDIAVIEW_COL_TITLE,
- MEDIAVIEW_COL_LENGTH,
- MEDIAVIEW_COL_GENRE,
- MEDIAVIEW_COL_RATING,
- MEDIAVIEW_COL_PLAYCOUNT,
- MEDIAVIEW_COL_LASTPLAY,
- MEDIAVIEW_COL_YEAR,
- -1
- };
- static signed char columnOrder[MAX_COLUMN_ORDER];
- int WCSCMP_NULLOK(const wchar_t *pa, const wchar_t *pb)
- {
- if (!pa) pa = L"";
- else SKIP_THE_AND_WHITESPACEW(pa)
- if (!pb) pb = L"";
- else SKIP_THE_AND_WHITESPACEW(pb)
- return CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE /*| NORM_IGNORENONSPACE*/, pa, -1, pb, -1) - 2;
- // return lstrcmpi(pa, pb);
- }
- int FLOATWCMP_NULLOK(const wchar_t *pa, const wchar_t *pb)
- {
- if (pa) SKIP_THE_AND_WHITESPACEW(pa)
- if (pb) SKIP_THE_AND_WHITESPACEW(pb)
- if ((!pa || !*pa) && (!pb || !*pb))
- return 0;
- if (!pa || !*pa)
- return 1;
- if (!pb || !*pb)
- return -1;
- _locale_t C_locale = WASABI_API_LNG->Get_C_NumericLocale();
- float a = (float)_wtof_l(pa,C_locale);
- float b = (float)_wtof_l(pb,C_locale);
- if (a > b)
- return 1;
- else if (a < b)
- return -1;
- else
- return 0;
- }
- typedef struct
- {
- resultsniff_funcW cb;
- int user32;
- }
- bgThreadParms;
- static int bg_total_len_s;
- static __int64 bg_total_len_bytes;
- static LARGE_INTEGER querytime;
- static HMENU rate_hmenu = NULL;
- static HMENU cloud_hmenu = NULL;
- static HMENU sendto_hmenu = NULL;
- static librarySendToMenuStruct s;
- static RATINGCOLUMN ratingColumn;
- static WCHAR ratingBackText[128];
- #define IDC_LIST2HEADER 2001 // WM_INITDIALOG assign this is to the IDC_LIST2 header
- // internal messages
- #define IM_SYNCHEADERORDER (WM_USER + 0xFFF0)
- static DWORD WINAPI bgThreadQueryProc(void *tmp)
- {
- bgThreadParms *p = (bgThreadParms*)tmp;
- bg_total_len_s = 0;
- bg_total_len_bytes = 0;
- LARGE_INTEGER starttime, endtime;
- QueryPerformanceCounter(&starttime);
- bg_total_len_s = saveQueryToListW(g_view_metaconf, m_media_scanner, &itemCache,
- &cloudFiles, &cloudUploading, p->cb, p->user32,
- &bgThread_Kill, &bg_total_len_bytes);
- QueryPerformanceCounter(&endtime);
- querytime.QuadPart = endtime.QuadPart - starttime.QuadPart;
- if (!bgThread_Kill) PostMessage(m_hwnd, WM_APP + 3, 0x69, 0);
- return 0;
- }
- void bgQuery_Stop() // exported for other people to call since it is useful (eventually
- // we should have bgQuery pass the new query info along but I'll do that soon)
- {
- if (bgThread_Handle)
- {
- bgThread_Kill = 1;
- WaitForSingleObject(bgThread_Handle, INFINITE);
- CloseHandle(bgThread_Handle);
- bgThread_Handle = 0;
- }
- KillTimer(m_hwnd, 123);
- }
- static void bgQuery(resultsniff_funcW cb = 0, int user32 = 0) // only internal used
- {
- bgQuery_Stop();
- SetDlgItemTextW(m_hwnd, IDC_MEDIASTATUS, WASABI_API_LNGSTRINGW(IDS_SCANNING));
- StringCchCopyW(oldText, 4096, WASABI_API_LNGSTRINGW(IDS_SCANNING));
- SetTimer(m_hwnd, 123, 200, NULL);
- DWORD id;
- static bgThreadParms parms;
- parms.cb = cb;
- parms.user32 = user32;
- bgThread_Kill = 0;
- bgThread_Handle = CreateThread(NULL, 0, bgThreadQueryProc, (LPVOID) & parms, 0, &id);
- }
- // this thing does not produce a fully valid itemRecordList. be afraid.
- static void copyFilesToItemCacheW(itemRecordListW *obj)
- {
- if (bgThread_Handle) return ;
- int cnt = itemCache.Size;
- int i, l = cnt;
- cnt = 0;
- for (i = 0;i < l;i++)
- {
- if (resultlist.GetSelected(i)) cnt++;
- }
- obj->Alloc = obj->Size = 0;
- if (!cnt) return ;
- allocRecordList(obj, cnt, 0);
- if (!obj->Items)
- {
- obj->Size = obj->Alloc = 0;
- return ;
- }
- for (i = 0; i < itemCache.Size; i ++)
- {
- if (resultlist.GetSelected(i))
- {
- obj->Items[obj->Size++] = itemCache.Items[i];
- // makes sure that we are providing filesize in kb as
- // per spec even if we store it as __int64 internally
- obj->Items[obj->Size-1].filesize /= 1024;
- }
- }
- }
- void playFiles(int enqueue, int all)
- {
- if (bgThread_Handle) return ;
- int cnt = 0;
- int l = itemCache.Size;
- int foo_all = 0; // all but play the only selected
- int foo_selected = -1;
- if (!enqueue && !all && g_config->ReadInt(L"viewplaymode", 1))
- {
- int selcnt = 0;
- for (int i = 0;i < l;i++)
- {
- if (resultlist.GetSelected(i)) selcnt++;
- }
- if (selcnt == 1)
- {
- foo_all = -1;
- }
- }
- for (int i = 0;i < l;i++)
- {
- if (foo_all || all || resultlist.GetSelected(i))
- {
- if (foo_all && foo_selected < 0 && resultlist.GetSelected(i)) foo_selected = i;
- if (!cnt)
- {
- if (!enqueue) SendMessage(plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_DELETE);
- cnt++;
- }
- wchar_t title[2048] = {0};
- TAG_FMT_EXT(itemCache.Items[i].filename, itemrecordWTagFunc, ndeTagFuncFree, (void*)&itemCache.Items[i], title, 2048, 0);
- enqueueFileWithMetaStructW s;
- s.filename = itemCache.Items[i].filename;
- s.title = title;
- s.ext = NULL;
- s.length = itemCache.Items[i].length;
- #ifndef _DEBUG
- ndestring_retain(itemCache.Items[i].filename);
- SendMessage(plugin.hwndWinampParent, WM_WA_IPC, (WPARAM)&s, IPC_PLAYFILEW_NDE);
- #else
- SendMessage(plugin.hwndWinampParent, WM_WA_IPC, (WPARAM)&s, IPC_PLAYFILEW);
- #endif
- }
- }
- if (cnt)
- {
- if (foo_selected >= 0)
- {
- SendMessage(plugin.hwndWinampParent, WM_WA_IPC, foo_selected, IPC_SETPLAYLISTPOS);
- SendMessage(plugin.hwndWinampParent, WM_COMMAND, 40047, 0); // stop button, literally
- SendMessage(plugin.hwndWinampParent, WM_COMMAND, 40045, 0); // play button, literally
- }
- else if (!enqueue) SendMessage(plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_STARTPLAY);
- }
- }
- // out can never be bigger than in+1
- 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 != ' ' && c != '\t' && c != '\"')
- {
- neednull = 1;
- *out++ = c;
- }
- else if (c == '\"')
- {
- inquotes = !inquotes;
- if (!inquotes)
- {
- *out++ = 0;
- neednull = 0;
- }
- }
- else
- {
- if (inquotes) *out++ = c;
- else if (neednull)
- {
- *out++ = 0;
- neednull = 0;
- }
- }
- }
- *out++ = 0;
- *out++ = 0;
- }
- void makeQueryStringFromText(GayStringW *query, wchar_t *text, int nf)
- {
- int ispar = 0;
- if (query->Get()[0])
- {
- ispar = 1;
- query->Append(L"&(");
- }
- if (!_wcsnicmp(text, L"query:", 6))
- query->Append(text + 6); // copy the query as is
- else if (text[0] == L'?')
- query->Append(text + 1);
- else
- {
- int isAny = 0;
- if (*text == L'*' && text[1] == L' ')
- {
- isAny = 1;
- text += 2;
- }
- wchar_t tmpbuf[2048 + 32] = {0};
- parsequicksearch(tmpbuf, text);
- int x;
- wchar_t *fields[] =
- {
- L"filename",
- L"title",
- L"artist",
- L"album",
- L"genre",
- L"albumartist",
- L"publisher",
- L"composer",
- };
- wchar_t *p = tmpbuf;
- while (p && *p)
- {
- size_t lenp = wcslen(p);
- if (p == tmpbuf) query->Append(L"(");
- else if (isAny) query->Append(L")|(");
- else query->Append(L")&(");
- if (p[0] == L'<' && p[wcslen(p) - 1] == L'>' && wcslen(p) > 2)
- {
- wchar_t *op = p;
- while (op && *op)
- {
- if (*op == L'\'') *op = L'\"';
- op++;
- }
- p[lenp - 1] = 0; // remove >
- query->Append(p + 1);
- }
- else
- {
- for (x = 0; x < (int)min(sizeof(fields) / sizeof(fields[0]), nf); x ++)
- {
- wchar_t *field = fields[x];
- if (x) query->Append(L"|");
- query->Append(field);
- query->Append(L" HAS \"");
- GayStringW escaped;
- queryStrEscape(p, escaped);
- query->Append(escaped.Get());
- query->Append(L"\"");
- }
- }
- p += lenp + 1;
- }
- query->Append(L")");
- }
- if (ispar) query->Append(L")");
- }
- static void doQuery(HWND hwndDlg, wchar_t *text, int dobg = 1)
- {
- bgQuery_Stop();
- GayStringW query;
- if (text[0]) makeQueryStringFromText(&query, text);
- wchar_t *parent_query = NULL;
- extern wchar_t* m_query;
- parent_query = m_query;
- SendMessage(GetParent(hwndDlg), WM_APP + 2, 0, (LPARAM)&parent_query);
- GayStringW q;
- if (parent_query && parent_query[0])
- {
- q.Set(L"(");
- q.Append(parent_query);
- q.Append(L")");
- }
- if (query.Get() && query.Get()[0])
- {
- if (q.Get()[0])
- {
- q.Append(L" & (");
- q.Append(query.Get());
- q.Append(L")");
- }
- else q.Set(query.Get());
- }
- EnterCriticalSection(&g_db_cs);
- NDE_Scanner_Query(m_media_scanner, q.Get());
- LeaveCriticalSection(&g_db_cs);
- if (dobg) bgQuery();
- }
- static void RecycleSelectedItems()
- {
- int totalItems = resultlist.GetSelectedCount();
- if (!totalItems)
- return ;
- SHFILEOPSTRUCTW fileOp;
- fileOp.hwnd = m_hwnd;
- fileOp.wFunc = FO_DELETE;
- fileOp.pFrom = 0;
- fileOp.pTo = 0;
- fileOp.fFlags = SendMessage(plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_USES_RECYCLEBIN) ? FOF_ALLOWUNDO : 0;
- fileOp.fAnyOperationsAborted = 0;
- fileOp.hNameMappings = 0;
- fileOp.lpszProgressTitle = 0;
- EnterCriticalSection(&g_db_cs);
- nde_scanner_t s = NDE_Table_CreateScanner(g_table);
- int cchLen = totalItems * (MAX_PATH + 1) + 1;
- wchar_t *files = new wchar_t[cchLen]; // need room for each file name, null terminated. then have to null terminate the whole list
- if (files) // if malloc succeeded
- {
- wchar_t *curFile = files;
- for (int i = 0; i < itemCache.Size; i++)
- {
- if (resultlist.GetSelected(i))
- {
- if (NDE_Scanner_LocateNDEFilename(s, MAINTABLE_ID_FILENAME, FIRST_RECORD, itemCache.Items[i].filename))
- {
- StringCchCopyW(curFile, cchLen, itemCache.Items[i].filename);
- curFile += wcslen(itemCache.Items[i].filename) + 1;
- }
- }
- }
- if (curFile != files)
- {
- curFile[0] = 0; // null terminate
- fileOp.pFrom = files;
- fileOp.fAnyOperationsAborted = 0;
- if (SHFileOperationW(&fileOp))
- {
- wchar_t title[64] = {0};
- MessageBoxW(m_hwnd, WASABI_API_LNGSTRINGW(IDS_ERROR_DELETING_FILES),
- WASABI_API_LNGSTRINGW_BUF(IDS_ERROR,title,64), MB_OK);
- }
- else
- {
- // only remove items if deletion was allowed
- if (!fileOp.fAnyOperationsAborted)
- {
- for (int j = 0; j < itemCache.Size; j++)
- {
- if (resultlist.GetSelected(j))
- {
- if (NDE_Scanner_LocateNDEFilename(s, MAINTABLE_ID_FILENAME, FIRST_RECORD, itemCache.Items[j].filename))
- {
- // Wasabi callback event for pre remove
- WASABI_API_SYSCB->syscb_issueCallback(api_mldb::SYSCALLBACK, api_mldb::MLDB_FILE_REMOVED_PRE, (size_t)itemCache.Items[j].filename, 0);
-
- NDE_Scanner_Delete(s);
- NDE_Scanner_Post(s);
- g_table_dirty++;
-
- // Wasabi callback event for post remove
- // ToDo: (BigG) Move outside of critical section somehow
- WASABI_API_SYSCB->syscb_issueCallback(api_mldb::SYSCALLBACK, api_mldb::MLDB_FILE_REMOVED_POST, (size_t)itemCache.Items[j].filename, 0);
- }
- }
- }
- }
- }
- }
- delete [] files;
- }
- else // if malloc failed ... maybe because there's too many items.
- {
- files = new wchar_t[MAX_PATH + 1 + 1]; // double null termination
- if (!files) // if this malloc failed, just bail out
- {
- NDE_Table_DestroyScanner(g_table, s);
- LeaveCriticalSection(&g_db_cs);
- return ;
- }
- fileOp.pFrom = files;
- for (int i = 0;i < itemCache.Size;i++)
- {
- if (resultlist.GetSelected(i))
- {
- if (NDE_Scanner_LocateNDEFilename(s, MAINTABLE_ID_FILENAME, FIRST_RECORD, itemCache.Items[i].filename))
- {
- StringCchCopyW(files, MAX_PATH + 1 + 1, itemCache.Items[i].filename);
- files[wcslen(itemCache.Items[i].filename) + 1] = 0; // double null terminate
- fileOp.fAnyOperationsAborted = 0;
- if (SHFileOperationW(&fileOp))
- {
- wchar_t mes[4096] = {0};
- StringCchPrintfW(mes, 4096, WASABI_API_LNGSTRINGW(IDS_ERROR_DELETING_X), files);
- MessageBoxW(m_hwnd, mes, WASABI_API_LNGSTRINGW(IDS_ERROR), MB_OK);
- continue;
- }
- if (!fileOp.fAnyOperationsAborted)
- {
- // Wasabi callback event for pre remove
- WASABI_API_SYSCB->syscb_issueCallback(api_mldb::SYSCALLBACK, api_mldb::MLDB_FILE_REMOVED_PRE, (size_t)itemCache.Items[i].filename, 0);
-
- NDE_Scanner_Delete(s);
- NDE_Scanner_Post(s);
- g_table_dirty++;
- // Wasabi callback event for post remove
- // ToDo: (BigG) Move outside of critical section somehow
- WASABI_API_SYSCB->syscb_issueCallback(api_mldb::SYSCALLBACK, api_mldb::MLDB_FILE_REMOVED_POST, (size_t)itemCache.Items[i].filename, 0);
- }
- }
- }
- delete files;
- }
- }
- NDE_Table_DestroyScanner(g_table, s);
- if (g_table_dirty) NDE_Table_Sync(g_table);
- g_table_dirty = 0;
- LeaveCriticalSection(&g_db_cs);
- resultlist.Clear();
- emptyRecordList(&itemCache);
- // this might be gay, refreshing it completely (i.e. the cursor pos gets put back to normal, etc),
- // but really it is necessary for the view to be accurate.
- SendMessage(m_hwnd, WM_APP + 1, 0, 0); //refresh current view
- }
- static void removeSelectedItems(int physical)
- {
- if (physical)
- {
- RecycleSelectedItems();
- return ;
- }
- int hasdel = 0;
- EnterCriticalSection(&g_db_cs);
- nde_scanner_t s = NDE_Table_CreateScanner(g_table);
- for (int i = 0;i < itemCache.Size;i++)
- {
- if (resultlist.GetSelected(i))
- {
- if (NDE_Scanner_LocateNDEFilename(s, MAINTABLE_ID_FILENAME, FIRST_RECORD, itemCache.Items[i].filename))
- {
- wchar_t conf[32] = {0};
- if (!hasdel && MessageBoxW(m_hwnd, WASABI_API_LNGSTRINGW(IDS_SURE_YOU_WANT_TO_REMOVE_SELECTED_FROM_LIBRARY),
- WASABI_API_LNGSTRINGW_BUF(IDS_CONFIRMATION,conf,32), MB_YESNO | MB_ICONQUESTION) != IDYES)
- {
- NDE_Table_DestroyScanner(g_table, s);
- LeaveCriticalSection(&g_db_cs);
- return ;
- //FUCKO> need to eat the RETURN msg
- //MSG msg;
- //while(PeekMessage(&msg,m_hwnd,WM_COMMAND,WM_COMMAND,1));
- }
- if (!hasdel) // stop any background queries
- {
- bgQuery_Stop();
- }
- // Wasabi callback event for pre remove
- WASABI_API_SYSCB->syscb_issueCallback(api_mldb::SYSCALLBACK, api_mldb::MLDB_FILE_REMOVED_PRE, (size_t)itemCache.Items[i].filename, 0);
-
- hasdel = 1;
- NDE_Scanner_Delete(s);
- NDE_Scanner_Post(s);
- g_table_dirty++;
- // Wasabi callback event for post remove
- // ToDo: (BigG) Move this outside of the critical section
- WASABI_API_SYSCB->syscb_issueCallback(api_mldb::SYSCALLBACK, api_mldb::MLDB_FILE_REMOVED_POST, (size_t)itemCache.Items[i].filename, 0);
- }
- }
- }
- NDE_Table_DestroyScanner(g_table, s);
- if (g_table_dirty) NDE_Table_Sync(g_table);
- g_table_dirty = 0;
- LeaveCriticalSection(&g_db_cs);
- if (!hasdel) return ;
- resultlist.Clear();
- emptyRecordList(&itemCache);
- // this might be gay, refreshing it completely (i.e. the cursor pos gets put back to normal, etc),
- // but really it is necessary for the view to be accurate.
- SendMessage(m_hwnd, WM_APP + 1, 0, 0); //refresh current view
- }
- static void exploreItemFolder(HWND hwndDlg)
- {
- if (resultlist.GetSelectionMark() >= 0)
- {
- int l=resultlist.GetCount();
- for(int i=0;i<l;i++)
- {
- if (resultlist.GetSelected(i))
- {
- WASABI_API_EXPLORERFINDFILE->AddFile(itemCache.Items[i].filename);
- }
- }
- WASABI_API_EXPLORERFINDFILE->ShowFiles();
- }
- }
- static void removeDeadFiles(HWND hwndDlg)
- {
- Scan_RemoveFiles(hwndDlg);
- // this might be gay, refreshing it completely (i.e. the cursor pos gets put back to normal, etc),
- // but really it is necessary for the view to be accurate.
- SendMessage(m_hwnd, WM_APP + 1, 0, 0); //refresh current view
- }
- static WNDPROC search_oldWndProc;
- static DWORD WINAPI search_newWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- if (uMsg == WM_KEYDOWN && wParam == VK_DOWN)
- {
- PostMessageW(GetParent(hwndDlg), WM_NEXTDLGCTL, (WPARAM)resultlist.getwnd(), (LPARAM)TRUE);
- ListView_SetItemState(resultlist.getwnd(), 0, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED);
- }
- return CallWindowProcW(search_oldWndProc, hwndDlg, uMsg, wParam, lParam);
- }
- typedef struct _LAYOUT
- {
- INT id;
- HWND hwnd;
- INT x;
- INT y;
- INT cx;
- INT cy;
- DWORD flags;
- HRGN rgn;
- }
- LAYOUT, PLAYOUT;
- #define SETLAYOUTPOS(_layout, _x, _y, _cx, _cy) { _layout->x=_x; _layout->y=_y;_layout->cx=_cx;_layout->cy=_cy;_layout->rgn=NULL; }
- #define SETLAYOUTFLAGS(_layout, _r) \
- { \
- BOOL fVis; \
- fVis = (WS_VISIBLE & (LONG)GetWindowLongPtr(_layout->hwnd, GWL_STYLE)); \
- if (_layout->x == _r.left && _layout->y == _r.top) _layout->flags |= SWP_NOMOVE; \
- if (_layout->cx == (_r.right - _r.left) && _layout->cy == (_r.bottom - _r.top)) _layout->flags |= SWP_NOSIZE; \
- if ((SWP_HIDEWINDOW & _layout->flags) && !fVis) _layout->flags &= ~SWP_HIDEWINDOW; \
- if ((SWP_SHOWWINDOW & _layout->flags) && fVis) _layout->flags &= ~SWP_SHOWWINDOW; \
- }
- #define LAYOUTNEEEDUPDATE(_layout) ((SWP_NOMOVE | SWP_NOSIZE) != ((SWP_NOMOVE | SWP_NOSIZE | SWP_HIDEWINDOW | SWP_SHOWWINDOW) & _layout->flags))
- #define GROUP_MIN 0x1
- #define GROUP_MAX 0x3
- #define GROUP_SEARCH 0x1
- #define GROUP_STATUSBAR 0x2
- #define GROUP_MAIN 0x3
- static void LayoutWindows(HWND hwnd, BOOL fRedraw, BOOL fUpdateAll = FALSE)
- {
- static INT controls[] =
- {
- GROUP_SEARCH, IDC_SEARCHCAPTION, IDC_CLEAR, IDC_QUICKSEARCH,
- GROUP_STATUSBAR, IDC_BUTTON_PLAY, IDC_BUTTON_ENQUEUE, IDC_BUTTON_MIX, IDC_BUTTON_CREATEPLAYLIST, IDC_BUTTON_INFOTOGGLE, IDC_MIXABLE, IDC_MEDIASTATUS,
- GROUP_MAIN, IDC_LIST2
- };
- INT index;
- RECT rc, rg, ri;
- LAYOUT layout[sizeof(controls)/sizeof(controls[0])], *pl;
- BOOL skipgroup;
- HRGN rgn = NULL;
- GetClientRect(hwnd, &rc);
- if (rc.bottom == rc.top || rc.right == rc.left) return;
- SetRect(&rg, rc.left, rc.top, rc.right, rc.bottom);
- pl = layout;
- skipgroup = FALSE;
- InvalidateRect(hwnd, NULL, TRUE);
- for (index = 0; index < sizeof(controls) / sizeof(*controls); index++)
- {
- if (controls[index] >= GROUP_MIN && controls[index] <= GROUP_MAX) // group id
- {
- skipgroup = FALSE;
- switch (controls[index])
- {
- case GROUP_SEARCH:
- if (g_displaysearch)
- {
- wchar_t buffer[128] = {0};
- HWND ctrl = GetDlgItem(hwnd, IDC_CLEAR);
- GetWindowTextW(ctrl, buffer, ARRAYSIZE(buffer));
- LRESULT idealSize = MLSkinnedButton_GetIdealSize(ctrl, buffer);
- SetRect(&rg, rc.left,
- rc.top + WASABI_API_APP->getScaleY(2),
- rc.right - WASABI_API_APP->getScaleX(2),
- rc.top + WASABI_API_APP->getScaleY(HIWORD(idealSize)+1));
- rc.top = rg.bottom + WASABI_API_APP->getScaleY(3);
- }
- skipgroup = !g_displaysearch;
- break;
- case GROUP_STATUSBAR:
- if (g_displaycontrols)
- {
- wchar_t buffer[128] = {0};
- HWND ctrl = GetDlgItem(hwnd, IDC_BUTTON_PLAY);
- GetWindowTextW(ctrl, buffer, ARRAYSIZE(buffer));
- LRESULT idealSize = MLSkinnedButton_GetIdealSize(ctrl, buffer);
- SetRect(&rg, rc.left + WASABI_API_APP->getScaleX(1),
- rc.bottom - WASABI_API_APP->getScaleY(HIWORD(idealSize)),
- rc.right, rc.bottom);
- rc.bottom = rg.top - WASABI_API_APP->getScaleY(3);
- }
- skipgroup = !g_displaycontrols;
- break;
- case GROUP_MAIN:
- SetRect(&rg, rc.left + WASABI_API_APP->getScaleX(1), rc.top, rc.right, rc.bottom);
- break;
- }
- continue;
- }
- if (skipgroup) continue;
- pl->id = controls[index];
- pl->hwnd = GetDlgItem(hwnd, pl->id);
- if (!pl->hwnd) continue;
- GetWindowRect(pl->hwnd, &ri);
- MapWindowPoints(HWND_DESKTOP, hwnd, (LPPOINT)&ri, 2);
- pl->flags = SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW | SWP_NOCOPYBITS;
- switch (pl->id)
- {
- case IDC_SEARCHCAPTION:
- {
- wchar_t buffer[128] = {0};
- GetWindowTextW(pl->hwnd, buffer, ARRAYSIZE(buffer));
- LRESULT idealSize = MLSkinnedStatic_GetIdealSize(pl->hwnd, buffer);
- SETLAYOUTPOS(pl, rg.left + WASABI_API_APP->getScaleX(2),
- rg.top + WASABI_API_APP->getScaleY(1),
- WASABI_API_APP->getScaleX(LOWORD(idealSize)),
- (rg.bottom - rg.top));
- rg.left += (pl->cx + WASABI_API_APP->getScaleX(4));
- break;
- }
- case IDC_CLEAR:
- {
- wchar_t buffer[128] = {0};
- GetWindowTextW(pl->hwnd, buffer, ARRAYSIZE(buffer));
- LRESULT idealSize = MLSkinnedButton_GetIdealSize(pl->hwnd, buffer);
- LONG width = LOWORD(idealSize) + WASABI_API_APP->getScaleX(6);
- pl->flags |= (((rg.right - rg.left) - width) > WASABI_API_APP->getScaleX(40)) ? SWP_SHOWWINDOW : SWP_HIDEWINDOW ;
- SETLAYOUTPOS(pl, rg.right - width, rg.top, width, rg.bottom - rg.top);
- if (SWP_SHOWWINDOW & pl->flags) rg.right -= (pl->cx + WASABI_API_APP->getScaleX(4));
- break;
- }
- case IDC_QUICKSEARCH:
- pl->flags |= (rg.right > rg.left) ? SWP_SHOWWINDOW : SWP_HIDEWINDOW;
- SETLAYOUTPOS(pl, rg.left, rg.top, rg.right - rg.left - WASABI_API_APP->getScaleX(1),
- (rg.bottom - rg.top) - WASABI_API_APP->getScaleY(1));
- break;
- case IDC_BUTTON_PLAY:
- case IDC_BUTTON_ENQUEUE:
- case IDC_BUTTON_MIX:
- case IDC_BUTTON_CREATEPLAYLIST:
- if (IDC_BUTTON_MIX != pl->id || customAllowed)
- {
- if (groupBtn && pl->id == IDC_BUTTON_PLAY && enqueuedef == 1)
- {
- pl->flags |= SWP_HIDEWINDOW;
- break;
- }
- if (groupBtn && pl->id == IDC_BUTTON_ENQUEUE && enqueuedef != 1)
- {
- pl->flags |= SWP_HIDEWINDOW;
- break;
- }
- if (groupBtn && (pl->id == IDC_BUTTON_PLAY || pl->id == IDC_BUTTON_ENQUEUE) && customAllowed)
- {
- pl->flags |= SWP_HIDEWINDOW;
- break;
- }
- if (pl->id == IDC_BUTTON_CREATEPLAYLIST && !AGAVE_API_PLAYLIST_GENERATOR)
- {
- pl->flags |= SWP_HIDEWINDOW;
- break;
- }
- wchar_t buffer[128] = {0};
- GetWindowTextW(pl->hwnd, buffer, ARRAYSIZE(buffer));
- LRESULT idealSize = MLSkinnedButton_GetIdealSize(pl->hwnd, buffer);
- LONG width = LOWORD(idealSize) + WASABI_API_APP->getScaleX(6);
- SETLAYOUTPOS(pl, rg.left, rg.bottom - WASABI_API_APP->getScaleY(HIWORD(idealSize)),
- width, WASABI_API_APP->getScaleY(HIWORD(idealSize)));
- pl->flags |= ((rg.right - rg.left) > width) ? SWP_SHOWWINDOW : SWP_HIDEWINDOW;
- if (SWP_SHOWWINDOW & pl->flags) rg.left += (pl->cx + WASABI_API_APP->getScaleX(4));
- }
- else
- pl->flags |= SWP_HIDEWINDOW;
- break;
- case IDC_BUTTON_INFOTOGGLE:
- switch (SendMessage(GetParent(hwnd), WM_USER + 66, 0, 0))
- {
- case 0xFF:
- case 0xF0:
- {
- wchar_t buffer[128] = {0};
- GetWindowTextW(pl->hwnd, buffer, ARRAYSIZE(buffer));
- LRESULT idealSize = MLSkinnedButton_GetIdealSize(pl->hwnd, buffer);
- LONG width = LOWORD(idealSize) + WASABI_API_APP->getScaleX(6);
- pl->flags |= (((rg.right - rg.left) - (ri.right - ri.left)) > WASABI_API_APP->getScaleX(60)) ? SWP_SHOWWINDOW : SWP_HIDEWINDOW ;
- SETLAYOUTPOS(pl, rg.right - width - WASABI_API_APP->getScaleX(2),
- rg.top, width, (rg.bottom - rg.top));
- if (SWP_SHOWWINDOW & pl->flags) rg.right -= (pl->cx + WASABI_API_APP->getScaleX(4));
- break;
- }
- }
- break;
- case IDC_MIXABLE:
- if (predixisExist & 1)
- {
- SETLAYOUTPOS(pl, rg.right - (ri.right - ri.left), rg.top, (ri.right - ri.left), (rg.bottom - rg.top));
- pl->flags |= ((rg.right - rg.left) - (ri.right - ri.left) > WASABI_API_APP->getScaleX(60)) ? SWP_SHOWWINDOW : SWP_HIDEWINDOW;
- if (SWP_SHOWWINDOW & pl->flags) rg.right -= (pl->cx + WASABI_API_APP->getScaleX(4));
- }
- break;
- case IDC_MEDIASTATUS:
- SETLAYOUTPOS(pl, rg.left, rg.top, rg.right - rg.left, (rg.bottom - rg.top));
- pl->flags |= (pl->cx > WASABI_API_APP->getScaleX(16)) ? SWP_SHOWWINDOW : SWP_HIDEWINDOW;
- break;
- case IDC_LIST2:
- SETLAYOUTPOS(pl, rg.left, rg.top + 1, (rg.right - rg.left) - WASABI_API_APP->getScaleX(3), (rg.bottom - rg.top) - WASABI_API_APP->getScaleY(2));
- break;
- }
- SETLAYOUTFLAGS(pl, ri);
- if (LAYOUTNEEEDUPDATE(pl))
- {
- if (SWP_NOSIZE == ((SWP_HIDEWINDOW | SWP_SHOWWINDOW | SWP_NOSIZE) & pl->flags) &&
- ri.left == (pl->x + offsetX) && ri.top == (pl->y + offsetY) && !fUpdateAll && IsWindowVisible(pl->hwnd))
- {
- SetRect(&ri, pl->x, pl->y, pl->cx + pl->x, pl->y + pl->cy);
- ValidateRect(hwnd, &ri);
- }
- pl++;
- }
- else if (!fUpdateAll && (fRedraw || (!offsetX && !offsetY)) && IsWindowVisible(pl->hwnd))
- {
- ValidateRect(hwnd, &ri);
- if (GetUpdateRect(pl->hwnd, NULL, FALSE))
- {
- if (!rgn) rgn = CreateRectRgn(0,0,0,0);
- GetUpdateRgn(pl->hwnd, rgn, FALSE);
- OffsetRgn(rgn, pl->x, pl->y);
- InvalidateRgn(hwnd, rgn, FALSE);
- }
- }
- }
- if (pl != layout)
- {
- LAYOUT *pc;
- HDWP hdwp = BeginDeferWindowPos((INT)(pl - layout));
- for (pc = layout; pc < pl && hdwp; pc++)
- {
- hdwp = DeferWindowPos(hdwp, pc->hwnd, NULL, pc->x, pc->y, pc->cx, pc->cy, pc->flags);
- }
- if (hdwp) EndDeferWindowPos(hdwp);
- if (!rgn) rgn = CreateRectRgn(0, 0, 0, 0);
- if (fRedraw)
- {
- GetUpdateRgn(hwnd, rgn, FALSE);
- for (pc = layout; pc < pl && hdwp; pc++)
- {
- if (pc->rgn)
- {
- OffsetRgn(pc->rgn, pc->x, pc->y);
- CombineRgn(rgn, rgn, pc->rgn, RGN_OR);
- }
- }
- RedrawWindow(hwnd, NULL, rgn, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASENOW | RDW_ALLCHILDREN);
- }
- if (g_rgnUpdate)
- {
- GetUpdateRgn(hwnd, g_rgnUpdate, FALSE);
- for (pc = layout; pc < pl && hdwp; pc++)
- {
- if (pc->rgn)
- {
- OffsetRgn(pc->rgn, pc->x, pc->y);
- CombineRgn(g_rgnUpdate, g_rgnUpdate, pc->rgn, RGN_OR);
- }
- }
- }
- for (pc = layout; pc < pl && hdwp; pc++)
- if (pc->rgn) DeleteObject(pc->rgn);
- }
- if (rgn) DeleteObject(rgn);
- ValidateRgn(hwnd, NULL);
- }
- static void updateInfoText(HWND hwndDlg, bool x = false)
- {
- int a = SendMessage(GetParent(hwndDlg), WM_USER + 66, x ? -1 : 0, 0);
- if (a == 0xff)
- SetDlgItemTextW(hwndDlg, IDC_BUTTON_INFOTOGGLE, WASABI_API_LNGSTRINGW(IDS_HIDE_INFO));
- else if (a == 0xf0)
- SetDlgItemTextW(hwndDlg, IDC_BUTTON_INFOTOGGLE, WASABI_API_LNGSTRINGW(IDS_SHOW_INFO));
- else ShowWindow(GetDlgItem(hwndDlg, IDC_BUTTON_INFOTOGGLE), SW_HIDE);
- }
- static void initColumnsHeader(HWND hwndList)
- {
- INT index, sortby;
- LVCOLUMNW lvc = {0, };
- if (!hwndList || !IsWindow(hwndList)) return;
- SendMessageW(hwndList, WM_SETREDRAW, FALSE, 0L);
- while (SendMessageW(hwndList, LVM_DELETECOLUMN, 0, 0L));
- sortby = g_view_metaconf->ReadInt(L"mv_sort_by", 1);
- lvc.mask = LVCF_TEXT | LVCF_WIDTH;
- lvc.pszText = L"";
- lvc.cx = 30;
- SendMessageW(hwndList, LVM_INSERTCOLUMNW, 0, (LPARAM)&lvc); // create dummy column
- // TODO set to a zero width if not available
- MLSkinnedHeader_SetCloudColumn(ListView_GetHeader(hwndList), -1); // reset the cloud status column so it'll be correctly removed
- SetPropW(hwndList, L"pmp_list_info", (HANDLE)-1);
- for (index = 0; columnOrder[index] != -1; index++)
- {
- headerColumn *cl = &columnList[columnOrder[index]];
- lvc.pszText = WASABI_API_LNGSTRINGW(cl->column_id);
- lvc.cx = g_view_metaconf->ReadInt(AutoWide(cl->config_name), cl->defWidth);
- if (lvc.cx < cl->minWidth) lvc.cx = cl->minWidth;
- // update position of the cloud column icon
- if (columnOrder[index] == MEDIAVIEW_COL_CLOUD)
- {
- if (!cloud_hinst || cloud_hinst == (HINSTANCE)1 ||
- !SendMessage(plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_GET_CLOUD_ACTIVE))
- {
- MLSkinnedHeader_SetCloudColumn(ListView_GetHeader(hwndList), -1);
- SetPropW(hwndList, L"pmp_list_info", (HANDLE)-1);
- lvc.cx = 0;
- }
- else
- {
- MLSkinnedHeader_SetCloudColumn(ListView_GetHeader(hwndList), index);
- SetPropW(hwndList, L"pmp_list_info", (HANDLE)index);
- lvc.cx = 27;
- MLCloudColumn_GetWidth(plugin.hwndLibraryParent, &lvc.cx);
- }
- }
- SendMessageW(hwndList, LVM_INSERTCOLUMNW, 0xFFFF, (LPARAM)&lvc);
-
- if (sortby == columnOrder[index]) MLSkinnedListView_DisplaySort(hwndList, index, !g_view_metaconf->ReadInt(L"mv_sort_dir", 0));
- }
- SendMessageW(hwndList, LVM_DELETECOLUMN, 0, 0L); // Delete dummy column
- for (index = 0; -1 != columnOrder[index] && MEDIAVIEW_COL_RATING != columnOrder[index]/* && MEDIAVIEW_COL_CLOUD != columnOrder[index]*/; index++);
- if (-1 != index) SendMessageW(hwndList, LVM_SETCOLUMNWIDTH, index, (LPARAM)SendMessageW(hwndList, LVM_GETCOLUMNWIDTH, index, 0L));
- SendMessageW(hwndList, WM_SETREDRAW, TRUE, 0L);
- }
- static int m_last_selitem = -1;
- static int m_bgupdinfoviewerflag;
- extern void add_to_library(HWND wndparent);
- static INT_PTR CALLBACK needAddFilesProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- switch (uMsg)
- {
- case WM_INITDIALOG:
- if (AGAVE_API_ITUNES_IMPORTER && AGAVE_API_ITUNES_IMPORTER->iTunesExists())
- EnableWindow(GetDlgItem(hwndDlg, IDC_IMPORT_ITUNES), TRUE);
- else
- EnableWindow(GetDlgItem(hwndDlg, IDC_IMPORT_ITUNES), FALSE);
-
- SetTimer(hwndDlg, 1, 1000, NULL);
- return 1;
- case WM_COMMAND:
- switch(LOWORD(wParam))
- {
- case IDOK:
- case IDCANCEL:
- if (BN_CLICKED == HIWORD(wParam))
- {
- if (IsDlgButtonChecked(hwndDlg, IDC_CHECK1)) g_config->WriteInt(L"noshowadddlg", 1);
- EndDialog(hwndDlg, 0);
- }
- break;
- case ID_ADD_FILES:
- if (BN_CLICKED == HIWORD(wParam))
- {
- add_to_library(hwndDlg);
- PostMessage(hwndDlg, WM_TIMER, 1, 0);
- }
- break;
- case IDC_IMPORT_ITUNES:
- if (BN_CLICKED == HIWORD(wParam))
- {
- if (AGAVE_API_ITUNES_IMPORTER)
- AGAVE_API_ITUNES_IMPORTER->ImportFromiTunes(hwndDlg);
- PostMessage(hwndDlg, WM_TIMER, 1, 0);
- if (m_curview_hwnd) PostMessage(m_curview_hwnd, WM_APP + 1, 0, 0); //update current view
- }
- break;
- case IDC_BTN_LINK_PROMO:
- if (BN_CLICKED == HIWORD(wParam)) ShellExecuteA(plugin.hwndWinampParent, "open", "https://help.winamp.com/hc/articles/8105244490772-Player-Overview", NULL, ".", 0);
- break;
- }
- break;
- case WM_TIMER:
- if (g_table && NDE_Table_GetRecordsCount(g_table))
- {
- wchar_t buf[512] = {0};
- StringCchPrintfW(buf, 512, WASABI_API_LNGSTRINGW(IDS_THERE_ARE_NOW_X_ITEMS_IN_THE_LIBRARY), NDE_Table_GetRecordsCount(g_table));
- SetDlgItemTextW(hwndDlg, IDC_TEXT, buf);
- SetDlgItemTextW(hwndDlg, ID_ADD_FILES, WASABI_API_LNGSTRINGW(IDS_ADD_MORE));
- }
- break;
- case WM_DRAWITEM:
- {
- DRAWITEMSTRUCT *di = (DRAWITEMSTRUCT *)lParam;
- if (di->CtlType == ODT_BUTTON)
- {
- wchar_t wt[123] = {0};
- int y;
- RECT r;
- HPEN hPen, hOldPen;
- DWORD style;
- GetDlgItemText(hwndDlg, (INT)wParam, wt, ARRAYSIZE(wt));
- style = (DWORD)GetWindowLongPtrW(di->hwndItem, GWL_STYLE);
- // draw text
- SetTextColor(di->hDC, (di->itemState & ODS_SELECTED) ? RGB(220, 0, 0) : RGB(0, 0, 220));
-
- memset(&r, 0, sizeof(r));
- DrawText(di->hDC, wt, -1, &r, DT_SINGLELINE | DT_CALCRECT);
-
- if (BS_RIGHT & style) r.left = max(di->rcItem.left+ 2, di->rcItem.right - r.right - 2);
- else if (BS_LEFT & style) r.left = di->rcItem.left+ 2;
- else r.left = ((di->rcItem.right - di->rcItem.left - 4) - r.right) / 2;
-
- if (r.left < di->rcItem.left + 2)
- {
- r.left = di->rcItem.left + 2;
- r.right = di->rcItem.right - 2;
- }
- else r.right += r.left;
- if (r.right > di->rcItem.right - 2) r.right = di->rcItem.right - 2;
-
- if (BS_TOP & style) r.top = di->rcItem.top;
- else if(BS_VCENTER & style) r.top = ((di->rcItem.bottom - di->rcItem.top - 2) - r.bottom) /2;
- else r.top = di->rcItem.bottom - 2 - r.bottom;
-
- if (r.top < di->rcItem.top)
- {
- r.top = di->rcItem.top;
- r.bottom = di->rcItem.bottom - 2;
- }
- else r.bottom += r.top;
- if (r.bottom > di->rcItem.bottom - 2) r.bottom = di->rcItem.bottom - 2;
- DrawText(di->hDC, wt, -1, &r, DT_SINGLELINE | DT_WORD_ELLIPSIS);
- // draw underline
- y = min(di->rcItem.bottom, r.bottom + 1);
- hPen = CreatePen(PS_SOLID, 0, (di->itemState & ODS_SELECTED) ? RGB(220, 0, 0) : RGB(0, 0, 220));
- hOldPen = (HPEN) SelectObject(di->hDC, hPen);
- MoveToEx(di->hDC, r.left, y, NULL);
- LineTo(di->hDC, r.right, y);
- SelectObject(di->hDC, hOldPen);
- DeleteObject(hPen);
- }
- }
- }
-
- return 0;
- };
- static void SetStatusText(HWND hwndStatus, LPCWSTR *ppsz, INT count)
- {
- WCHAR buffer[4096] = {0};
- if (0 == count || !ppsz)
- {
- SetWindowText(hwndStatus, L"");
- return;
- }
- buffer[0] = 0x00;
- for (int i = 0; i < count; i++)
- {
- StringCchCatW(buffer, 4096, ppsz[i]);
- StringCchCatW(buffer, 4096, L" ");
- }
- SetWindowTextW(hwndStatus, buffer);
- StringCchCopyW(oldText, 4096, buffer);
- }
- static void SetRating(UINT iItem, INT newRating, HWND hwndList)
- {
- if (0 == newRating) newRating = -1;
- if (iItem < (UINT)itemCache.Size)
- {
- if (g_table && newRating != itemCache.Items[iItem].rating)
- {
- EnterCriticalSection(&g_db_cs);
- nde_scanner_t s = NDE_Table_CreateScanner(g_table);
- if (NDE_Scanner_LocateNDEFilename(s, MAINTABLE_ID_FILENAME, FIRST_RECORD, itemCache.Items[iItem].filename))
- {
- NDE_Scanner_Edit(s);
- db_setFieldInt(s, MAINTABLE_ID_RATING, newRating);
- NDE_Scanner_Post(s);
- itemCache.Items[iItem].rating = newRating;
- if (g_config->ReadInt(L"writeratings", 0))
- {
- wchar_t buf[64] = {0};
- if (newRating > 0)
- {
- wsprintfW(buf, L"%d", newRating);
- }
- else
- buf[0] = 0;
- updateFileInfo(itemCache.Items[iItem].filename, DB_FIELDNAME_rating, buf);
- SendMessage(plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_WRITE_EXTENDED_FILE_INFO);
- }
- }
- NDE_Table_DestroyScanner(g_table, s);
- if (g_table_dirty)
- {
- g_table_dirty = 0;
- NDE_Table_Sync(g_table);
- }
- LeaveCriticalSection(&g_db_cs);
- }
- if (newRating == itemCache.Items[iItem].rating && hwndList)
- {
- ratingColumn.hwndList = hwndList;
- ratingColumn.iItem = iItem;
- ratingColumn.iSubItem = 600;
- MLRatingColumn_Animate(plugin.hwndLibraryParent, &ratingColumn);
- ListView_RedrawItems(resultlist.getwnd(), iItem, iItem);
- // TODO: benski> update the top panes w/o refreshing, if possible
- // CUT: PostMessage(GetParent(GetParent(hwndList)), WM_APP + 4, (WPARAM)newRating, (LPARAM)1);
- }
- }
- }
- /////////// Header Messages / Notifications
- static BOOL Header_OnItemChanging(HWND hwndDlg, NMHEADERW *phdr, LRESULT *pResult, UINT uMsg)
- {
- if (phdr->pitem && (HDI_WIDTH & phdr->pitem->mask))
- {
- INT test;
- test = columnList[columnOrder[phdr->iItem]].minWidth;
- if (phdr->pitem->cxy < test) phdr->pitem->cxy = test;
- test = columnList[columnOrder[phdr->iItem]].maxWidth;
- if (test != UNLIMITED_WIDTH && phdr->pitem->cxy > test) phdr->pitem->cxy = test;
- if (MEDIAVIEW_COL_RATING == columnOrder[phdr->iItem])
- {
- RATINGWIDTH rw;
- rw.fStyle = RCS_DEFAULT;
- rw.width = phdr->pitem->cxy;
- if (MLRatingColumn_GetWidth(plugin.hwndLibraryParent, &rw)) phdr->pitem->cxy = rw.width;
- if (0 == phdr->iItem)
- {
- RATINGBACKTEXT rbt;
- rbt.pszText = ratingBackText;
- rbt.cchTextMax = sizeof(ratingBackText)/sizeof(WCHAR);
- rbt.nColumnWidth = phdr->pitem->cxy;
- rbt.fStyle = RCS_DEFAULT;
- MLRatingColumn_FillBackString(plugin.hwndLibraryParent, &rbt);
- }
- else ratingBackText[0] = 0x00;
- }
- else if (MEDIAVIEW_COL_CLOUD == columnOrder[phdr->iItem])
- {
- if (!cloud_hinst || cloud_hinst == (HINSTANCE)1 ||
- !SendMessage(plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_GET_CLOUD_ACTIVE))
- phdr->pitem->cxy = 0;
- else
- {
- INT width = phdr->pitem->cxy;
- if (MLCloudColumn_GetWidth(plugin.hwndLibraryParent, &width))
- {
- phdr->pitem->cxy = width;
- }
- }
- }
- }
- return FALSE;
- }
- static BOOL Header_OnEndDrag(HWND hwndDlg, NMHEADERW *phdr, LRESULT *pResult)
- {
- PostMessageW(hwndDlg, IM_SYNCHEADERORDER, 0, (LPARAM)phdr->hdr.hwndFrom);
- return FALSE;
- }
- static BOOL Header_OnRightClick(HWND hwndDlg, NMHDR *pnmh, LRESULT *pResult)
- {
- HMENU menu = GetSubMenu(g_context_menus, 4);
- POINT p;
- GetCursorPos(&p);
- int r = DoTrackPopup(menu, TPM_RETURNCMD | TPM_RIGHTBUTTON | TPM_LEFTBUTTON, p.x, p.y, hwndDlg, NULL);
- switch (r)
- {
- case ID_HEADERWND_CUSTOMIZECOLUMNS:
- customizeColumnsDialog(hwndDlg);
- break;
- }
- return FALSE;
- }
- /////////// ListView Messages / Notifications
- static BOOL ListView_OnItemChanged(HWND hwndDlg, NMLISTVIEW *pnmv)
- {
- if (pnmv->uNewState & LVIS_SELECTED)
- {
- //if (GetFocus()==resultlist.getwnd())
- {
- m_last_selitem = pnmv->iItem;
- KillTimer(hwndDlg, 6600);
- SetTimer(hwndDlg, 6600, 250, NULL);
- }
- }
- else
- {
- if (isMixablePresent)
- {
- SetDlgItemText(hwndDlg, IDC_MIXABLE, L"");
- isMixablePresent = false;
- }
- }
- return FALSE;
- }
- static BOOL ListView_OnDoubleClick(HWND hwndDlg, NMITEMACTIVATE *pnmitem)
- {
- playFiles((!!g_config->ReadInt(L"enqueuedef", 0)) ^(!!(GetAsyncKeyState(VK_SHIFT)&0x8000)), 0);
- return FALSE;
- }
- void EatKeyboard()
- {
- Sleep(100);
- MSG msg;
- while (PeekMessage(&msg, NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE)); //eat return
- }
- static void Dialog_OnContextMenu(HWND hwndDlg, HWND hwndFrom, int x, int y)
- {
- if (hwndFrom != resultlist.getwnd())
- return;
- POINT pt = {x,y};
- if (x == -1 || y == -1) // x and y are -1 if the user invoked a shift-f10 popup menu
- {
- RECT itemRect = {0};
- int selected = resultlist.GetNextSelected();
- if (selected != -1) // if something is selected we'll drop the menu from there
- {
- resultlist.GetItemRect(selected, &itemRect);
- ClientToScreen(resultlist.getwnd(), (POINT *)&itemRect);
- }
- else // otherwise we'll drop it from the top-left corner of the listview, adjusting for the header location
- {
- GetWindowRect(resultlist.getwnd(), &itemRect);
- HWND hHeader = (HWND)SNDMSG(resultlist.getwnd(), LVM_GETHEADER, 0, 0L);
- RECT headerRect;
- if ((WS_VISIBLE & GetWindowLongPtr(hHeader, GWL_STYLE)) && GetWindowRect(hHeader, &headerRect))
- {
- itemRect.top += (headerRect.bottom - headerRect.top);
- }
- }
- x = itemRect.left;
- y = itemRect.top;
- }
- HWND hHeader = (HWND)SNDMSG(resultlist.getwnd(), LVM_GETHEADER, 0, 0L);
- RECT headerRect;
- if (0 == (WS_VISIBLE & GetWindowLongPtr(hHeader, GWL_STYLE)) || FALSE == GetWindowRect(hHeader, &headerRect))
- {
- SetRectEmpty(&headerRect);
- }
- if (FALSE != PtInRect(&headerRect, pt))
- {
- return;
- }
- HMENU globmenu = WASABI_API_LOADMENU(IDR_CONTEXTMENUS);
- HMENU menu = GetSubMenu(globmenu, 0);
- int rate_idx = 9;
- sendto_hmenu = GetSubMenu(menu, 2);
- rate_hmenu = GetSubMenu(menu, rate_idx);
- ConvertRatingMenuStar(rate_hmenu, ID_RATE_5);
- ConvertRatingMenuStar(rate_hmenu, ID_RATE_4);
- ConvertRatingMenuStar(rate_hmenu, ID_RATE_3);
- ConvertRatingMenuStar(rate_hmenu, ID_RATE_2);
- ConvertRatingMenuStar(rate_hmenu, ID_RATE_1);
- s.mode = 0;
- s.hwnd = 0;
- s.build_hMenu = 0;
- IPC_LIBRARY_SENDTOMENU = SendMessage(plugin.hwndWinampParent, WM_WA_IPC, (WPARAM)&"LibrarySendToMenu", IPC_REGISTER_WINAMP_IPCMESSAGE);
- if (IPC_LIBRARY_SENDTOMENU > 65536 && SendMessage(plugin.hwndWinampParent, WM_WA_IPC, (WPARAM)0, IPC_LIBRARY_SENDTOMENU) == (LRESULT)-1)
- {
- s.mode = 1;
- s.hwnd = hwndDlg;
- s.data_type = ML_TYPE_ITEMRECORDLIST;
- s.ctx[1] = 1;
- s.build_hMenu = sendto_hmenu;
- }
- wchar_t *artist = NULL;
- wchar_t *album = NULL;
- int n = resultlist.GetSelectionMark();
- if (n != -1)
- {
- artist = itemCache.Items[n].artist;
- album = itemCache.Items[n].album;
- wchar_t str[2048] = {0}, str2[128] = {0};
- // (BigG): Check the ini settings for viewing vs playing and create the menu accordingly
- // Keeping this here in case we want to use the ini setting:
- //StringCchPrintfW(str, 2048, WASABI_API_LNGSTRINGW( (g_viewnotplay != 0) ? IDS_VIEW_ALL_FILES_BY : IDS_PLAY_ALL_FILES_BY), artist ? artist : L"");
- int len = lstrlenW(artist);
- if (len > 39)
- {
- StringCchPrintfW(str2, 40, L"%.36s...", artist);//WASABI_API_LNGSTRINGW(IDS_VIEW_ALL_FILES_BY), artist ? artist : L"");
- StringCchPrintfW(str, 2048, WASABI_API_LNGSTRINGW(IDS_VIEW_ALL_FILES_BY), str2);
- }
- else
- {
- StringCchPrintfW(str, 2048, WASABI_API_LNGSTRINGW(IDS_VIEW_ALL_FILES_BY), artist ? artist : L"");
- }
- FixAmps(str, 2048);
- MENUITEMINFOW mii =
- {
- sizeof(MENUITEMINFOW),
- MIIM_TYPE | MIIM_ID,
- MFT_STRING,
- MFS_ENABLED,
- 0x1234,
- NULL,
- NULL,
- NULL,
- 0,
- str,
- 0,
- };
- if (!(!cloud_hinst || cloud_hinst == (HINSTANCE)1 ||
- !SendMessage(plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_GET_CLOUD_ACTIVE)))
- {
- MENUITEMINFOW m = {sizeof(m), MIIM_TYPE | MIIM_ID | MIIM_SUBMENU, MFT_SEPARATOR, 0};
- m.wID = CLOUD_SOURCE_MENUS - 1;
- InsertMenuItemW(menu, 0, FALSE, &m);
- wchar_t a[100] = {0};
- m.fType = MFT_STRING;
- m.dwTypeData = WASABI_API_LNGSTRINGW_BUF(IDS_CLOUD_SOURCES, a, 100);
- m.wID = CLOUD_SOURCE_MENUS;
- m.hSubMenu = cloud_hmenu = CreatePopupMenu();
- InsertMenuItemW(menu, 0, FALSE, &m);
- }
- if (artist && artist[0])
- {
- InsertMenuItemW(menu, ID_EDITITEMINFOS, FALSE, &mii);
- }
- // (BigG): Check the ini settings for viewing vs playing and create the menu accordingly
- // Keeping this here in case we want to use the ini setting:
- len = lstrlenW(album);
- if (len > 39)
- {
- StringCchPrintfW(str2, 40, L"%.36s...", album);
- StringCchPrintfW(str, 2048, WASABI_API_LNGSTRINGW(IDS_VIEW_ALL_FILES_FROM), str2);
- }
- else
- {
- StringCchPrintfW(str, 2048, WASABI_API_LNGSTRINGW(IDS_VIEW_ALL_FILES_FROM), album ? album : L"");
- }
- FixAmps(str, 2048);
- mii.cch = wcslen(str);
- mii.wID = 0x1235;
- if (album && album[0])
- {
- InsertMenuItemW(menu, ID_EDITITEMINFOS, FALSE, &mii);
- }
- {
- mii.wID = 0xdeadbeef;
- mii.fType = MFT_SEPARATOR;
- InsertMenuItemW(menu, ID_EDITITEMINFOS, FALSE, &mii);
- }
- }
- else
- {
- EnableMenuItem(menu, ID_MEDIAWND_PLAYSELECTEDFILES, MF_BYCOMMAND | MF_GRAYED);
- EnableMenuItem(menu, ID_MEDIAWND_ENQUEUESELECTEDFILES, MF_BYCOMMAND | MF_GRAYED);
- EnableMenuItem(menu, IDC_REFRESH_METADATA, MF_BYCOMMAND | MF_GRAYED);
- EnableMenuItem(menu, ID_MEDIAWND_REMOVEFROMLIBRARY, MF_BYCOMMAND | MF_GRAYED);
- EnableMenuItem(menu, ID_EDITITEMINFOS, MF_BYCOMMAND | MF_GRAYED);
- EnableMenuItem(menu, ID_MEDIAWND_EXPLOREFOLDER, MF_BYCOMMAND | MF_GRAYED);
- EnableMenuItem(menu, ID_PE_ID3, MF_BYCOMMAND | MF_GRAYED);
- EnableMenuItem(menu, 2, MF_BYPOSITION | MF_GRAYED); //grays the "Add to playlist..." menu
- EnableMenuItem(menu, rate_idx, MF_BYPOSITION | MF_GRAYED); //grays the "Rate..." menu
- EnableMenuItem(menu, 13, MF_BYPOSITION | MF_GRAYED); //grays the "Remove..." menu
- }
- menufucker_t mf = {sizeof(mf),MENU_MEDIAVIEW,menu,0x3000,0x4000,0};
- mf.extinf.mediaview.list = resultlist.getwnd();
- mf.extinf.mediaview.items = &itemCache;
- pluginMessage message_build = {ML_IPC_MENUFUCKER_BUILD,(intptr_t)&mf,0};
- SendMessage(plugin.hwndLibraryParent, WM_ML_IPC, (WPARAM)&message_build, ML_IPC_SEND_PLUGIN_MESSAGE);
- Menu_SetRatingValue(rate_hmenu, 0);
- UpdateMenuItems(hwndDlg, menu, IDR_VIEW_ACCELERATORS);
- int r = DoTrackPopup(menu, TPM_RETURNCMD | TPM_RIGHTBUTTON | TPM_LEFTBUTTON, x, y, hwndDlg, NULL);
- pluginMessage message_result = {ML_IPC_MENUFUCKER_RESULT,(intptr_t)&mf,r,0};
- SendMessage(plugin.hwndLibraryParent, WM_ML_IPC, (WPARAM)&message_result, ML_IPC_SEND_PLUGIN_MESSAGE);
- switch (r)
- {
- case ID_MEDIAWND_PLAYSELECTEDFILES:
- case ID_MEDIAWND_ENQUEUESELECTEDFILES:
- playFiles((r == ID_MEDIAWND_ENQUEUESELECTEDFILES), 0);
- break;
- case ID_MEDIAWND_SELECTALL:
- {
- LVITEM item = {0};
- item.state = LVIS_SELECTED;
- item.stateMask = LVIS_SELECTED;
- SendMessageW(hwndFrom, LVM_SETITEMSTATE, (WPARAM)-1, (LPARAM)&item);
- }
- break;
- case ID_MEDIAWND_REMOVEFROMLIBRARY:
- removeSelectedItems(0);
- break;
- case ID_EDITITEMINFOS:
- if (resultlist.GetSelectedCount() > 0)
- editInfo(hwndDlg);
- break;
- case ID_PE_ID3:
- fileInfoDialogs(hwndDlg);
- PostMessageW(hwndDlg, WM_NEXTDLGCTL, (WPARAM)hwndFrom, (LPARAM)TRUE);
- break;
- case IDC_REFRESH_METADATA:
- RefreshMetadata(hwndDlg);
- break;
- case 0x1234: // all files from selected artist
- {
- wchar_t tmp[2048] = {0};
- GayStringW escaped;
- queryStrEscape(artist, escaped);
- // Keeping this here in case we want to use the ini setting later:
- //if ( g_viewnotplay ) // (BigG): Check to see if we should play or view the current tracks
- //{
- StringCchPrintfW(tmp, 2048, L"?artist = \"%s\"", escaped.Get());
- SetWindowTextW(hwndSearchGlobal, tmp);
- //}
- //else // Otherwise do the old behavior and just play it back
- //{
- // StringCchPrintfW(tmp, 2048, L"artist = \"%s\"", escaped.Get());
- // main_playQuery(g_view_metaconf, tmp, 0);
- //}
-
- SetWindowTextW(hwndSearchGlobal, tmp);
- }
- break;
- case 0x1235: // all files from selected album
- {
- wchar_t tmp[2048] = {0};
- GayStringW escaped;
- queryStrEscape(album, escaped);
-
- // Keeping this here in case we want to use the ini setting later:
- //if ( g_viewnotplay ) // (BigG): Check to see if we should play or view the current tracks
- //{
- StringCchPrintfW(tmp, 2048, L"?album = \"%s\"", escaped.Get());
- SetWindowTextW(hwndSearchGlobal, tmp);
- //}
- //else // Otherwise do the old behavior and just play it back
- //{
- // StringCchPrintfW(tmp, 2048, L"album = \"%s\"", escaped.Get());
- // main_playQuery(g_view_metaconf, tmp, 0);
- //}
- }
- break;
- case ID_RATE_1:
- case ID_RATE_2:
- case ID_RATE_3:
- case ID_RATE_4:
- case ID_RATE_5:
- case ID_RATE_0:
- {
- int rate = r - ID_RATE_1 + 1;
- if (r == ID_RATE_0) rate = 0;
- int x;
- int has = 0;
- EnterCriticalSection(&g_db_cs);
- nde_scanner_t s = NDE_Table_CreateScanner(g_table);
- for (x = 0; x < itemCache.Size; x ++)
- {
- if (resultlist.GetSelected(x))
- {
- if (NDE_Scanner_LocateNDEFilename(s, MAINTABLE_ID_FILENAME, FIRST_RECORD, itemCache.Items[x].filename))
- {
- has++;
- NDE_Scanner_Edit(s);
- db_setFieldInt(s, MAINTABLE_ID_RATING, rate);
- NDE_Scanner_Post(s);
- itemCache.Items[x].rating = rate;
- if (g_config->ReadInt(L"writeratings", 0))
- {
- wchar_t buf[64] = {0};
- if (rate > 0)
- {
- wsprintfW(buf, L"%d", rate);
- }
- else
- buf[0] = 0;
- updateFileInfo(itemCache.Items[x].filename, DB_FIELDNAME_rating, buf);
- SendMessage(plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_WRITE_EXTENDED_FILE_INFO);
- }
- }
- }
- }
- NDE_Table_DestroyScanner(g_table, s);
- if (g_table_dirty)
- {
- g_table_dirty = 0;
- NDE_Table_Sync(g_table);
- }
- LeaveCriticalSection(&g_db_cs);
- if (has)
- {
- ListView_RedrawItems(resultlist.getwnd(), 0, itemCache.Size - 1);
- PostMessage(GetParent(hwndDlg), WM_APP + 4, (WPARAM)rate, (LPARAM)0);
- }
- }
- break;
- case ID_MEDIAWND_EXPLOREFOLDER:
- exploreItemFolder(hwndDlg);
- break;
- case ID_MEDIAWND_REMOVE_REMOVEALLDEADFILES:
- removeDeadFiles(hwndDlg);
- break;
- case ID_MEDIAWND_REMOVE_PHYSICALLYREMOVESELECTEDITEMS:
- RecycleSelectedItems();
- break;
- default:
- {
- if (cloud_hmenu && (r >= CLOUD_SOURCE_MENUS && r < CLOUD_SOURCE_MENUS_UPPER)) // deals with cloud specific menus
- {
- // 0 = no change
- // 1 = add cloud
- // 2 = add local
- // 4 = removed
- int mode = 0;
- WASABI_API_SYSCB->syscb_issueCallback(api_mldb::SYSCALLBACK, api_mldb::MLDB_FILE_PROCESS_CLOUD_STATUS, (intptr_t)r, (intptr_t)&mode);
- int n = resultlist.GetSelectionMark();
- if (n != -1)
- {
- switch (mode)
- {
- case 1:
- setCloudValue(&itemCache.Items[n], L"5");
- break;
- case 2:
- setCloudValue(&itemCache.Items[n], L"0");
- break;
- case 4:
- setCloudValue(&itemCache.Items[n], L"4");
- break;
- }
- InvalidateRect(resultlist.getwnd(), NULL, TRUE);
- }
- break;
- }
- if (s.mode == 2)
- {
- s.menu_id = r;
- if (SendMessage(plugin.hwndWinampParent, WM_WA_IPC, (WPARAM)&s, IPC_LIBRARY_SENDTOMENU) == (LRESULT)-1)
- {
- // build my data.
- s.mode = 3;
- s.data_type = ML_TYPE_ITEMRECORDLISTW;
- itemRecordListW myObj = {0, };
- copyFilesToItemCacheW(&myObj); // does not dupe strings
- s.data = (void*) & myObj;
- LRESULT result = SendMessage(plugin.hwndWinampParent, WM_WA_IPC, (WPARAM) & s, IPC_LIBRARY_SENDTOMENU);
- if (result != 1)
- {
- s.mode = 3;
- s.data_type = ML_TYPE_ITEMRECORDLIST;
- itemRecordList objA = {0, };
- convertRecordList(&objA, &myObj);
- s.data = (void*) & objA;
- SendMessage(plugin.hwndWinampParent, WM_WA_IPC, (WPARAM)&s, IPC_LIBRARY_SENDTOMENU);
- freeRecordList(&objA);
- }
- _aligned_free(myObj.Items);
- }
- }
- break;
- }
- }
- if (s.mode)
- {
- s.mode = 4;
- SendMessage(plugin.hwndWinampParent, WM_WA_IPC, (WPARAM)&s, IPC_LIBRARY_SENDTOMENU); // cleanup
- }
- sendto_hmenu = 0;
- DestroyMenu(cloud_hmenu);
- cloud_hmenu = 0;
- DestroyMenu(globmenu);
- UpdateWindow(hwndFrom);
- EatKeyboard();
- }
- static BOOL ListView_OnFindItem(HWND hwndDlg, NMLVFINDITEMW *pfi, LRESULT *pResult, UINT uMsg)
- {
- if (bgThread_Handle) return FALSE;
- int i = pfi->iStart;
- if (i >= itemCache.Size) i = 0;
- int cnt = itemCache.Size - i;
- if (pfi->lvfi.flags & LVFI_WRAP) cnt += i;
- int by = g_view_metaconf->ReadInt(L"mv_sort_by", MEDIAVIEW_COL_ARTIST);
- while (cnt-- > 0)
- {
- itemRecordW *thisitem = itemCache.Items + i;
- wchar_t tmp[128] = {0};
- wchar_t *name = 0;
- switch (by)
- {
- case MEDIAVIEW_COL_FILENAME:
- name = thisitem->filename + wcslen(thisitem->filename);
- while (name >= thisitem->filename && *name != L'/' && *name != L'\\') name--;
- break;
- case MEDIAVIEW_COL_FULLPATH:
- name = thisitem->filename;
- break;
- case MEDIAVIEW_COL_EXTENSION:
- name = PathFindExtensionW(thisitem->filename);
- if (name && *name)
- name++;
- break;
- case MEDIAVIEW_COL_TITLE: name = thisitem->title; break;
- case MEDIAVIEW_COL_COMMENT: name = thisitem->comment; break;
- case MEDIAVIEW_COL_ARTIST: name = thisitem->artist; break;
- case MEDIAVIEW_COL_ALBUM: name = thisitem->album; break;
- case MEDIAVIEW_COL_GENRE: name = thisitem->genre; break;
- case MEDIAVIEW_COL_YEAR:
- tmp[0] = 0;
- if (thisitem->year >= 0) StringCchPrintfW(tmp, 128, L"%04d", thisitem->year);
- name = tmp;
- break;
- case MEDIAVIEW_COL_TRACK:
- tmp[0] = 0;
- if (thisitem->track > 0)
- {
- if (thisitem->tracks > 0) StringCchPrintfW(tmp, 128, L"%d/%d", thisitem->track, thisitem->tracks);
- else StringCchPrintfW(tmp, 128, L"%d", thisitem->track);
- }
- name = tmp;
- break;
- case MEDIAVIEW_COL_LENGTH:
- tmp[0] = 0;
- if (thisitem->length >= 0) StringCchPrintfW(tmp, 128, L"%d:%02d", thisitem->length / 60, thisitem->length % 60);
- name = tmp;
- break;
- case MEDIAVIEW_COL_RATING:
- tmp[0] = 0;
- if (thisitem->rating > 0) StringCchPrintfW(tmp, 128, L"%d", thisitem->rating);
- name = tmp;
- break;
- case MEDIAVIEW_COL_CLOUD:
- {
- tmp[0] = 0;
- wchar_t *x = getRecordExtendedItem_fast(thisitem, extended_fields.cloud);
- if (x && *x) StringCchPrintfW(tmp, 128, L"%d", x);
- name = tmp;
- break;
- }
- case MEDIAVIEW_COL_PLAYCOUNT:
- tmp[0] = 0;
- if (thisitem->playcount > 0) StringCchPrintfW(tmp, 128, L"%d", thisitem->playcount);
- name = tmp;
- break;
- case MEDIAVIEW_COL_BITRATE:
- if (thisitem->bitrate > 0)
- StringCchPrintfW(name = tmp, 128, L"%d%s", thisitem->bitrate, WASABI_API_LNGSTRINGW(IDS_KBPS));
- break;
- case MEDIAVIEW_COL_BPM:
- if (thisitem->bpm > 0)
- StringCchPrintfW(name = tmp, 128, L"%d", thisitem->bpm);
- break;
- case MEDIAVIEW_COL_TYPE:
- name = WASABI_API_LNGSTRINGW(thisitem->type ? IDS_VIDEO : IDS_AUDIO);
- break;
- case MEDIAVIEW_COL_DISC:
- tmp[0] = 0;
- if (thisitem->disc > 0)
- {
- if (thisitem->discs > 0)
- StringCchPrintfW(tmp, 128, L"%d/%d", thisitem->disc, thisitem->discs);
- else
- StringCchPrintfW(tmp, 128, L"%d", thisitem->disc);
- }
- name = tmp;
- break;
- case MEDIAVIEW_COL_ALBUMARTIST:
- name = thisitem->albumartist;
- break;
- case MEDIAVIEW_COL_PUBLISHER:
- name = thisitem->publisher;
- break;
- case MEDIAVIEW_COL_COMPOSER:
- name = thisitem->composer;
- break;
- case MEDIAVIEW_COL_ALBUMGAIN:
- name = thisitem->replaygain_album_gain;
- break;
- case MEDIAVIEW_COL_TRACKGAIN:
- name = thisitem->replaygain_track_gain;
- break;
- case MEDIAVIEW_COL_FILESIZE:
- tmp[0] = 0;
- if (thisitem->filesize > 0) StringCchPrintfW(tmp, 128, L"%d", thisitem->filesize);
- name = tmp;
- break;
- case MEDIAVIEW_COL_FILETIME:
- tmp[0] = 0;
- if (thisitem->filetime > 0) StringCchPrintfW(tmp, 128, L"%d", thisitem->filetime);
- name = tmp;
- break;
- case MEDIAVIEW_COL_LASTUPD:
- tmp[0] = 0;
- if (thisitem->lastupd > 0) StringCchPrintfW(tmp, 128, L"%d", thisitem->lastupd);
- name = tmp;
- break;
- case MEDIAVIEW_COL_DATEADDED:
- {
- tmp[0] = 0;
- wchar_t *x = getRecordExtendedItem_fast(thisitem,extended_fields.dateadded);
- if (x && *x) StringCchPrintfW(tmp, 128, L"%d", x);
- name = tmp;
- break;
- }
- case MEDIAVIEW_COL_LASTPLAY:
- tmp[0] = 0;
- if (thisitem->lastplay > 0) StringCchPrintfW(tmp, 128, L"%d", thisitem->lastplay);
- name = tmp;
- break;
- case MEDIAVIEW_COL_ISPODCAST:
- {
- wchar_t * t = getRecordExtendedItem_fast(thisitem, extended_fields.ispodcast);
- name = WASABI_API_LNGSTRINGW(t && wcscmp(t,L"1") ? IDS_PODCAST : IDS_NON_PODCAST);
- }
- break;
- case MEDIAVIEW_COL_PODCASTCHANNEL:
- name = getRecordExtendedItem_fast(thisitem,extended_fields.podcastchannel);
- break;
- case MEDIAVIEW_COL_PODCASTPUBDATE:
- {
- tmp[0] = 0;
- wchar_t *x = getRecordExtendedItem_fast(thisitem,extended_fields.podcastpubdate);
- if (x && *x) StringCchPrintfW(tmp, 128, L"%d", x);
- name = tmp;
- }
- break;
- case MEDIAVIEW_COL_CATEGORY:
- name = thisitem->category;
- break;
- case MEDIAVIEW_COL_DIRECTOR:
- name = getRecordExtendedItem_fast(thisitem,extended_fields.director);
- break;
- case MEDIAVIEW_COL_PRODUCER:
- name = getRecordExtendedItem_fast(thisitem,extended_fields.producer);
- break;
- case MEDIAVIEW_COL_DIMENSION:
- {
- tmp[0] = 0;
- wchar_t *w = getRecordExtendedItem_fast(thisitem,extended_fields.width);
- wchar_t *h = getRecordExtendedItem_fast(thisitem,extended_fields.height);
- if (w && *w && h && *h) StringCchPrintfW(tmp, 128, L"%dx%d", _wtoi(w), _wtoi(h));
- name = tmp;
- break;
- }
- }
- if (!name) name = L"";
- else SKIP_THE_AND_WHITESPACEW(name)
- if (pfi->lvfi.flags & (4 | LVFI_PARTIAL))
- {
- if (!StrCmpNIW(name, pfi->lvfi.psz, wcslen(pfi->lvfi.psz)))
- {
- *pResult = i;
- return TRUE;
- }
- }
- else if (pfi->lvfi.flags & LVFI_STRING)
- {
- if (!lstrcmpiW(name, pfi->lvfi.psz))
- {
- *pResult = i;
- return TRUE;
- }
- }
- else
- {
- *pResult = i;
- return TRUE;
- }
- if (++i == itemCache.Size) i = 0;
- }
- *pResult = i;
- return TRUE;
- }
- static BOOL ListView_OnGetDispInfo(HWND hwndDlg, NMLVDISPINFOW* pdi, UINT uMsg)
- {
- LVITEMW *pItem;
- itemRecordW *pRec;
- pItem = &pdi->item;
- if (bgThread_Handle)
- {
- if (0 == pItem->iItem && 0 == pItem->iSubItem && (LVIF_TEXT & pItem->mask))
- {
- static char bufpos = 0;
- static int buflen = 17;
- static wchar_t buffer[64];//L"Scanning _\0/-\\|";
- if (!buffer[0])
- {
- WASABI_API_LNGSTRINGW_BUF(IDS_SCANNING_PLAIN,buffer,54);
- StringCchCatW(buffer,64,L" _");
- StringCchCatW(buffer+(buflen=lstrlenW(buffer)+1),64,L"/-\\|");
- buflen+=4;
- }
- int pos = buflen - 5;;
- buffer[pos - 1] = buffer[pos + (bufpos++&3) + 1];
- pItem->pszText = buffer;
- }
- return FALSE;
- }
- if (pItem->iItem < 0 || pItem->iItem >= itemCache.Size) return FALSE;
- pRec = itemCache.Items + pItem->iItem;
- if (LVIF_TEXT & pItem->mask)
- {
- switch (columnOrder[pItem->iSubItem])
- {
- case MEDIAVIEW_COL_FILENAME: // show filename (Tho we'll show without the path cause paths are gay)
- pItem->pszText = PathFindFileNameW(pRec->filename);
- break;
- case MEDIAVIEW_COL_FULLPATH: // show filename (Tho we'll show without the path cause paths are gay)
- pItem->pszText = pRec->filename;
- break;
- case MEDIAVIEW_COL_EXTENSION:
- pItem->pszText = PathFindExtensionW(pRec->filename);
- if (pItem->pszText && *pItem->pszText) pItem->pszText++;
- break;
- case MEDIAVIEW_COL_TITLE:
- pItem->pszText = pRec->title;
- break;
- case MEDIAVIEW_COL_COMMENT:
- pItem->pszText = pRec->comment;
- break;
- case MEDIAVIEW_COL_ALBUM:
- pItem->pszText = pRec->album;
- break;
- case MEDIAVIEW_COL_ARTIST:
- pItem->pszText = pRec->artist;
- break;
- case MEDIAVIEW_COL_TRACK:
- if (pRec->track > 0)
- {
- if (pRec->tracks > 0) StringCchPrintfW(pItem->pszText, pItem->cchTextMax, L"%d/%d", pRec->track, pRec->tracks);
- else StringCchPrintfW(pItem->pszText, pItem->cchTextMax, L"%d", pRec->track);
- }
- break;
- case MEDIAVIEW_COL_GENRE:
- pItem->pszText = pRec->genre;
- break;
- case MEDIAVIEW_COL_YEAR:
- if (pRec->year >= 0) StringCchPrintfW(pItem->pszText, pItem->cchTextMax, L"%04d", pRec->year);
- break;
- case MEDIAVIEW_COL_LENGTH:
- if (pRec->length >= 0) StringCchPrintfW(pItem->pszText, pItem->cchTextMax, L"%d:%02d", pRec->length / 60, pRec->length % 60);
- break;
- case MEDIAVIEW_COL_RATING:
- if (0 == pItem->iSubItem && ratingBackText[0]) pItem->pszText = ratingBackText;
- else if (pRec->rating > 0 && pRec->rating <= 5) _itow(pRec->rating, pItem->pszText, 10);
- break;
- case MEDIAVIEW_COL_CLOUD:
- {
- wchar_t *t = getRecordExtendedItem_fast(pRec, extended_fields.cloud);
- if (t && *t) StringCchPrintfW(pItem->pszText, pItem->cchTextMax, L"%d", _wtoi(t));
- break;
- }
- case MEDIAVIEW_COL_PLAYCOUNT:
- if (pRec->playcount >= 0) StringCchPrintfW(pItem->pszText, pItem->cchTextMax, L"%d", pRec->playcount);
- else pItem->pszText = L"0";
- break;
- case MEDIAVIEW_COL_DISC:
- if (pRec->disc > 0)
- {
- if (pRec->discs > 0) StringCchPrintfW(pItem->pszText, pItem->cchTextMax, L"%d/%d", pRec->disc, pRec->discs);
- else StringCchPrintfW(pItem->pszText, pItem->cchTextMax, L"%d", pRec->disc);
- }
- break;
- case MEDIAVIEW_COL_ALBUMARTIST:
- pItem->pszText = pRec->albumartist;
- break;
- case MEDIAVIEW_COL_PUBLISHER:
- pItem->pszText = pRec->publisher;
- break;
- case MEDIAVIEW_COL_COMPOSER:
- pItem->pszText = pRec->composer;
- break;
- case MEDIAVIEW_COL_ALBUMGAIN:
- pItem->pszText = pRec->replaygain_album_gain;
- break;
- case MEDIAVIEW_COL_TRACKGAIN:
- pItem->pszText = pRec->replaygain_track_gain;
- break;
- case MEDIAVIEW_COL_TYPE:
- pItem->pszText = WASABI_API_LNGSTRINGW((pRec->type) ? IDS_VIDEO : IDS_AUDIO);
- break;
- case MEDIAVIEW_COL_BITRATE:
- if (pRec->bitrate > 0) StringCchPrintfW(pItem->pszText, pItem->cchTextMax, L"%d%s", pRec->bitrate, WASABI_API_LNGSTRINGW(IDS_KBPS));
- break;
- case MEDIAVIEW_COL_BPM:
- if (pRec->bpm > 0) StringCchPrintfW(pItem->pszText, pItem->cchTextMax, L"%d", pRec->bpm);
- break;
- case MEDIAVIEW_COL_FILESIZE:
- if (pRec->filesize != -1) WASABI_API_LNG->FormattedSizeString(pItem->pszText, pItem->cchTextMax, pRec->filesize);
- break;
- case MEDIAVIEW_COL_FILETIME:
- MakeDateString(pRec->filetime, pItem->pszText, pItem->cchTextMax);
- break;
- case MEDIAVIEW_COL_LASTUPD:
- MakeDateString(pRec->lastupd, pItem->pszText, pItem->cchTextMax);
- break;
- case MEDIAVIEW_COL_DATEADDED:
- {
- wchar_t * t = getRecordExtendedItem_fast(pRec,extended_fields.dateadded);
- if (t && *t) MakeDateString(_wtoi64(t), pItem->pszText, pItem->cchTextMax);
- break;
- }
- case MEDIAVIEW_COL_LASTPLAY:
- if (pRec->lastplay > 0) MakeDateString(pRec->lastplay, pItem->pszText, pItem->cchTextMax);
- break;
- case MEDIAVIEW_COL_ISPODCAST:
- {
- wchar_t *t = getRecordExtendedItem_fast(pRec, extended_fields.ispodcast);
- pItem->pszText = WASABI_API_LNGSTRINGW((t && t[0] == L'1' && !t[1]) ? IDS_PODCAST : IDS_NON_PODCAST);
- break;
- }
- case MEDIAVIEW_COL_PODCASTCHANNEL:
- pItem->pszText = getRecordExtendedItem_fast(pRec, extended_fields.podcastchannel);
- break;
- case MEDIAVIEW_COL_PODCASTPUBDATE:
- {
- wchar_t * t = getRecordExtendedItem_fast(pRec,extended_fields.podcastpubdate);
- if (t && *t) MakeDateString(_wtoi64(t), pItem->pszText, pItem->cchTextMax);
- break;
- }
- case MEDIAVIEW_COL_CATEGORY:
- pItem->pszText = pRec->category;
- break;
- case MEDIAVIEW_COL_DIRECTOR:
- pItem->pszText = getRecordExtendedItem_fast(pRec, extended_fields.director);
- break;
- case MEDIAVIEW_COL_PRODUCER:
- pItem->pszText = getRecordExtendedItem_fast(pRec, extended_fields.producer);
- break;
- case MEDIAVIEW_COL_DIMENSION:
- {
- wchar_t *w = getRecordExtendedItem_fast(pRec,extended_fields.width);
- wchar_t *h = getRecordExtendedItem_fast(pRec,extended_fields.height);
- if (w && *w && h && *h) StringCchPrintfW(pItem->pszText, pItem->cchTextMax, L"%dx%d", _wtoi(w), _wtoi(h));
- break;
- }
- }
- if (!pItem->pszText) pItem->pszText = L"";
- }
- return FALSE;
- }
- static BOOL ListView_OnColumnClick(HWND hwndDlg, NMLISTVIEW *pnmv)
- {
- int l_sc = g_view_metaconf->ReadInt(L"mv_sort_by", MEDIAVIEW_COL_ARTIST);
- int l_sd = g_view_metaconf->ReadInt(L"mv_sort_dir", 0);
- if (columnOrder[pnmv->iSubItem] == l_sc) l_sd = !l_sd;
- else
- {
- /* JF> I like this better when the direction doesnt get reset every
- time you choose a new column. To revert to old behavior, uncomment
- this line:
- l_sd=0;
- */
- l_sc = columnOrder[pnmv->iSubItem];
- }
- g_view_metaconf->WriteInt(L"mv_sort_by", l_sc);
- g_view_metaconf->WriteInt(L"mv_sort_dir", l_sd);
- MLSkinnedListView_DisplaySort(pnmv->hdr.hwndFrom, pnmv->iSubItem, !l_sd);
- sortResults(g_view_metaconf, &itemCache);
- resultlist.SetVirtualCount(0);
- resultlist.SetVirtualCount(itemCache.Size); // TODO: we could set a limit here
- ListView_RedrawItems(pnmv->hdr.hwndFrom, 0, itemCache.Size - 1);
- return FALSE;
- }
- static BOOL ListView_OnBeginDrag(HWND hwndDlg, NMLISTVIEW *pnmv)
- {
- switch (columnOrder[pnmv->iSubItem])
- {
- case MEDIAVIEW_COL_RATING:
- ratingColumn.hwndList = pnmv->hdr.hwndFrom;
- ratingColumn.fStyle = RCS_DEFAULT;
- ratingColumn.iItem = pnmv->iItem;
- ratingColumn.iSubItem = pnmv->iSubItem;
- ratingColumn.value = ((UINT)pnmv->iItem < (UINT)itemCache.Size) ? itemCache.Items[pnmv->iItem].rating : 0;
- MLRatingColumn_BeginDrag(plugin.hwndLibraryParent, &ratingColumn);
- break;
- }
- SetCapture(hwndDlg);
- return FALSE;
- }
- static BOOL ListView_OnReturn(HWND hwndDlg, NMHDR *pnmh)
- {
- SendMessage(hwndDlg, WM_COMMAND, ((!!(GetAsyncKeyState(VK_SHIFT)&0x8000)) ^(!!g_config->ReadInt(L"enqueuedef", 0)))
- ? IDC_BUTTON_ENQUEUE : IDC_BUTTON_PLAY, 0);
- return FALSE;
- }
- static BOOL ListView_OnCustomDraw(HWND hwndDlg, NMLVCUSTOMDRAW *plvcd, LRESULT *pResult)
- {
- static BOOL bDrawFocus;
- static RECT rcView;
- static RATINGCOLUMNPAINT ratingColumnPaint;
- static CLOUDCOLUMNPAINT cloudColumnPaint;
- *pResult = CDRF_DODEFAULT;
- switch (plvcd->nmcd.dwDrawStage)
- {
- case CDDS_PREPAINT:
- *pResult |= CDRF_NOTIFYITEMDRAW;
- CopyRect(&rcView, &plvcd->nmcd.rc);
- ratingColumnPaint.fStyle = RCS_DEFAULT;
- ratingColumnPaint.hwndList = plvcd->nmcd.hdr.hwndFrom;
- ratingColumnPaint.hdc = plvcd->nmcd.hdc;
- ratingColumnPaint.prcView = &rcView;
- cloudColumnPaint.hwndList = plvcd->nmcd.hdr.hwndFrom;
- cloudColumnPaint.hdc = plvcd->nmcd.hdc;
- cloudColumnPaint.prcView = &rcView;
- return TRUE;
- case CDDS_ITEMPREPAINT:
- *pResult |= CDRF_NOTIFYSUBITEMDRAW;
- bDrawFocus = (CDIS_FOCUS & plvcd->nmcd.uItemState);
- if (bDrawFocus)
- {
- plvcd->nmcd.uItemState &= ~CDIS_FOCUS;
- *pResult |= CDRF_NOTIFYPOSTPAINT;
- }
- return TRUE;
- case CDDS_ITEMPOSTPAINT:
- if (bDrawFocus)
- {
- RECT rc;
- rc.left = LVIR_BOUNDS;
- SendMessageW(plvcd->nmcd.hdr.hwndFrom, LVM_GETITEMRECT, plvcd->nmcd.dwItemSpec, (LPARAM)&rc);
- rc.left += 3;
- DrawFocusRect(plvcd->nmcd.hdc, &rc);
- plvcd->nmcd.uItemState |= CDIS_FOCUS;
- bDrawFocus = FALSE;
- }
- *pResult = CDRF_SKIPDEFAULT;
- return TRUE;
- case(CDDS_SUBITEM | CDDS_ITEMPREPAINT):
- switch (columnOrder[plvcd->iSubItem])
- {
- case MEDIAVIEW_COL_RATING:
- if (bgThread_Handle || (0 == plvcd->iSubItem && 0 == plvcd->nmcd.rc.right)) break;
- ratingColumnPaint.iItem = plvcd->nmcd.dwItemSpec;
- ratingColumnPaint.iSubItem = plvcd->iSubItem;
- ratingColumnPaint.value = (plvcd->nmcd.dwItemSpec >= 0 && plvcd->nmcd.dwItemSpec < (UINT)itemCache.Size) ? itemCache.Items[plvcd->nmcd.dwItemSpec].rating : 0;
- ratingColumnPaint.prcItem = &plvcd->nmcd.rc;
- ratingColumnPaint.rgbBk = plvcd->clrTextBk;
- ratingColumnPaint.rgbFg = plvcd->clrText;
- if (MLRatingColumn_Paint(plugin.hwndLibraryParent, &ratingColumnPaint))
- {
- *pResult = CDRF_SKIPDEFAULT;
- return TRUE;
- }
- break;
- case MEDIAVIEW_COL_CLOUD:
- if (bgThread_Handle || (0 == plvcd->iSubItem && 0 == plvcd->nmcd.rc.right)) break;
- int icon = 4;
- wchar_t *t = getRecordExtendedItem_fast(&itemCache.Items[plvcd->nmcd.dwItemSpec], extended_fields.cloud);
- if (t && *t) icon = _wtoi(t);
- cloudColumnPaint.iItem = plvcd->nmcd.dwItemSpec;
- cloudColumnPaint.iSubItem = plvcd->iSubItem;
- cloudColumnPaint.value = icon;
- cloudColumnPaint.prcItem = &plvcd->nmcd.rc;
- cloudColumnPaint.rgbBk = plvcd->clrTextBk;
- cloudColumnPaint.rgbFg = plvcd->clrText;
- if (MLCloudColumn_Paint(plugin.hwndLibraryParent, &cloudColumnPaint))
- {
- *pResult = CDRF_SKIPDEFAULT;
- return TRUE;
- }
- break;
- }
- break;
- }
- return FALSE;
- }
- static BOOL ListView_OnClick(HWND hwnDlg, NMITEMACTIVATE *pnmitem)
- {
- if (bgThread_Handle) return FALSE;
- if (pnmitem->iItem != -1)
- {
- switch (columnOrder[pnmitem->iSubItem])
- {
- case MEDIAVIEW_COL_RATING:
- ratingColumn.hwndList = pnmitem->hdr.hwndFrom;
- ratingColumn.ptAction = pnmitem->ptAction;
- ratingColumn.bRedrawNow = TRUE;
- ratingColumn.fStyle = RCS_DEFAULT;
- if (!MLRatingColumn_Click(plugin.hwndLibraryParent, &ratingColumn)) return FALSE;
- SetRating(ratingColumn.iItem, ratingColumn.value, ratingColumn.hwndList);
- break;
- case MEDIAVIEW_COL_CLOUD:
- {
- RECT itemRect = {0};
- if (pnmitem->iSubItem)
- ListView_GetSubItemRect(pnmitem->hdr.hwndFrom, pnmitem->iItem, pnmitem->iSubItem, LVIR_BOUNDS, &itemRect);
- else
- {
- ListView_GetItemRect(pnmitem->hdr.hwndFrom, pnmitem->iItem, &itemRect, LVIR_BOUNDS);
- itemRect.right = itemRect.left + ListView_GetColumnWidth(pnmitem->hdr.hwndFrom, pnmitem->iSubItem);
- }
- MapWindowPoints(pnmitem->hdr.hwndFrom, HWND_DESKTOP, (POINT*)&itemRect, 2);
- HMENU cloud_menu = CreatePopupMenu();
- WASABI_API_SYSCB->syscb_issueCallback(api_mldb::SYSCALLBACK, api_mldb::MLDB_FILE_GET_CLOUD_STATUS, (intptr_t)itemCache.Items[pnmitem->iItem].filename, (intptr_t)&cloud_menu);
- if (cloud_menu)
- {
- int r = DoTrackPopup(cloud_menu, TPM_RETURNCMD | TPM_RIGHTBUTTON | TPM_LEFTBUTTON, itemRect.right, itemRect.top, pnmitem->hdr.hwndFrom, NULL);
- if (r >= CLOUD_SOURCE_MENUS && r < CLOUD_SOURCE_MENUS_UPPER)
- {
- // 0 = no change
- // 1 = adding to cloud
- // 2 = added locally
- // 4 = removed
- int mode = 0; // deals with cloud specific menus
- WASABI_API_SYSCB->syscb_issueCallback(api_mldb::SYSCALLBACK, api_mldb::MLDB_FILE_PROCESS_CLOUD_STATUS, (intptr_t)r, (intptr_t)&mode);
- switch (mode)
- {
- case 1:
- setCloudValue(&itemCache.Items[pnmitem->iItem], L"5");
- break;
- case 2:
- setCloudValue(&itemCache.Items[pnmitem->iItem], L"4");
- break;
- case 4:
- setCloudValue(&itemCache.Items[pnmitem->iItem], L"4");
- break;
- }
- InvalidateRect(resultlist.getwnd(), NULL, TRUE);
- }
- DestroyMenu(cloud_menu);
- }
- }
- break;
- }
- }
- return FALSE;
- }
- static BOOL ListView_OnHotTrack(HWND hwndDlg, NMLISTVIEW *pnmlv, LRESULT *pResult)
- {
- UINT iItem;
- if (bgThread_Handle)
- {
- pnmlv->iItem = -1;
- *pResult = TRUE;
- return TRUE;
- }
- if (-1 == pnmlv->iItem && 0 == pnmlv->iSubItem)
- {
- LVHITTESTINFO lvhit;
- lvhit.pt = pnmlv->ptAction;
- SendMessageW(pnmlv->hdr.hwndFrom, LVM_HITTEST, 0, (LPARAM)&lvhit);
- iItem = lvhit.iItem;
- }
- else iItem = pnmlv->iItem;
- switch (columnOrder[pnmlv->iSubItem])
- {
- case MEDIAVIEW_COL_RATING:
- ratingColumn.hwndList = pnmlv->hdr.hwndFrom;
- ratingColumn.fStyle = RCS_DEFAULT;
- ratingColumn.iItem = iItem;
- ratingColumn.iSubItem = pnmlv->iSubItem;
- ratingColumn.value = (iItem < (UINT)itemCache.Size) ? itemCache.Items[iItem].rating : 0;
- ratingColumn.ptAction = pnmlv->ptAction;
- ratingColumn.bRedrawNow = TRUE;
- MLRatingColumn_Track(plugin.hwndLibraryParent, &ratingColumn);
- break;
- }
- // LVS_EX_ONECLICKACTIVATE enabled - make listview select nothing
- pnmlv->iItem = -1;
- *pResult = TRUE;
- return TRUE;
- }
- /////////// Dialog Messages / Notifications
- static void Dialog_OnDisplayChange(HWND hwndDlg)
- {
- INT i;
- HWND hwndList = GetDlgItem(hwndDlg, IDC_LIST2);
- for (i = 0; -1 != columnOrder[i] && MEDIAVIEW_COL_RATING != columnOrder[i] && MEDIAVIEW_COL_CLOUD != columnOrder[i]; i++);
- if (-1 != columnOrder[i])
- {
- if (hwndList)
- {
- INT w = (INT)SendMessageW(hwndList, LVM_GETCOLUMNWIDTH, i, 0L);
- SendMessageW(hwndList, LVM_SETCOLUMNWIDTH, i, (LPARAM)w);
- }
- }
- LayoutWindows(hwndDlg, TRUE);
- }
- static wchar_t tt_buf[256] = {L""};
- static int last_item = -1, last_icon = -1;
- LRESULT pmp_listview(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
- if (uMsg == WM_NOTIFY)
- {
- LPNMHDR l=(LPNMHDR)lParam;
- switch (l->code)
- {
- case TTN_SHOW:
- {
- LVHITTESTINFO lvh = {0};
- GetCursorPos(&lvh.pt);
- ScreenToClient(hwnd, &lvh.pt);
- ListView_SubItemHitTest(hwnd, &lvh);
- int cloudcol = (int)GetPropW(hwnd, L"pmp_list_info");
- if (lvh.iItem != -1 && lvh.iSubItem == cloudcol)
- {
- RECT r = {0};
- if (lvh.iSubItem)
- ListView_GetSubItemRect(hwnd, lvh.iItem, lvh.iSubItem, LVIR_BOUNDS, &r);
- else
- {
- ListView_GetItemRect(hwnd, lvh.iItem, &r, LVIR_BOUNDS);
- r.right = r.left + ListView_GetColumnWidth(hwnd, cloudcol);
- }
- MapWindowPoints(hwnd, HWND_DESKTOP, (LPPOINT)&r, 2);
- SetWindowPos(l->hwndFrom, HWND_TOPMOST, r.right, r.top + 2, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE);
- return 1;
- }
- }
- break;
- case TTN_NEEDTEXTW:
- {
- LVHITTESTINFO lvh = {0};
- GetCursorPos(&lvh.pt);
- ScreenToClient(hwnd, &lvh.pt);
- ListView_SubItemHitTest(hwnd, &lvh);
- int cloudcol = (int)GetPropW(hwnd, L"pmp_list_info");
- if (lvh.iItem != -1 && lvh.iSubItem == cloudcol)
- {
- LPNMTTDISPINFOW lpnmtdi = (LPNMTTDISPINFOW)lParam;
- int icon = 4;
- wchar_t *t = getRecordExtendedItem_fast(&itemCache.Items[lvh.iItem], extended_fields.cloud);
- if (t && *t) icon = _wtoi(t);
- if (last_item == lvh.iItem && last_icon == icon)
- {
- lpnmtdi->lpszText = tt_buf;
- return 0;
- }
- if (icon == 4)
- {
- WASABI_API_LNGSTRINGW_BUF(IDS_UPLOAD_TO_SOURCE, tt_buf, ARRAYSIZE(tt_buf));
- }
- else if (icon == 5)
- {
- WASABI_API_LNGSTRINGW_BUF(IDS_UPLOADING_TO_SOURCE, tt_buf, ARRAYSIZE(tt_buf));
- }
- else
- {
- if (!cloud_hinst) cloud_hinst = (HINSTANCE)SendMessage(plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_GET_CLOUD_HINST);
- if (cloud_hinst && cloud_hinst != (HINSTANCE)1)
- {
- winampMediaLibraryPlugin *(*gp)();
- gp = (winampMediaLibraryPlugin * (__cdecl *)(void))GetProcAddress(cloud_hinst, "winampGetMediaLibraryPlugin");
- if (gp)
- {
- winampMediaLibraryPlugin *mlplugin = gp();
- if (mlplugin && (mlplugin->version >= MLHDR_VER_OLD && mlplugin->version <= MLHDR_VER))
- {
- WASABI_API_LNGSTRINGW_BUF(IDS_TRACK_AVAILABLE, tt_buf, ARRAYSIZE(tt_buf));
- nx_string_t *out_devicenames = 0;
- size_t num_names = mlplugin->MessageProc(0x405, (INT_PTR)itemCache.Items[lvh.iItem].filename, (INT_PTR)&out_devicenames, 0);
- if (num_names > 0)
- {
- for (size_t i = 0; i < num_names; i++)
- {
- if (i > 0) StringCchCatW(tt_buf, ARRAYSIZE(tt_buf), L", ");
- StringCchCatW(tt_buf, ARRAYSIZE(tt_buf), out_devicenames[i]->string);
- }
- }
- else
- {
- WASABI_API_LNGSTRINGW_BUF(IDS_UPLOAD_TO_SOURCE, tt_buf, ARRAYSIZE(tt_buf));
- }
- if (out_devicenames)
- free(out_devicenames);
- }
- }
- }
- }
- last_item = lvh.iItem;
- last_icon = icon;
- lpnmtdi->lpszText = tt_buf;
- // bit of a fiddle but it allows for multi-line tooltips
- //SendMessage(l->hwndFrom, TTM_SETMAXTIPWIDTH, 0, 0);
- }
- else
- return CallWindowProcW((WNDPROC)GetPropW(hwnd, L"pmp_list_proc"), hwnd, uMsg, wParam, lParam);
- }
- return 0;
- }
- }
- return CallWindowProcW((WNDPROC)GetPropW(hwnd, L"pmp_list_proc"), hwnd, uMsg, wParam, lParam);
- }
- void Dialog_UpdateButtonText(HWND hwndDlg, int _enqueuedef)
- {
- if (groupBtn)
- {
- switch(_enqueuedef)
- {
- case 1:
- SetDlgItemTextW(hwndDlg, IDC_BUTTON_PLAY, view.enqueue);
- customAllowed = FALSE;
- break;
- default:
- // v5.66+ - re-use the old predixis parts so the button can be used functionally via ml_enqplay
- // pass the hwnd, button id and plug-in id so the ml plug-in can check things as needed
- pluginMessage p = {ML_MSG_VIEW_BUTTON_HOOK_IN_USE, (INT_PTR)_enqueuedef, 0, 0};
- wchar_t *pszTextW = (wchar_t *)SENDMLIPC(plugin.hwndLibraryParent, ML_IPC_SEND_PLUGIN_MESSAGE, (WPARAM)&p);
- if (pszTextW && pszTextW[0] != 0)
- {
- // set this to be a bit different so we can just use one button and not the
- // mixable one as well (leaving that to prevent messing with the resources)
- SetDlgItemTextW(hwndDlg, IDC_BUTTON_PLAY, pszTextW);
- customAllowed = TRUE;
- }
- else
- {
- SetDlgItemTextW(hwndDlg, IDC_BUTTON_PLAY, view.play);
- customAllowed = FALSE;
- }
- break;
- }
- }
- }
- enum
- {
- BPM_ECHO_WM_COMMAND=0x1, // send WM_COMMAND and return value
- BPM_WM_COMMAND = 0x2, // just send WM_COMMAND
- };
- BOOL Dialog_ButtonPopupMenu(HWND hwndDlg, int buttonId, HMENU menu, int flags=0)
- {
- RECT r;
- HWND buttonHWND = GetDlgItem(hwndDlg, buttonId);
- GetWindowRect(buttonHWND, &r);
- UpdateMenuItems(hwndDlg, menu, IDR_VIEW_ACCELERATORS);
- MLSkinnedButton_SetDropDownState(buttonHWND, TRUE);
- UINT tpmFlags = TPM_RIGHTBUTTON | TPM_LEFTBUTTON | TPM_BOTTOMALIGN | TPM_LEFTALIGN;
- if (!(flags & BPM_WM_COMMAND)) tpmFlags |= TPM_RETURNCMD;
- int x = DoTrackPopup(menu, tpmFlags, r.left, r.top, hwndDlg, NULL);
- if ((flags & BPM_ECHO_WM_COMMAND) && x)
- SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(x, 0), 0);
- MLSkinnedButton_SetDropDownState(buttonHWND, FALSE);
- return x;
- }
- static void Dialog_Play(HWND hwndDlg, HWND from, UINT idFrom)
- {
- HMENU listMenu = GetSubMenu(g_context_menus2, 0);
- int count = GetMenuItemCount(listMenu);
- if (count > 2)
- {
- for (int i = 2; i < count; i++)
- {
- DeleteMenu(listMenu, 2, MF_BYPOSITION);
- }
- }
- Dialog_ButtonPopupMenu(hwndDlg, idFrom, listMenu, BPM_WM_COMMAND);
- }
- static INT_PTR Dialog_OnInit(HWND hwndDlg, HWND hwndFocus, LPARAM lParam)
- {
- // benski> this is just going here because it's very likely to get called. will only get compiled in debug mode.
- assert(sizeof(extra_idsW) / sizeof(*extra_idsW) == sizeof(extra_strsW) / sizeof(*extra_strsW));
- g_displaysearch = !(BOOL)lParam;
- // Set the hwnd for the search to a global only if the multipane view hasnt set it yet, as it takes precedence to which box gets populated with the query
- //if (!IsWindow(hwndSearchGlobal))
- hwndSearchGlobal = GetDlgItem(hwndDlg, IDC_QUICKSEARCH);
- HACCEL accel = WASABI_API_LOADACCELERATORSW(IDR_VIEW_ACCELERATORS);
- if (accel)
- WASABI_API_APP->app_addAccelerators(hwndDlg, &accel, 1, TRANSLATE_MODE_CHILD);
- if (!view.play)
- {
- SENDMLIPC(plugin.hwndLibraryParent, ML_IPC_GET_VIEW_BUTTON_TEXT, (WPARAM)&view);
- }
- HWND hwndList;
- FLICKERFIX ff;
- INT index;
- INT ffcl[] = { IDC_CLEAR,
- IDC_BUTTON_PLAY,
- IDC_BUTTON_ENQUEUE,
- IDC_BUTTON_MIX,
- IDC_BUTTON_INFOTOGGLE,
- IDC_BUTTON_CREATEPLAYLIST,
- IDC_MIXABLE,
- IDC_MEDIASTATUS,
- };
- m_hwnd = hwndDlg;
- m_bgupdinfoviewerflag = 0;
- columnOrder[0] = -1;
- last_item = -1;
- tt_buf[0] = 0;
- if (!cloud_hinst) cloud_hinst = (HINSTANCE)SendMessage(plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_GET_CLOUD_HINST);
- if (cloud_hinst && cloud_hinst != (HINSTANCE)1)
- {
- winampMediaLibraryPlugin *(*gp)();
- gp = (winampMediaLibraryPlugin * (__cdecl *)(void))GetProcAddress(cloud_hinst, "winampGetMediaLibraryPlugin");
- if (gp)
- {
- winampMediaLibraryPlugin *mlplugin = gp();
- if (mlplugin && (mlplugin->version >= MLHDR_VER_OLD && mlplugin->version <= MLHDR_VER))
- {
- int64_t *out_ids = 0;
- nx_string_t *out_filenames = 0;
- size_t num_files = mlplugin->MessageProc(0x404, (INT_PTR)&out_filenames, (INT_PTR)&out_ids, 0xDEADBEEF);
- for (size_t i = 0; i < num_files; i++)
- {
- cloudFiles.push_back((wchar_t *)out_filenames[i]->string);
- }
- if (out_filenames)
- {
- free(out_filenames);
- out_filenames = 0;
- }
- if (out_ids)
- {
- free(out_ids);
- out_ids = 0;
- }
- HWND ml_pmp_window = FindWindowW(L"ml_pmp_window", NULL);
- if (IsWindow(ml_pmp_window))
- {
- SendMessage(ml_pmp_window, WM_PMP_IPC, (WPARAM)&cloudUploading, PMP_IPC_GETCLOUDTRANSFERS);
- wchar_t a[32] = {0};
- StringCchPrintfW(a, 32, L"%d", cloudUploading.size());
- }
- }
- }
- }
- EnterCriticalSection(&g_db_cs);
- if (!m_media_scanner) m_media_scanner = NDE_Table_CreateScanner(g_table);
- LeaveCriticalSection(&g_db_cs);
- itemCache.Items = 0;
- itemCache.Alloc = 0;
- itemCache.Size = 0;
- hwndList = GetDlgItem(hwndDlg, IDC_LIST2);
- if (IsWindow(hwndList))
- {
- resultlist.setwnd(hwndList);
- resultlist.ForceUnicode();
- DWORD styleEx = LVS_EX_DOUBLEBUFFER | LVS_EX_HEADERDRAGDROP | LVS_EX_ONECLICKACTIVATE; /*LVS_EX_ONECLICKACTIVATE - needed to hottracking work prior WinXp */
- SendMessageW(hwndList, LVM_SETEXTENDEDLISTVIEWSTYLE, styleEx, styleEx);
- HWND hwndHeader = (HWND)SendMessage(hwndList, LVM_GETHEADER, 0, 0L);
- if (IsWindow(hwndHeader)) SetWindowLongPtrW(hwndHeader, GWLP_ID, IDC_LIST2HEADER);
- MLSKINWINDOW skin = {0};
- skin.hwndToSkin = hwndList;
- skin.skinType = SKINNEDWND_TYPE_LISTVIEW;
- skin.style = SWS_USESKINFONT | SWS_USESKINCOLORS | SWS_USESKINCURSORS | SWLVS_FULLROWSELECT | SWLVS_DOUBLEBUFFER | SWLVS_ALTERNATEITEMS;
- MLSkinWindow(plugin.hwndLibraryParent, &skin);
- }
- else resultlist.setwnd(NULL);
- ff.mode = FFM_ERASEINPAINT;
- for (index = 0; index < sizeof(ffcl) / sizeof(INT); index++)
- {
- ff.hwnd = GetDlgItem(hwndDlg, ffcl[index]);
- SENDMLIPC(plugin.hwndLibraryParent, ML_IPC_FLICKERFIX, (WPARAM)&ff);
- }
- if (!g_displaysearch) // disable search box
- {
- ShowWindow(GetDlgItem(hwndDlg, IDC_QUICKSEARCH), SW_HIDE);
- ShowWindow(GetDlgItem(hwndDlg, IDC_CLEAR), SW_HIDE);
- ShowWindow(GetDlgItem(hwndDlg, IDC_SEARCHCAPTION), SW_HIDE);
- }
- if (!cloud_hinst || cloud_hinst == (HINSTANCE)1)
- memcpy(columnOrder, defColumnOrder, sizeof(defColumnOrder));
- else
- memcpy(columnOrder, defColumnOrderCloud, sizeof(defColumnOrderCloud));
- //Read the column order
- Dialog_OnDisplayChange(hwndDlg);
- int cloudcol = -1;
- int l = g_view_metaconf->ReadInt(L"nbcolumns", 0);
- if (l)
- {
- if (l > MAX_COLUMN_ORDER - 1) l = MAX_COLUMN_ORDER - 1;
- index = 0;
- for (; index < l; index++)
- {
- wchar_t tmp[128] = {0};
- StringCchPrintfW(tmp, 128, L"column%d", index);
- int v = g_view_metaconf->ReadInt(tmp, 0);
- if (v == MEDIAVIEW_COL_CLOUD) cloudcol = index;
- if (v < 0 || v >= MEDIAVIEW_COL_NUMS) v = 0;
- columnOrder[index] = (BYTE)v;
- }
- columnOrder[index] = -1;
- }
- if (cloudcol == -1 && !g_view_metaconf->ReadInt(L"cloud", 1))
- {
- g_view_metaconf->WriteInt(L"cloud", 1);
- for(int i = l; i != 0; i--)
- {
- columnOrder[i+1] = columnOrder[i];
- if (i == 3)
- {
- columnOrder[i] = MEDIAVIEW_COL_CLOUD;
- break;
- }
- }
- }
- if (!GetPropW(hwndList, L"pmp_list_proc")) {
- SetPropW(hwndList, L"pmp_list_proc", (HANDLE)SetWindowLongPtrW(hwndList, GWLP_WNDPROC, (LONG_PTR)pmp_listview));
- }
- initColumnsHeader(hwndList);
- char *pszTextA = (g_config->ReadInt(L"remembersearch", 0)) ? g_view_metaconf->ReadString("lastquery_utf8", "") : "";
- AutoWide queryUnicode(pszTextA, CP_UTF8);
- SetDlgItemTextW(hwndDlg, IDC_QUICKSEARCH, queryUnicode);
- KillTimer(hwndDlg, UPDATE_QUERY_TIMER_ID);
- doQuery(hwndDlg, queryUnicode, 0);
- updateInfoText(hwndDlg);
- search_oldWndProc = (WNDPROC)SetWindowLongPtrW(GetDlgItem(hwndDlg, IDC_QUICKSEARCH), GWLP_WNDPROC, (LONG_PTR)search_newWndProc);
- if (g_table && !NDE_Table_GetRecordsCount(g_table) && !g_config->ReadInt(L"noshowadddlg", 0))
- {
- SetTimer(hwndDlg, 5050, 1000, NULL);
- }
- groupBtn = g_config->ReadInt(L"groupbtn", 1);
- enqueuedef = (g_config->ReadInt(L"enqueuedef", 0) == 1);
- /// detect predixis
- predixisExist = FALSE;
- //predixis out - begin
- //pluginMessage p = {ML_MSG_PDXS_STATUS, (INT_PTR)"test", 0, 0};
- //pszTextA = (char *)SENDMLIPC(plugin.hwndLibraryParent, ML_IPC_SEND_PLUGIN_MESSAGE, (WPARAM)&p);
- //predixisExist = (pszTextA != NULL && pszTextA[0] != 0);
- //predixis out - end
- // v5.66+ - re-use the old predixis parts so the button can be used functionally via ml_enqplay
- // pass the hwnd, button id and plug-in id so the ml plug-in can check things as needed
- pluginMessage p = {ML_MSG_VIEW_BUTTON_HOOK, (INT_PTR)hwndDlg, (INT_PTR)MAKELONG(IDC_BUTTON_MIX, IDC_BUTTON_ENQUEUE), (INT_PTR)L"ml_local"};
- wchar_t *pszTextW = (wchar_t *)SENDMLIPC(plugin.hwndLibraryParent, ML_IPC_SEND_PLUGIN_MESSAGE, (WPARAM)&p);
- if (pszTextW && pszTextW[0] != 0)
- {
- // set this to be a bit different so we can just use one button and not the
- // mixable one as well (leaving that to prevent messing with the resources)
- customAllowed = TRUE;
- SetDlgItemTextW(hwndDlg, IDC_BUTTON_MIX, pszTextW);
- }
- else
- customAllowed = FALSE;
- ShowWindow(GetDlgItem(hwndDlg, IDC_BUTTON_MIX), (!customAllowed ? SW_HIDE : SW_SHOW));
- ShowWindow(GetDlgItem(hwndDlg, IDC_MIXABLE), (!(predixisExist & 1) ? SW_HIDE : SW_SHOW));
- MLSKINWINDOW m = {0};
- m.hwndToSkin = hwndDlg;
- m.skinType = SKINNEDWND_TYPE_AUTO;
- m.style = SWS_USESKINFONT | SWS_USESKINCOLORS | SWS_USESKINCURSORS | SWLVS_FULLROWSELECT | SWLVS_DOUBLEBUFFER | SWLVS_ALTERNATEITEMS;
- MLSkinWindow(plugin.hwndLibraryParent, &m);
- m.skinType = SKINNEDWND_TYPE_BUTTON;
- m.style = SWS_USESKINFONT | SWS_USESKINCOLORS | SWS_USESKINCURSORS | (groupBtn ? SWBS_SPLITBUTTON : 0);
- const int buttonids[] = {IDC_BUTTON_PLAY, IDC_BUTTON_ENQUEUE, IDC_BUTTON_MIX};
- for (size_t i=0;i!=sizeof(buttonids)/sizeof(buttonids[0]);i++)
- {
- m.hwndToSkin = GetDlgItem(hwndDlg, buttonids[i]);
- if (IsWindow(m.hwndToSkin)) MLSkinWindow(plugin.hwndLibraryParent, &m);
- }
- m.skinType = SKINNEDWND_TYPE_AUTO;
- m.style = SWS_USESKINFONT | SWS_USESKINCOLORS | SWS_USESKINCURSORS;
- const int buttonidz[] = {IDC_SEARCHCAPTION, IDC_QUICKSEARCH, IDC_MEDIASTATUS, IDC_CLEAR, IDC_BUTTON_INFOTOGGLE, IDC_BUTTON_CREATEPLAYLIST, IDC_MIXABLE};
- for (size_t i=0;i!=sizeof(buttonidz)/sizeof(buttonidz[0]);i++)
- {
- m.hwndToSkin = GetDlgItem(hwndDlg, buttonidz[i]);
- if (IsWindow(m.hwndToSkin)) MLSkinWindow(plugin.hwndLibraryParent, &m);
- }
- Dialog_UpdateButtonText(hwndDlg, enqueuedef);
- return FALSE;
- }
- static BOOL Dialog_OnNotify(HWND hwndDlg, INT idCtrl, NMHDR* pnmh, LRESULT *pResult)
- {
- switch (pnmh->idFrom)
- {
- case IDC_LIST2:
- switch (pnmh->code)
- {
- case LVN_ITEMCHANGED: return ListView_OnItemChanged(hwndDlg, (NMLISTVIEW*)pnmh);
- case NM_DBLCLK: return ListView_OnDoubleClick(hwndDlg, (NMITEMACTIVATE*)pnmh);
- case LVN_ODFINDITEMA:
- case LVN_ODFINDITEMW: return ListView_OnFindItem(hwndDlg, (NMLVFINDITEMW*)pnmh, pResult, pnmh->code);
- case LVN_GETDISPINFOA:
- case LVN_GETDISPINFOW: return ListView_OnGetDispInfo(hwndDlg, (NMLVDISPINFOW*)pnmh, pnmh->code);
- case LVN_COLUMNCLICK: return ListView_OnColumnClick(hwndDlg, (NMLISTVIEW*)pnmh);
- case LVN_BEGINDRAG: return ListView_OnBeginDrag(hwndDlg, (NMLISTVIEW*)pnmh);
- case NM_RETURN: return ListView_OnReturn(hwndDlg, pnmh);
- case NM_CUSTOMDRAW: return ListView_OnCustomDraw(hwndDlg, (NMLVCUSTOMDRAW*)pnmh, pResult);
- case LVN_HOTTRACK: return ListView_OnHotTrack(hwndDlg, (NMLISTVIEW*)pnmh, pResult);
- case NM_CLICK: return ListView_OnClick(hwndDlg, (NMITEMACTIVATE*)pnmh);
- }
- break;
- case IDC_LIST2HEADER:
- switch (pnmh->code)
- {
- case NM_RCLICK: return Header_OnRightClick(hwndDlg, pnmh, pResult);
- case HDN_ENDDRAG: return Header_OnEndDrag(hwndDlg, (NMHEADERW*)pnmh, pResult);
- case HDN_ITEMCHANGINGA:
- case HDN_ITEMCHANGINGW: return Header_OnItemChanging(hwndDlg, (NMHEADERW*)pnmh, pResult, pnmh->code);
- }
- break;
- }
- return FALSE;
- }
- static void Dialog_OnInitMenuPopup(HWND hwndDlg, HMENU hMenu, UINT nIndex, BOOL bSysMenu)
- {
- if (hMenu && hMenu == s.build_hMenu && s.mode == 1)
- {
- myMenu = TRUE;
- if (SendMessage(plugin.hwndWinampParent, WM_WA_IPC, (WPARAM)&s, IPC_LIBRARY_SENDTOMENU) == (LRESULT)-1)
- s.mode = 2;
- myMenu = FALSE;
- }
- if (rate_hmenu && hMenu == rate_hmenu)
- {
- int x;
- int sel = 0;
- for (x = 0; x < itemCache.Size; x ++)
- {
- if (resultlist.GetSelected(x))
- {
- int s = itemCache.Items[x].rating;
- if (s == sel || !sel) sel = s;
- if (s != sel) break;
- }
- }
- if (-1 == sel) sel = 0;
- Menu_SetRatingValue(rate_hmenu, sel);
- }
- if (cloud_hmenu && hMenu == cloud_hmenu)
- {
- int n = resultlist.GetSelectionMark();
- if (n != -1 && !GetMenuItemCount(hMenu))
- {
- WASABI_API_SYSCB->syscb_issueCallback(api_mldb::SYSCALLBACK, api_mldb::MLDB_FILE_GET_CLOUD_STATUS, (intptr_t)itemCache.Items[n].filename, (intptr_t)&cloud_hmenu);
- }
- }
- }
- static void Dialog_OnMouseMove(HWND hwndDlg, UINT nFlags, POINTS pts)
- {
- if (GetCapture() == hwndDlg)
- {
- mlDropItemStruct m = {0};
- POINTSTOPOINT(m.p, pts);
- MapWindowPoints(hwndDlg, HWND_DESKTOP, (POINT*)&m.p, 1);
- if (MLRatingColumn_Drag(plugin.hwndLibraryParent, &m.p)) return;
- m.type = ML_TYPE_ITEMRECORDLIST;
- pluginHandleIpcMessage(ML_IPC_HANDLEDRAG, (WPARAM)&m);
- }
- }
- static void Dialog_OnLButtonUp(HWND hwndDlg, UINT nFlags, POINTS pts)
- {
- if (GetCapture() == hwndDlg)
- {
- mlDropItemStruct m = {0};
- ReleaseCapture();
- POINTSTOPOINT(m.p, pts);
- MapWindowPoints(hwndDlg, HWND_DESKTOP, (POINT*)&m.p, 1);
- ratingColumn.bCanceled = FALSE;
- ratingColumn.ptAction = m.p;
- ratingColumn.bRedrawNow = TRUE;
- if (MLRatingColumn_EndDrag(plugin.hwndLibraryParent, &ratingColumn))
- {
- SetRating(ratingColumn.iItem, ratingColumn.value, ratingColumn.hwndList);
- return;
- }
- m.type = ML_TYPE_ITEMRECORDLISTW;
- m.flags = ML_HANDLEDRAG_FLAG_NOCURSOR;
- pluginHandleIpcMessage(ML_IPC_HANDLEDRAG, (WPARAM)&m);
- if (m.result > 0) // try itemRecordListW
- {
- itemRecordListW myObj = {0, };
- copyFilesToItemCacheW(&myObj);
- m.flags = 0;
- m.result = 0;
- m.data = (void*) & myObj;
- pluginHandleIpcMessage(ML_IPC_HANDLEDROP, (WPARAM)&m);
- _aligned_free(myObj.Items); // DO NOT empty this object, cause it doesnt own its data
- }
- else // if it didn't work, fall back to itemRecordList
- {
- m.type = ML_TYPE_ITEMRECORDLIST;
- m.result = 0;
- pluginHandleIpcMessage(ML_IPC_HANDLEDRAG, (WPARAM)&m);
- if (m.result > 0)
- {
- itemRecordListW myObj = {0, };
- copyFilesToItemCacheW(&myObj);
- itemRecordList objA = {0, };
- convertRecordList(&objA, &myObj);
- m.flags = 0;
- m.result = 0;
- m.data = (void*) & objA;
- pluginHandleIpcMessage(ML_IPC_HANDLEDROP, (WPARAM)&m);
- emptyRecordList(&objA);
- freeRecordList(&objA);
- _aligned_free(myObj.Items); // DO NOT empty this object, cause it doesnt own its data
- }
- }
- }
- }
- class ItemRecordPlaylist : public ifc_playlist
- {
- public:
- ItemRecordPlaylist(const itemRecordListW *_list)
- {
- list = _list;
- }
- private:
- size_t GetNumItems()
- {
- return list->Size;
- }
- size_t GetItem(size_t item, wchar_t *filename, size_t filenameCch)
- {
- if (item < (size_t)list->Size && list->Items[item].filename)
- {
- StringCchCopyW(filename, filenameCch, list->Items[item].filename);
- return 1;
- }
- return 0;
- }
- size_t GetItemTitle(size_t item, wchar_t *title, size_t titleCch)
- {
- if (item < (size_t)list->Size && list->Items[item].filename)
- {
- TAG_FMT_EXT(list->Items[item].filename, itemrecordWTagFunc, ndeTagFuncFree, (void*)&list->Items[item], title, titleCch, 0);
- return 1;
- }
- return 0;
- }
- int GetItemLengthMilliseconds(size_t item)
- {
- if (item < (size_t)list->Size && list->Items[item].length>=0)
- {
- return list->Items[item].length * 1000;
- }
- return -1000;
- }
- private:
- const itemRecordListW *list;
- protected:
- RECVS_DISPATCH;
- };
- #define CBCLASS ItemRecordPlaylist
- START_DISPATCH;
- CB(IFC_PLAYLIST_GETNUMITEMS, GetNumItems)
- CB(IFC_PLAYLIST_GETITEM, GetItem)
- CB(IFC_PLAYLIST_GETITEMTITLE, GetItemTitle)
- CB(IFC_PLAYLIST_GETITEMLENGTHMILLISECONDS, GetItemLengthMilliseconds)
- END_DISPATCH;
- #undef CBCLASS
- static void Dialog_OnCommand(HWND hwndDlg, UINT idCtrl, INT nCode, HWND hwndCtrl)
- {
- if (GetFocus() != hwndSearchGlobal)
- {
- switch (idCtrl)
- {
- case IDC_CLEAR:
- SetDlgItemText(hwndDlg, IDC_QUICKSEARCH, L"");
- break;
- case IDC_BUTTON_INFOTOGGLE:
- updateInfoText(hwndDlg, TRUE);
- UpdateWindow(hwndDlg);
- LayoutWindows(hwndDlg, TRUE);
- break;
- case IDC_QUICKSEARCH:
- if (nCode == EN_CHANGE)
- {
- KillTimer(hwndDlg, UPDATE_QUERY_TIMER_ID);
- SetTimer(hwndDlg, UPDATE_QUERY_TIMER_ID, g_querydelay, NULL);
- }
- break;
- case ID_AUDIOWND_PLAYSELECTION:
- case ID_QUERYWND_PLAYQUERY:
- case IDC_BUTTON_PLAY:
- case ID_MEDIAWND_PLAYSELECTEDFILES:
- case ID_AUDIOWND_ENQUEUESELECTION:
- case IDC_BUTTON_ENQUEUE:
- case ID_MEDIAWND_ENQUEUESELECTEDFILES:
- case IDC_BUTTON_MIX:
- {
- if (nCode == MLBN_DROPDOWN)
- {
- Dialog_Play(hwndDlg, hwndCtrl, idCtrl);
- }
- else
- {
- int action;
- if (idCtrl == IDC_BUTTON_PLAY || idCtrl == ID_MEDIAWND_PLAYSELECTEDFILES || idCtrl == ID_AUDIOWND_PLAYSELECTION)
- {
- action = (nCode == 1) ? g_config->ReadInt(L"enqueuedef", 0) == 1 : 0;
- }
- else if (idCtrl == IDC_BUTTON_ENQUEUE || idCtrl == ID_MEDIAWND_ENQUEUESELECTEDFILES || idCtrl == ID_AUDIOWND_ENQUEUESELECTION)
- {
- action = (nCode == 1) ? g_config->ReadInt(L"enqueuedef", 0) != 1 : 1;
- }
- else
- break;
- int i, l = itemCache.Size;
- for (i = 0; i < l; i++) if (resultlist.GetSelected(i)) break;
- playFiles(action/*idCtrl == IDC_BUTTON_ENQUEUE*/, i == l);
- }
- }
- break;
- case IDC_BUTTON_CREATEPLAYLIST:
- #if 0
- // TODO consider exposing this option somehow...
- if (AGAVE_API_PLAYLISTMANAGER) // This is the old Create Playlist button code
- {
- wchar_t fn[MAX_PATH] = {0};
- wchar_t dir[MAX_PATH] = {0};
- GetTempPathW(MAX_PATH,dir);
- GetTempFileNameW(dir,L"ml_playlist",0,fn);
- wcscat(fn,L".m3u8");
- ItemRecordPlaylist playlist(&itemCache);
- if (AGAVE_API_PLAYLISTMANAGER->Save(fn, &playlist) == PLAYLISTMANAGER_SUCCESS)
- {
- mlAddPlaylist p={sizeof(p),NULL,fn,PL_FLAGS_IMPORT,-1,-1};
- SendMessage(plugin.hwndLibraryParent,WM_ML_IPC,(WPARAM)&p,ML_IPC_PLAYLIST_ADD);
- DeleteFileW(fn);
- }
- }
- #endif
- if (AGAVE_API_PLAYLIST_GENERATOR)
- {
- const int number_selected = resultlist.GetSelectedCount(); // Total selected
- if (number_selected > 0)
- {
- itemRecordListW recordList; // Record list
- itemRecordW *records = new itemRecordW[number_selected]; // Array of records
- int selectedRecordcounter = 0;
- for (int i = 0; i < itemCache.Size; i++)
- {
- if (resultlist.GetSelected(i)) // See if the current item is selected or not
- {
- records[selectedRecordcounter] = itemCache.Items[i]; // If its selected then add it to our itemlist
- selectedRecordcounter++;
- }
- }
- recordList.Size = selectedRecordcounter; // Set the correct size of the record list
- recordList.Items = records; // Set the array of records to the record list
- AGAVE_API_PLAYLIST_GENERATOR->GeneratePlaylist(hwndDlg, &recordList); // Call the playlist API with the list of selected records
- delete [] records; // Free up the array of records
- }
- else
- {
- wchar_t title[64] = {0};
- MessageBoxW(m_hwnd, WASABI_API_LNGSTRINGW(IDS_ERROR_PLG_SELECT_TRACKS), WASABI_API_LNGSTRINGW_BUF(IDS_NULLSOFT_PLAYLIST_GENERATOR,title,64), MB_OK | MB_ICONINFORMATION);
- }
- }
- break;
- #if 0
- case IDC_BUTTON_MIX:
- {
- itemRecordList list;
- int i;
- int ct = 0;
- for (i = 0; i < itemCache.Size; i++)
- {
- if (resultlist.GetSelected(i))
- {
- ct++;
- }
- }
- ZeroMemory(&list, sizeof(itemRecordList));
- allocRecordList(&list, ct, 1);
- list.Size = ct;
- ct = 0;
- for (i = 0; i < itemCache.Size; i++)
- {
- if (resultlist.GetSelected(i))
- {
- convertRecord(&list.Items[ct], &itemCache.Items[i]);
- ct++;
- }
- }
- pluginMessage p = {ML_MSG_PDXS_MIX, (INT_PTR) &list, 0, 0};
- SendMessage(plugin.hwndLibraryParent, WM_ML_IPC, (WPARAM)&p, ML_IPC_SEND_PLUGIN_MESSAGE);
- emptyRecordList(&list);
- freeRecordList(&list);
- }
- break;
- #endif
- case ID_MEDIAWND_SELECTALL:
- {
- LVITEM item = {0};
- item.state = LVIS_SELECTED;
- item.stateMask = LVIS_SELECTED;
- SendMessageW(resultlist.getwnd(), LVM_SETITEMSTATE, (WPARAM)-1, (LPARAM)&item);
- }
- break;
- case ID_MEDIAWND_REMOVEFROMLIBRARY:
- removeSelectedItems(0);
- break;
- case ID_EDITITEMINFOS:
- if (resultlist.GetSelectedCount() > 0)
- editInfo(hwndDlg);
- break;
- case ID_PE_ID3:
- fileInfoDialogs(hwndDlg);
- PostMessageW(hwndDlg, WM_NEXTDLGCTL, (WPARAM)resultlist.getwnd(), (LPARAM)TRUE);
- break;
- case IDC_REFRESH_METADATA:
- RefreshMetadata(hwndDlg);
- break;
- case ID_MEDIAWND_EXPLOREFOLDER:
- exploreItemFolder(hwndDlg);
- break;
- }
- }
- else
- {
- switch (idCtrl)
- {
- case IDC_QUICKSEARCH:
- if (nCode == EN_CHANGE)
- {
- KillTimer(hwndDlg, UPDATE_QUERY_TIMER_ID);
- SetTimer(hwndDlg, UPDATE_QUERY_TIMER_ID, g_querydelay, NULL);
- }
- break;
- case ID_MEDIAWND_SELECTALL:
- SendMessageW(hwndSearchGlobal, EM_SETSEL, 0, -1);
- break;
- case ID_MEDIAWND_REMOVEFROMLIBRARY:
- {
- DWORD start = -1, end = -1;
- SendMessageW(hwndSearchGlobal, EM_GETSEL, (WPARAM)&start, (LPARAM)&end);
- if (start != -1)
- {
- if (start == end)
- {
- SendMessageW(hwndSearchGlobal, EM_SETSEL, start, end + 1);
- }
- SendMessageW(hwndSearchGlobal, EM_REPLACESEL, TRUE, (LPARAM)"");
- SendMessageW(hwndSearchGlobal, EM_SETSEL, start, start);
- }
- }
- break;
- }
- }
- }
- static void Dialog_OnTimer(HWND hwndDlg, UINT_PTR idEvent, TIMERPROC fnTimer)
- {
- switch (idEvent)
- {
- case 5050:
- KillTimer(hwndDlg, 5050);
- WASABI_API_DIALOGBOXW(IDD_NEEDADDFILES, hwndDlg, needAddFilesProc);
- PostMessage(GetParent(hwndDlg), WM_APP + 1, (WPARAM)0, (LPARAM)0);
- break;
- case 6600:
- KillTimer(hwndDlg, idEvent);
- if (m_last_selitem >= 0 && m_last_selitem < itemCache.Size)
- {
- if (predixisExist & 1)
- {
- // Only single seeds are supported currently
- if (resultlist.GetSelectedCount() == 1 && isMixable(itemCache.Items[m_last_selitem]))
- {
- SetDlgItemTextW(hwndDlg, IDC_MIXABLE, WASABI_API_LNGSTRINGW(IDS_MIXABLE));
- isMixablePresent = true;
- }
- else SetDlgItemText(hwndDlg, IDC_MIXABLE, L"");
- }
- SendMessageW(GetParent(hwndDlg), WM_SHOWFILEINFO, (WPARAM)FALSE, (LPARAM)itemCache.Items[m_last_selitem].filename);
- m_last_selitem = -1;
- }
- break;
- case 123:
- if (bgThread_Handle)
- {
- HWND hwndList;
- hwndList = resultlist.getwnd();
- if (1 != ListView_GetItemCount(hwndList)) ListView_SetItemCountEx(hwndList, 1, LVSICF_NOINVALIDATEALL | LVSICF_NOSCROLL);
- ListView_RedrawItems(hwndList, 0, 0);
- //UpdateWindow(hwndList);
- }
- break;
- case UPDATE_QUERY_TIMER_ID:
- {
- KillTimer(hwndDlg, UPDATE_QUERY_TIMER_ID);
- wchar_t buf[2048] = {0};
- GetWindowTextW(GetDlgItem(hwndDlg, IDC_QUICKSEARCH), buf, ARRAYSIZE(buf));
- doQuery(hwndDlg, buf);
- }
- break;
- case UPDATE_RESULT_LIST_TIMER_ID:
- {
- ListView_RedrawItems(resultlist.getwnd(), 0, resultlist.GetCount() - 1);
- }
- break;
- }
- }
- static void Dialog_OnDestroy(HWND hwndDlg)
- {
- HWND hwndList;
- INT i, j;
- wchar_t buf[2048] = {0};
- bgQuery_Stop();
- GetDlgItemTextW(hwndDlg, IDC_QUICKSEARCH, buf, ARRAYSIZE(buf));
- g_view_metaconf->WriteString("lastquery_utf8", AutoChar(buf, CP_UTF8));
- hwndList = GetDlgItem(hwndDlg, IDC_LIST2);
- if (hwndList && IsWindow(hwndList))
- {
- for (i = 0; columnOrder[i] != -1; i++)
- {
- headerColumn *cl = &columnList[columnOrder[i]];
- g_view_metaconf->WriteInt(AutoWide(cl->config_name), SendMessageW(hwndList, LVM_GETCOLUMNWIDTH, i, 0L));
- }
- }
- //Save the column order
- for (i = 0; columnOrder[i] != -1; i++);
- g_view_metaconf->WriteInt(L"nbcolumns", i);
- for (j = 0; j < i; j++)
- {
- wchar_t tmp[128] = {0};
- StringCchPrintfW(tmp, 128, L"column%d", j);
- g_view_metaconf->WriteInt(tmp, columnOrder[j]);
- }
- freeRecordList(&itemCache);
- itemCache.Items = 0;
- itemCache.Alloc = 0;
- itemCache.Size = 0;
- cloudFiles.clear();
- cloudUploading.clear();
- hwndSearchGlobal = 0; // Set the hwnd for the search to a global to null so we know we are not in the single pane view
- }
- static void Dialog_OnWindowPosChanged(HWND hwndDlg, WINDOWPOS *pwp)
- {
- if ((SWP_NOSIZE | SWP_NOMOVE) != ((SWP_NOSIZE | SWP_NOMOVE) & pwp->flags) || (SWP_FRAMECHANGED & pwp->flags))
- {
- LayoutWindows(hwndDlg, !(SWP_NOREDRAW & pwp->flags), 0 != (SWP_SHOWWINDOW & pwp->flags));
- }
- }
- static void Dialog_OnSyncHeaderOrder(HWND hwndDlg, HWND hwndHeader)
- {
- LVCOLUMNW column = {0};
- wchar_t buffer[128] = {0};
- signed char tempOrder[MAX_COLUMN_ORDER] = {0};
- HWND hwndList = GetDlgItem(hwndDlg, IDC_LIST2);
- if (!hwndList) return;
- CopyMemory(tempOrder, columnOrder, sizeof(tempOrder)/sizeof(signed char));
- column.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM | LVCF_IMAGE;
- column.cchTextMax = sizeof(buffer) /sizeof(wchar_t);
- SendMessageW(hwndList, WM_SETREDRAW, FALSE, 0L);
- INT sort = MLSkinnedListView_GetSort(hwndList);
- INT count = (INT)SendMessageW(hwndHeader, HDM_GETITEMCOUNT, 0, 0L);
- if (count > 0)
- {
- INT index = count + 1, *pOrder = (INT*)calloc(1, sizeof(INT)*count);
- if (pOrder && SendMessageW(hwndList, LVM_GETCOLUMNORDERARRAY, count, (LPARAM)pOrder))
- {
- INT order;
- for (order = 0; order < count; order++)
- {
- column.pszText = buffer;
- if (!SendMessageW(hwndList, LVM_GETCOLUMNW, pOrder[order], (LPARAM)&column)) continue;
- column.iOrder = order;
- // update position of the cloud column icon
- if (tempOrder[pOrder[order]] == MEDIAVIEW_COL_CLOUD)
- {
- if (!cloud_hinst || cloud_hinst == (HINSTANCE)1 ||
- !SendMessage(plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_GET_CLOUD_ACTIVE))
- {
- MLSkinnedHeader_SetCloudColumn(ListView_GetHeader(hwndList), -1);
- SetPropW(hwndList, L"pmp_list_info", (HANDLE)-1);
- column.cx = 0;
- }
- else
- {
- MLSkinnedHeader_SetCloudColumn(ListView_GetHeader(hwndList), order);
- SetPropW(hwndList, L"pmp_list_info", (HANDLE)order);
- column.cx = 27;
- MLCloudColumn_GetWidth(plugin.hwndLibraryParent, &column.cx);
- }
- }
- SendMessageW(hwndList, LVM_INSERTCOLUMNW, index++, (LPARAM)&column);
- columnOrder[order] = tempOrder[pOrder[order]];
- if (LOWORD(sort) == pOrder[order]) MLSkinnedListView_DisplaySort(hwndList, order, HIWORD(sort));
- }
- for (order = 0; order < count; order++) SendMessageW(hwndList, LVM_DELETECOLUMN, 0, 0L);
- }
- for (index = 0; -1 != columnOrder[index] && MEDIAVIEW_COL_RATING != columnOrder[index] && MEDIAVIEW_COL_CLOUD != columnOrder[index]; index++);
- if (-1 != columnOrder[index])
- {
- INT w = (INT)SendMessageW(hwndList, LVM_GETCOLUMNWIDTH, index, 0L);
- SendMessageW(hwndList, LVM_SETCOLUMNWIDTH, index, (LPARAM)w);
- }
- if (pOrder) free(pOrder);
- }
- SendMessageW(hwndList, WM_SETREDRAW, TRUE, 0L);
- }
- static void Window_OnQueryFileInfo(HWND hwnd)
- {
- INT index;
- HWND hwndList = GetDlgItem(hwnd, IDC_LIST2);
- index = (hwndList) ? (INT)SendMessage(hwndList, LVM_GETNEXTITEM, (WPARAM)-1, (LPARAM)LVNI_FOCUSED) : -1;
- SendMessageW(GetParent(hwnd), WM_SHOWFILEINFO, (WPARAM)FALSE, (LPARAM)((-1 != index && index < itemCache.Size) ? itemCache.Items[index].filename : L""));
- }
- void Window_OnDropFiles(HWND hwndDlg, HDROP hdrop)
- {
- wchar_t temp[1024] = {0};
- int y = DragQueryFileW(hdrop, 0xffffffff, temp, 1024);
- if (y > 0)
- {
- wchar_t **paths = (wchar_t **)calloc(y, sizeof(wchar_t *));
- int *guesses = (int *)calloc(y, sizeof(int));
- int *metas = (int *)calloc(y, sizeof(int));
- int *recs= (int *)calloc(y, sizeof(int));
- if (paths && guesses && metas && recs)
- {
- size_t count=0;
- for (int x = 0; x < y; x ++)
- {
- DragQueryFileW(hdrop, x, temp, 1024);
- int guess = -1, meta = -1, rec = 1;
- // do this for normal media drops
- PLCallBackW plCB;
- if (AGAVE_API_PLAYLISTMANAGER && PLAYLISTMANAGER_SUCCESS != AGAVE_API_PLAYLISTMANAGER->Load(temp, &plCB))
- {
- autoscan_add_directory(temp, &guess, &meta, &rec, 0);
- if (guess == -1) guess = g_config->ReadInt(L"guessmode", 0);
- if (meta == -1) meta = g_config->ReadInt(L"usemetadata", 1);
- paths[count] = _wcsdup(temp);
- guesses[count]=guess;
- metas[count]=meta;
- recs[count]=rec;
- count++;
- }
- }
- DragFinish(hdrop);
- Scan_ScanFolders(hwndDlg, count, paths, guesses, metas, recs);
- if (IsWindow(m_curview_hwnd)) SendMessage(m_curview_hwnd, WM_APP + 1, 0, 0); //update current view
- }
- else
- {
- free(paths);
- free(guesses);
- free(metas);
- free(recs);
- }
- }
- else DragFinish(hdrop);
- }
- INT_PTR CALLBACK view_mediaDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- BOOL a = dialogSkinner.Handle(hwndDlg, uMsg, wParam, lParam); if (a) return a;
- switch (uMsg)
- {
- case WM_INITMENUPOPUP: Dialog_OnInitMenuPopup(hwndDlg, (HMENU)wParam, LOWORD(lParam), HIWORD(lParam)); break;
- case WM_DISPLAYCHANGE: Dialog_OnDisplayChange(hwndDlg); break;
- case WM_INITDIALOG: return Dialog_OnInit(hwndDlg, (HWND)wParam, lParam);
- case WM_MOUSEMOVE: Dialog_OnMouseMove(hwndDlg, (UINT)wParam, MAKEPOINTS(lParam)); break;
- case WM_LBUTTONUP: Dialog_OnLButtonUp(hwndDlg, (UINT)wParam, MAKEPOINTS(lParam)); break;
- case WM_DROPFILES: Window_OnDropFiles(hwndDlg, (HDROP)wParam);
- case WM_COMMAND: Dialog_OnCommand(hwndDlg, LOWORD(wParam), HIWORD(wParam), (HWND)lParam); break;
- case WM_TIMER: Dialog_OnTimer(hwndDlg, (UINT_PTR) wParam, (TIMERPROC)lParam); break;
- case WM_DESTROY: Dialog_OnDestroy(hwndDlg); break;
- case WM_WINDOWPOSCHANGED: Dialog_OnWindowPosChanged(hwndDlg, (WINDOWPOS*)lParam); break;
- case WM_ERASEBKGND: return 1; //handled by WADlg_DrawChildWindowBorders in WM_PAINT
- case WM_CONTEXTMENU:
- Dialog_OnContextMenu(hwndDlg, (HWND)wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
- return 0;
- case WM_NOTIFY:
- {
- LRESULT result;
- result = 0L;
- if (Dialog_OnNotify(hwndDlg, (INT)wParam, (NMHDR*)lParam, &result))
- {
- SetWindowLongPtrW(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)result);
- return TRUE;
- }
- }
- break;
- case IM_SYNCHEADERORDER: Dialog_OnSyncHeaderOrder(hwndDlg, (HWND)lParam); break;
- case WM_APP + 3: // send by bgthread
- if (wParam == 0x666) m_bgupdinfoviewerflag = 1;
- else if (wParam == 0x69)
- {
- bgQuery_Stop();
- resultlist.SetVirtualCount(0);
- resultlist.SetVirtualCount(itemCache.Size); // TODO: we could set a limit here
- ListView_RedrawItems(resultlist.getwnd(), 0, itemCache.Size - 1);
- UpdateWindow(resultlist.getwnd());
- __int64 total_len_bytes = bg_total_len_bytes;
- int total_length_s = (int)bg_total_len_s & 0x7FFFFFFF;
- wchar_t buffer[4*64] = {0};
- wchar_t *pb[4] = {0};
- for (int i = 0; i < 4; i++) pb[i] = buffer + i * 64;
- int index(0);
- StringCchPrintfW(pb[index], 64, L"%d %s", itemCache.Size,
- WASABI_API_LNGSTRINGW(itemCache.Size == 1 ? IDS_ITEM : IDS_ITEMS));
- index++;
- if (itemCache.Size)
- {
- int uncert = 0; //bg_total_len_s>>31;
- if (total_length_s < 60*60) StringCchPrintfW(pb[index], 64, L"[%s%u:%02u]", uncert ? L"~" : L"", total_length_s / 60, total_length_s % 60);
- else if (total_length_s < 60*60*24) StringCchPrintfW(pb[index], 64, L"[%s%u:%02u:%02u]", uncert ? L"~" : L"", total_length_s / 60 / 60, (total_length_s / 60) % 60, total_length_s % 60);
- else
- {
- wchar_t days[16] = {0};
- int total_days = total_length_s / (60 * 60 * 24);
- total_length_s -= total_days * 60 * 60 * 24;
- StringCchPrintfW(pb[index], 64,
- WASABI_API_LNGSTRINGW(IDS_LENGTH_DURATION_STRING),
- uncert ? L"~" : L"", total_days,
- WASABI_API_LNGSTRINGW_BUF(total_days == 1 ? IDS_DAY : IDS_DAYS, days, 16),
- total_length_s / 60 / 60, (total_length_s / 60) % 60, total_length_s % 60);
- }
- index++;
- }
- if (total_len_bytes)
- {
- StringCchCopyW(pb[index], 64, L"[");
- WASABI_API_LNG->FormattedSizeString(pb[index] + 1, 64, total_len_bytes);
- StringCchCatW(pb[index], 64, L"]");
- index++;
- }
- unsigned int ms = (UINT)(querytime.QuadPart * 1000 / freq.QuadPart);
- StringCchPrintfW(pb[index], 64, WASABI_API_LNGSTRINGW(IDS_IN_X_SEC), ms / 1000.0f);
- index++;
- SetStatusText(GetDlgItem(hwndDlg, IDC_MEDIASTATUS), (LPCWSTR*)pb, index);
- if (m_bgupdinfoviewerflag)
- {
- m_bgupdinfoviewerflag = 0;
- if (itemCache.Size > 0)
- {
- if (predixisExist)
- {
- if (resultlist.GetSelectedCount() == 1 && isMixable(itemCache.Items[0]))
- {
- SetDlgItemText(hwndDlg, IDC_MIXABLE, L"");
- isMixablePresent = true;
- }
- else
- {
- SetDlgItemText(hwndDlg, IDC_MIXABLE, L"");
- }
- }
- SendMessageW(GetParent(hwndDlg), WM_SHOWFILEINFO, (WPARAM)FALSE, (LPARAM)itemCache.Items[0].filename);
- }
- }
- }
- break;
- case WM_APP + 1:
- bgQuery((resultsniff_funcW)wParam, (int)lParam);
- break;
- case WM_APP + 5:
- {
- // TODO
- int done = (HIWORD(wParam) == 1);
- int code = (LOWORD(wParam));
- for (int i = 0; i < itemCache.Size; i ++)
- {
- // 0 = no change
- // 1 = add cloud
- // 2 = add local
- // 4 = removed
- if (!lstrcmpiW(itemCache.Items[i].filename, (wchar_t *)lParam))
- {
- if (!done)
- {
- setCloudValue(&itemCache.Items[i], L"5");
- }
- else
- {
- if (code == NErr_Success)
- {
- // uploaded ok
- // TODO if going to another device, will need to alter this
- setCloudValue(&itemCache.Items[i], L"0");
- }
- else
- {
- // re-query state
- setCloudValue(&itemCache.Items[i], L"0");
- }
- }
- InvalidateRect(resultlist.getwnd(), NULL, TRUE);
- break;
- }
- }
- break;
- }
- case WM_APP + 6: // handles the ml_cloud 'first pull' announces so we
- { // can then show the cloud column & update the cache
- initColumnsHeader(resultlist.getwnd());
- bgQuery();//(resultsniff_funcW)wParam, (int)lParam);
- break;
- }
- case WM_APP + 104:
- {
- Dialog_UpdateButtonText(hwndDlg, wParam);
- LayoutWindows(hwndDlg, TRUE);
- return 0;
- }
- case WM_PAINT:
- {
- int tab[] = { IDC_LIST2 | DCW_SUNKENBORDER, IDC_QUICKSEARCH | DCW_SUNKENBORDER};
- dialogSkinner.Draw(hwndDlg, tab, 1 + !!IsWindowVisible(GetDlgItem(hwndDlg, IDC_QUICKSEARCH)));
- }
- return 0;
- case WM_ML_CHILDIPC:
- switch (lParam)
- {
- case ML_CHILDIPC_GO_TO_SEARCHBAR:
- SendDlgItemMessage(hwndDlg, IDC_QUICKSEARCH, EM_SETSEL, 0, -1);
- SetFocus(GetDlgItem(hwndDlg, IDC_QUICKSEARCH));
- break;
- case ML_CHILDIPC_REFRESH_SEARCH:
- PostMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_QUICKSEARCH, EN_CHANGE), (LPARAM)GetDlgItem(hwndDlg, IDC_QUICKSEARCH));
- break;
- }
- break;
- case WM_USER + 0x201:
- offsetX = (short)LOWORD(wParam);
- offsetY = (short)HIWORD(wParam);
- g_rgnUpdate = (HRGN)lParam;
- return TRUE;
- case WM_QUERYFILEINFO: Window_OnQueryFileInfo(hwndDlg); break;
- }
- return FALSE;
- }
- //////////////////////////////// Customize columns dialog
- static signed char edit_columnOrder[MAX_COLUMN_ORDER];
- static INT_PTR CALLBACK custColumns_dialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- static HWND m_curlistbox_hwnd, m_availlistbox_hwnd;
- switch (uMsg)
- {
- case WM_INITDIALOG:
- memcpy(edit_columnOrder, columnOrder, sizeof(edit_columnOrder));
- m_curlistbox_hwnd = GetDlgItem(hwndDlg, IDC_LIST1);
- m_availlistbox_hwnd = GetDlgItem(hwndDlg, IDC_LIST2);
-
- if (NULL != WASABI_API_APP)
- {
- if (NULL != m_curlistbox_hwnd)
- WASABI_API_APP->DirectMouseWheel_EnableConvertToMouseWheel(m_curlistbox_hwnd, TRUE);
- if (NULL != m_availlistbox_hwnd)
- WASABI_API_APP->DirectMouseWheel_EnableConvertToMouseWheel(m_availlistbox_hwnd, TRUE);
- }
- case WM_USER + 32:
- {
- for (int i = 0; edit_columnOrder[i] != -1; i++)
- {
- int c = edit_columnOrder[i];
- headerColumn *cl = &columnList[c];
- int column_id = cl->column_id;
- if (column_id == IDS_CLOUD || column_id == IDS_CLOUD_HIDDEN)
- {
- // if no cloud support at all then we hide everything
- if (!cloud_hinst || cloud_hinst == (HINSTANCE)1) continue;
- column_id = ((!cloud_hinst || cloud_hinst == (HINSTANCE)1 ||
- !SendMessageW(plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_GET_CLOUD_ACTIVE)) ? IDS_CLOUD_HIDDEN : IDS_CLOUD);
- }
- int r = SendMessageW(m_curlistbox_hwnd, LB_ADDSTRING, 0, (LPARAM)WASABI_API_LNGSTRINGW(column_id));
- SendMessageW(m_curlistbox_hwnd, LB_SETITEMDATA, r, c);
- }
- for (int i = 0; i < sizeof(columnList) / sizeof(headerColumn); i++)
- {
- headerColumn *cl = &columnList[i];
- int j;
- for (j = 0; edit_columnOrder[j] != -1 && edit_columnOrder[j] != i; j++);
- if (edit_columnOrder[j] == -1)
- {
- int column_id = cl->column_id;
- if (column_id == IDS_CLOUD || column_id == IDS_CLOUD_HIDDEN)
- {
- // if no cloud support at all then we hide everything
- if (!cloud_hinst || cloud_hinst == (HINSTANCE)1) continue;
- column_id = ((!cloud_hinst || cloud_hinst == (HINSTANCE)1 ||
- !SendMessage(plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_GET_CLOUD_ACTIVE)) ? IDS_CLOUD_HIDDEN : IDS_CLOUD);
- }
- int r = SendMessageW(m_availlistbox_hwnd, LB_ADDSTRING, 0, (LPARAM)WASABI_API_LNGSTRINGW(column_id));
- SendMessageW(m_availlistbox_hwnd, LB_SETITEMDATA, r, i);
- }
- }
- }
- break;
- case WM_COMMAND:
- switch (LOWORD(wParam))
- {
- case IDC_DEFS:
- if (!cloud_hinst || cloud_hinst == (HINSTANCE)1)
- memcpy(edit_columnOrder, defColumnOrder, sizeof(defColumnOrder));
- else
- memcpy(edit_columnOrder, defColumnOrderCloud, sizeof(defColumnOrderCloud));
- SendMessage(m_curlistbox_hwnd, LB_RESETCONTENT, 0, 0);
- SendMessage(m_availlistbox_hwnd, LB_RESETCONTENT, 0, 0);
- SendMessage(hwndDlg, WM_USER + 32, 0, 0);
- break;
- case IDC_LIST2:
- if (HIWORD(wParam) != LBN_DBLCLK)
- {
- if (HIWORD(wParam) == LBN_SELCHANGE)
- {
- int r = SendMessage(m_availlistbox_hwnd, LB_GETSELCOUNT, 0, 0) > 0;
- EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON2), r);
- }
- return 0;
- }
- case IDC_BUTTON2:
- //add column
- {
- for (int i = 0;i < SendMessage(m_availlistbox_hwnd, LB_GETCOUNT, 0, 0);i++)
- {
- if (SendMessage(m_availlistbox_hwnd, LB_GETSEL, i, 0))
- {
- int c = SendMessage(m_availlistbox_hwnd, LB_GETITEMDATA, i, 0);
- int j;
- for (j = 0;edit_columnOrder[j] != -1;j++);
- edit_columnOrder[j] = (BYTE)c;
- edit_columnOrder[j + 1] = -1;
- SendMessage(m_availlistbox_hwnd, LB_DELETESTRING, i, 0);
- i--;
- int r = SendMessageW(m_curlistbox_hwnd, LB_ADDSTRING, 0, (LPARAM)WASABI_API_LNGSTRINGW(columnList[c].column_id));
- SendMessageW(m_curlistbox_hwnd, LB_SETITEMDATA, r, c);
- }
- }
- EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON2), 0);
- }
- break;
- case IDC_LIST1:
- if (HIWORD(wParam) != LBN_DBLCLK)
- {
- if (HIWORD(wParam) == LBN_SELCHANGE)
- {
- int r = SendMessage(m_curlistbox_hwnd, LB_GETSELCOUNT, 0, 0) > 0;
- EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON3), r);
- EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON4), r);
- EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON5), r);
- }
- return 0;
- }
- case IDC_BUTTON3:
- //remove column
- {
- for (int i = 0;i < SendMessage(m_curlistbox_hwnd, LB_GETCOUNT, 0, 0);i++)
- {
- if (SendMessage(m_curlistbox_hwnd, LB_GETSEL, i, 0))
- {
- int c = edit_columnOrder[i];
- for (int j = i;edit_columnOrder[j] != -1;j++)
- {
- edit_columnOrder[j] = edit_columnOrder[j + 1];
- }
- SendMessage(m_curlistbox_hwnd, LB_DELETESTRING, i, 0);
- i--;
- int r = SendMessageW(m_availlistbox_hwnd, LB_ADDSTRING, 0, (LPARAM)WASABI_API_LNGSTRINGW(columnList[c].column_id));
- SendMessageW(m_availlistbox_hwnd, LB_SETITEMDATA, r, c);
- }
- }
- EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON3), 0);
- EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON4), 0);
- EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON5), 0);
- }
- break;
- case IDC_BUTTON4:
- //move column up
- {
- for (int i = 0;i < (INT)SendMessage(m_curlistbox_hwnd, LB_GETCOUNT, 0, 0);i++)
- {
- if (i != 0 && (INT)SendMessage(m_curlistbox_hwnd, LB_GETSEL, i, 0))
- {
- BYTE c = edit_columnOrder[i - 1];
- edit_columnOrder[i - 1] = edit_columnOrder[i];
- edit_columnOrder[i] = c;
- SendMessage(m_curlistbox_hwnd, LB_DELETESTRING, i - 1, 0);
- int r = (INT)SendMessageW(m_curlistbox_hwnd, LB_INSERTSTRING, i, (LPARAM)WASABI_API_LNGSTRINGW(columnList[c].column_id));
- SendMessage(m_curlistbox_hwnd, LB_SETITEMDATA, r, c);
- }
- }
- }
- break;
- case IDC_BUTTON5:
- //move column down
- {
- int l = SendMessage(m_curlistbox_hwnd, LB_GETCOUNT, 0, 0);
- for (int i = l - 2;i >= 0;i--)
- {
- if (SendMessage(m_curlistbox_hwnd, LB_GETSEL, i, 0))
- {
- BYTE c = edit_columnOrder[i + 1];
- edit_columnOrder[i + 1] = edit_columnOrder[i];
- edit_columnOrder[i] = c;
- SendMessage(m_curlistbox_hwnd, LB_DELETESTRING, i + 1, 0);
- int r = (INT)SendMessageW(m_curlistbox_hwnd, LB_INSERTSTRING, i, (LPARAM)WASABI_API_LNGSTRINGW(columnList[c].column_id));
- SendMessage(m_curlistbox_hwnd, LB_SETITEMDATA, r, c);
- }
- }
- }
- break;
- case IDOK:
- {
- HWND hwndList = resultlist.getwnd();
- memcpy(columnOrder, edit_columnOrder, sizeof(edit_columnOrder));
- if (hwndList)
- {
- initColumnsHeader(hwndList);
- InvalidateRect(hwndList, NULL, TRUE);
- UpdateWindow(hwndList);
- }
- }
- case IDCANCEL:
- EndDialog(hwndDlg, 0);
- break;
- }
- break;
- case WM_DESTROY:
- if (NULL != WASABI_API_APP)
- {
- if (NULL != m_curlistbox_hwnd)
- WASABI_API_APP->DirectMouseWheel_EnableConvertToMouseWheel(m_curlistbox_hwnd, FALSE);
- if (NULL != m_availlistbox_hwnd)
- WASABI_API_APP->DirectMouseWheel_EnableConvertToMouseWheel(m_availlistbox_hwnd, FALSE);
- WASABI_API_APP->app_removeAccelerators(hwndDlg);
- }
- break;
- }
- return FALSE;
- }
- void customizeColumnsDialog(HWND hwndParent)
- {
- WASABI_API_DIALOGBOXW(IDD_CUSTCOLUMNS, hwndParent, custColumns_dialogProc);
- EatKeyboard();
- }
- bool isMixable(itemRecordW &song)
- {
- if (!song.filename) return false;
- AutoChar charFn(song.filename);
- pluginMessage p = {ML_MSG_PDXS_STATUS, (INT_PTR)(char *)charFn, 0, 0};
- char *text = (char *)SendMessage(plugin.hwndLibraryParent, WM_ML_IPC, (WPARAM) & p, ML_IPC_SEND_PLUGIN_MESSAGE);
- // Analyzed/Identified = mixable
- return text && (text[0] == 'A' || text[0] == 'I');
- }
- void AccessingGracenoteHack(int p)
- {
- if (p == 0)
- {
- GetDlgItemTextW(m_hwnd, IDC_MEDIASTATUS, oldText, 4096);
- SetDlgItemTextW(m_hwnd, IDC_MEDIASTATUS, L"Accessing Gracenote Database");
- }
- else
- {
- SetDlgItemTextW(m_hwnd, IDC_MEDIASTATUS, oldText);
- }
- }
|