fileview_format.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. #include "./fileview.h"
  2. #include "./fileview_internal.h"
  3. #include "./resource.h"
  4. #include <strsafe.h>
  5. INT FileView_FormatFileTime(FILETIME *pft, LPWSTR pszDest, INT cchDest)
  6. {
  7. SYSTEMTIME st;
  8. if (!pszDest) return 0;
  9. pszDest[0] = 0x00;
  10. if (!pft || (0 == pft->dwHighDateTime && 0 == pft->dwLowDateTime)) return 0;
  11. if (FileTimeToSystemTime(pft, &st))
  12. {
  13. INT len;
  14. len = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, pszDest, cchDest);
  15. if (0 == len) return 0;
  16. cchDest -= len;
  17. if (cchDest > 0)
  18. {
  19. pszDest += len;
  20. *(pszDest - 1) = L' ';
  21. INT len2;
  22. len2 = GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, pszDest, cchDest);
  23. if (0 == len2) return 0;
  24. len += len2;
  25. return len - 1;
  26. }
  27. return len;
  28. }
  29. return 0;
  30. }
  31. INT FileView_FormatType(UINT fileType, LPWSTR pszDest, INT cchDest)
  32. {
  33. if (!pszDest) return 0;
  34. pszDest[0] = 0x00;
  35. INT strId;
  36. switch(fileType)
  37. {
  38. case FVFT_AUDIO: strId = IDS_FILETYPE_AUDIO; break;
  39. case FVFT_VIDEO: strId = IDS_FILETYPE_VIDEO; break;
  40. case FVFT_PLAYLIST: strId = IDS_FILETYPE_PLAYLIST; break;
  41. default: strId = IDS_FILETYPE_UNKNOWN; break;
  42. }
  43. WASABI_API_LNGSTRINGW_BUF(strId, pszDest, cchDest);
  44. return lstrlenW(pszDest);
  45. }
  46. INT FileView_FormatAttributes(UINT uAttributes, LPWSTR pszDest, INT cchDest)
  47. {
  48. if (!pszDest) return 0;
  49. pszDest[0] = 0x00;
  50. wchar_t szAttrib[32] = {0};
  51. if(!WASABI_API_LNGSTRINGW_BUF(IDS_FILE_ATTRIBUTES, szAttrib, sizeof(szAttrib)/sizeof(szAttrib[0])))
  52. szAttrib[0] = L'\0';
  53. INT len = 0;
  54. if (len < cchDest && (FILE_ATTRIBUTE_READONLY & uAttributes)) { pszDest[len] = szAttrib[0]; len++; }
  55. if (len < cchDest && (FILE_ATTRIBUTE_HIDDEN & uAttributes)) { pszDest[len] = szAttrib[1]; len++; }
  56. if (len < cchDest && (FILE_ATTRIBUTE_SYSTEM & uAttributes)) { pszDest[len] = szAttrib[2]; len++; }
  57. if (len < cchDest && (FILE_ATTRIBUTE_ARCHIVE & uAttributes)) { pszDest[len] = szAttrib[3]; len++; }
  58. if (len < cchDest && (FILE_ATTRIBUTE_COMPRESSED & uAttributes)) { pszDest[len] = szAttrib[4]; len++; }
  59. if (len < cchDest && (FILE_ATTRIBUTE_ENCRYPTED & uAttributes)) { pszDest[len] = szAttrib[5]; len++; }
  60. if (len < cchDest) pszDest[len] = 0x00;
  61. return len;
  62. }
  63. INT FileView_FormatYesNo(BOOL bValue, LPWSTR pszDest, INT cchDest)
  64. {
  65. if (!pszDest) return 0;
  66. pszDest[0] = 0x00;
  67. WASABI_API_LNGSTRINGW_BUF(((bValue) ? IDS_YES : IDS_NO), pszDest, cchDest);
  68. return lstrlenW(pszDest);
  69. }
  70. INT FileView_FormatYear(INT nYear, LPWSTR pszDest, INT cchDest)
  71. {
  72. if (nYear < 1 || S_OK != StringCchPrintfW(pszDest, cchDest, L"%d", nYear)) *pszDest = L'\0';
  73. return lstrlenW(pszDest);
  74. }
  75. INT FileView_FormatBitrate(INT nBitrate, LPWSTR pszDest, INT cchDest)
  76. {
  77. if (nBitrate < 1 || S_OK != StringCchPrintfW(pszDest, cchDest, L"%d%s", nBitrate, WASABI_API_LNGSTRINGW(IDS_KBPS))) *pszDest = L'\0';
  78. return lstrlenW(pszDest);
  79. }
  80. INT FileView_FormatLength(INT nLength, LPWSTR pszDest, INT cchDest)
  81. {
  82. if (nLength < 1 || S_OK != StringCchPrintfW(pszDest, cchDest, L"%d:%02d:%02d",
  83. nLength / (60 * 60), (nLength % (60 * 60)) / 60, nLength % 60)) *pszDest = L'\0';
  84. return lstrlenW(pszDest);
  85. }
  86. INT FileView_FormatIntSlashInt(INT part1, INT part2, LPWSTR pszDest, INT cchDest)
  87. {
  88. if (part1 > 0)
  89. {
  90. size_t remaining = cchDest;
  91. HRESULT hr = (part2 > 0) ? StringCchPrintfExW(pszDest, cchDest, NULL, &remaining, STRSAFE_IGNORE_NULLS, L"%d/%d", part1, part2) :
  92. StringCchPrintfExW(pszDest, cchDest, NULL, &remaining, STRSAFE_IGNORE_NULLS, L"%d", part1);
  93. if (S_OK != hr) *pszDest = L'\0';
  94. if (remaining != (size_t)cchDest) remaining;
  95. return (S_OK == hr) ? (cchDest - (INT)remaining) : 0;
  96. }
  97. else
  98. {
  99. *pszDest = L'\0';
  100. return 0;
  101. }
  102. }
  103. static void FileView_FormatPlaylistTip(FILERECORD *pfr, LPWSTR pszText, size_t cchTextMax, LPCWSTR pszSeparator)
  104. {
  105. INT nLines = 0;
  106. if (!pfr->pMeta || METATYPE_PLAYLIST != pfr->pMeta->type) return;
  107. PLAYLISTMETA *plm = &pfr->pMeta->playlist;
  108. if (plm->pszTitle && *plm->pszTitle && cchTextMax > 2)
  109. {
  110. if (S_OK != StringCchPrintfExW(pszText, cchTextMax, &pszText, &cchTextMax, STRSAFE_IGNORE_NULLS,
  111. L"%s: %s", WASABI_API_LNGSTRINGW(IDS_FILEVIEW_COL_TITLE), plm->pszTitle)) return;
  112. nLines++;
  113. }
  114. LPCWSTR pszExt = FileView_GetTypeFamily(pfr->Info.cFileName + pfr->extOffset);
  115. if (pszExt && *pszExt)
  116. {
  117. if (S_OK != StringCchPrintfExW(pszText, cchTextMax, &pszText, &cchTextMax, STRSAFE_IGNORE_NULLS,
  118. L"%s%s: %s", ((!nLines) ? L"" : pszSeparator), WASABI_API_LNGSTRINGW(IDS_FILEVIEW_COL_TYPE), pszExt)) return;
  119. nLines++;
  120. }
  121. if (plm->nLength > 0 && cchTextMax > 2)
  122. {
  123. if (S_OK != StringCchPrintfExW(pszText, cchTextMax, &pszText, &cchTextMax, STRSAFE_IGNORE_NULLS,
  124. L"%s%s: ", ((!nLines) ? L"" : pszSeparator), WASABI_API_LNGSTRINGW(IDS_FILEVIEW_COL_TOTALLENGTH))) return;
  125. size_t len = FileView_FormatLength(plm->nLength, pszText, (INT)cchTextMax);
  126. pszText += len;
  127. cchTextMax -= (len + 1);
  128. nLines++;
  129. }
  130. if (cchTextMax > 2)
  131. {
  132. if (S_OK != StringCchPrintfExW(pszText, cchTextMax, &pszText, &cchTextMax, STRSAFE_IGNORE_NULLS,
  133. L"%s%s: %d", ((!nLines) ? L"" : pszSeparator), WASABI_API_LNGSTRINGW(IDS_FILEVIEW_COL_ENTRYCOUNT), plm->nCount)) return;
  134. nLines++;
  135. }
  136. for (UINT i = 0; i < sizeof(plm->szEntries)/sizeof(plm->szEntries[0]) && i < plm->nCount; i++)
  137. {
  138. if (S_OK != StringCchPrintfExW(pszText, cchTextMax, &pszText, &cchTextMax, STRSAFE_IGNORE_NULLS,
  139. L"%s%02d. %s", ((!nLines) ? L"" : pszSeparator), (i + 1), plm->szEntries[i].pszTitle)) return;
  140. nLines++;
  141. }
  142. if (plm->nCount > sizeof(plm->szEntries)/sizeof(plm->szEntries[0]))
  143. {
  144. if (S_OK != StringCchPrintfExW(pszText, cchTextMax, &pszText, &cchTextMax, STRSAFE_IGNORE_NULLS,
  145. L"%s>>>", ((!nLines) ? L"" : pszSeparator))) return;
  146. nLines++;
  147. }
  148. }
  149. static void FileView_FormatAudioTip(FILERECORD *pfr, LPWSTR pszText, size_t cchTextMax, LPCWSTR pszSeparator)
  150. {
  151. size_t len;
  152. INT nLines = 0;
  153. if (!pfr->pMeta || METATYPE_AUDIO != pfr->pMeta->type) return;
  154. AUDIOMETA *pam = &pfr->pMeta->audio;
  155. if (pam->pszArtist && *pam->pszArtist && cchTextMax > 2)
  156. {
  157. if (S_OK != StringCchPrintfExW(pszText, cchTextMax, &pszText, &cchTextMax, STRSAFE_IGNORE_NULLS,
  158. L"%s: %s", WASABI_API_LNGSTRINGW(IDS_FILEVIEW_COL_ARTIST), pam->pszArtist)) return;
  159. nLines++;
  160. }
  161. if (pam->pszAlbum && *pam->pszAlbum && cchTextMax > 2)
  162. {
  163. if (S_OK != StringCchPrintfExW(pszText, cchTextMax, &pszText, &cchTextMax, STRSAFE_IGNORE_NULLS,
  164. L"%s%s: %s", ((!nLines) ? L"" : pszSeparator), WASABI_API_LNGSTRINGW(IDS_FILEVIEW_COL_ALBUM), pam->pszAlbum)) return;
  165. nLines++;
  166. }
  167. if (pam->pszTitle && *pam->pszTitle && cchTextMax > 2)
  168. {
  169. if (S_OK != StringCchPrintfExW(pszText, cchTextMax, &pszText, &cchTextMax, STRSAFE_IGNORE_NULLS,
  170. L"%s%s: %s", ((!nLines) ? L"" : pszSeparator), WASABI_API_LNGSTRINGW(IDS_FILEVIEW_COL_TITLE), pam->pszTitle)) return;
  171. nLines++;
  172. }
  173. if (pam->nYear > 0 && cchTextMax > 2)
  174. {
  175. if (S_OK != StringCchPrintfExW(pszText, cchTextMax, &pszText, &cchTextMax, STRSAFE_IGNORE_NULLS,
  176. L"%s%s: %d", ((!nLines) ? L"" : pszSeparator), WASABI_API_LNGSTRINGW(IDS_FILEVIEW_COL_YEAR), pam->nYear)) return;
  177. nLines++;
  178. }
  179. if (pam->pszGenre && *pam->pszGenre && cchTextMax > 2)
  180. {
  181. if (S_OK != StringCchPrintfExW(pszText, cchTextMax, &pszText, &cchTextMax, STRSAFE_IGNORE_NULLS,
  182. L"%s%s: %s", ((!nLines) ? L"" : pszSeparator), WASABI_API_LNGSTRINGW(IDS_FILEVIEW_COL_GENRE), pam->pszGenre)) return;
  183. nLines++;
  184. }
  185. if (pam->nLength > 0 && cchTextMax > 2)
  186. {
  187. if (S_OK != StringCchPrintfExW(pszText, cchTextMax, &pszText, &cchTextMax, STRSAFE_IGNORE_NULLS,
  188. L"%s%s: ", ((!nLines) ? L"" : pszSeparator), WASABI_API_LNGSTRINGW(IDS_FILEVIEW_COL_LENGTH))) return;
  189. len = FileView_FormatLength(pam->nLength, pszText, (INT)cchTextMax);
  190. pszText += len;
  191. cchTextMax -= (len + 1);
  192. nLines++;
  193. }
  194. if (pam->nTrackNum > 0 && cchTextMax > 2)
  195. {
  196. if (S_OK != StringCchPrintfExW(pszText, cchTextMax, &pszText, &cchTextMax, STRSAFE_IGNORE_NULLS,
  197. L"%s%s: ", ((!nLines) ? L"" : pszSeparator), WASABI_API_LNGSTRINGW(IDS_FILEVIEW_COL_TRACK))) return;
  198. len = FileView_FormatIntSlashInt(pam->nTrackNum, pam->nTrackCount, pszText, (INT)cchTextMax);
  199. pszText += len;
  200. cchTextMax -= (len + 1);
  201. nLines++;
  202. }
  203. if (pam->nDiscNum > 0 && cchTextMax > 2)
  204. {
  205. if (S_OK != StringCchPrintfExW(pszText, cchTextMax, &pszText, &cchTextMax, STRSAFE_IGNORE_NULLS,
  206. L"%s%s: ", ((!nLines) ? L"" : pszSeparator), WASABI_API_LNGSTRINGW(IDS_FILEVIEW_COL_DISC))) return;
  207. len = FileView_FormatIntSlashInt(pam->nDiscNum, pam->nDiscCount, pszText, (INT)cchTextMax);
  208. pszText += len;
  209. cchTextMax -= (len + 1);
  210. nLines++;
  211. }
  212. if (pam->nBitrate > 0 && cchTextMax > 2)
  213. {
  214. if (S_OK != StringCchPrintfExW(pszText, cchTextMax, &pszText, &cchTextMax, STRSAFE_IGNORE_NULLS,
  215. L"%s%s: ", ((!nLines) ? L"" : pszSeparator), WASABI_API_LNGSTRINGW(IDS_FILEVIEW_COL_BITRATE))) return;
  216. len = FileView_FormatBitrate(pam->nBitrate, pszText, (INT)cchTextMax);
  217. pszText += len;
  218. cchTextMax -= (len + 1);
  219. nLines++;
  220. }
  221. LPCWSTR pszExt = FileView_GetTypeFamily(pfr->Info.cFileName + pfr->extOffset);
  222. if (pszExt && *pszExt)
  223. {
  224. if (S_OK != StringCchPrintfExW(pszText, cchTextMax, &pszText, &cchTextMax, STRSAFE_IGNORE_NULLS,
  225. L"%s%s: %s", ((!nLines) ? L"" : pszSeparator), WASABI_API_LNGSTRINGW(IDS_FILEVIEW_COL_TYPE), pszExt)) return;
  226. nLines++;
  227. }
  228. if (pam->nSource != METADATA_SOURCE_UNKNOWN && cchTextMax > 2)
  229. {
  230. if (S_OK != StringCchPrintfExW(pszText, cchTextMax, &pszText, &cchTextMax, STRSAFE_IGNORE_NULLS,
  231. L"%s%s: ", ((!nLines) ? L"" : pszSeparator), WASABI_API_LNGSTRINGW(IDS_FILEVIEW_COL_INMLDB))) return;
  232. len = FileView_FormatYesNo(METADATA_SOURCE_MLDB == pam->nSource, pszText, (INT)cchTextMax);
  233. pszText += len;
  234. cchTextMax -= (len + 1);
  235. nLines++;
  236. }
  237. if (cchTextMax > 2)
  238. {
  239. if (S_OK != StringCchPrintfExW(pszText, cchTextMax, &pszText, &cchTextMax, STRSAFE_IGNORE_NULLS,
  240. L"%s%s: ", ((!nLines) ? L"" : pszSeparator), WASABI_API_LNGSTRINGW(IDS_FILEVIEW_COL_SIZE))) return;
  241. WASABI_API_LNG->FormattedSizeString(pszText, (INT)cchTextMax, (((__int64)pfr->Info.nFileSizeHigh << 32) | pfr->Info.nFileSizeLow));
  242. len = lstrlenW(pszText);
  243. pszText += len;
  244. cchTextMax -= (len + 1);
  245. nLines++;
  246. }
  247. }
  248. void FileView_FormatDefaultTip(FILERECORD *pfr, LPWSTR pszText, size_t cchTextMax, LPCWSTR pszSeparator)
  249. {
  250. size_t len;
  251. if ((len = lstrlenW(pszText)) > 0) { cchTextMax -= len; pszText += len; }
  252. if (S_OK != StringCchPrintfExW(pszText, cchTextMax, &pszText, &cchTextMax, STRSAFE_IGNORE_NULLS,
  253. L"%s: ", WASABI_API_LNGSTRINGW(IDS_FILEVIEW_COL_TYPE))) return;
  254. len = FileView_FormatType(pfr->fileType, pszText, (INT)cchTextMax);
  255. pszText += len;
  256. cchTextMax -= (len + 1);
  257. if (S_OK != StringCchPrintfExW(pszText, cchTextMax, &pszText, &cchTextMax, STRSAFE_IGNORE_NULLS,
  258. L"%s%s: ", pszSeparator, WASABI_API_LNGSTRINGW(IDS_FILEVIEW_COL_MODIFIED))) return;
  259. len = FileView_FormatFileTime(&pfr->Info.ftLastWriteTime, pszText, (INT)cchTextMax);
  260. pszText += len;
  261. cchTextMax -= (len + 1);
  262. if (S_OK != StringCchPrintfExW(pszText, cchTextMax, &pszText, &cchTextMax, STRSAFE_IGNORE_NULLS,
  263. L"%s%s: ", pszSeparator, WASABI_API_LNGSTRINGW(IDS_FILEVIEW_COL_SIZE))) return;
  264. WASABI_API_LNG->FormattedSizeString(pszText, (INT)cchTextMax, (((__int64)pfr->Info.nFileSizeHigh << 32) | pfr->Info.nFileSizeLow));
  265. len = lstrlenW(pszText);
  266. pszText += len;
  267. cchTextMax -= (len + 1);
  268. }
  269. void FileView_FormatFileInfo(FILERECORD *pfr, LPWSTR pszText, size_t cchTextMax, UINT uMode)
  270. {
  271. LPCWSTR pszSeparator;
  272. switch(uMode)
  273. {
  274. case FIF_STATUS: pszSeparator = L" "; break;
  275. case FIF_TOOLTIP:
  276. default: pszSeparator = L"\r\n"; break;
  277. }
  278. switch(pfr->fileType)
  279. {
  280. case FVFT_AUDIO:
  281. if (pfr->pMeta) { FileView_FormatAudioTip(pfr, pszText, cchTextMax, pszSeparator); return; }
  282. break;
  283. case FVFT_PLAYLIST:
  284. if (pfr->pMeta) { FileView_FormatPlaylistTip(pfr, pszText, cchTextMax, pszSeparator); return; }
  285. break;
  286. }
  287. FileView_FormatDefaultTip(pfr, pszText, cchTextMax, pszSeparator);
  288. }