xuidownloadslist.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. #include <precomp.h>
  2. #include "xuidownloadslist.h"
  3. #include "wa2frontend.h"
  4. #include <api/wnd/popup.h>
  5. #include <bfc/parse/pathparse.h>
  6. #ifndef _WASABIRUNTIME
  7. BEGIN_SERVICES(DownloadsList_Svc);
  8. DECLARE_SERVICE(XuiObjectCreator<DownloadsListXuiSvc>);
  9. END_SERVICES(DownloadsList_Svc, _DownloadsList_Svc);
  10. #ifdef _X86_
  11. extern "C" { int _link_DownloadsListXuiSvc; }
  12. #else
  13. extern "C" { int __link_DownloadsListXuiSvc; }
  14. #endif
  15. #endif
  16. // -----------------------------------------------------------------------
  17. const wchar_t DownloadsListXuiObjectStr[] = L"DownloadsList"; // This is the xml tag
  18. char DownloadsListXuiSvcName[] = "DownloadsList xui object";
  19. XMLParamPair DownloadsList::params[] = {
  20. {CTLIST_NOHSCROLL, L"NOHSCROLL"},
  21. };
  22. // -----------------------------------------------------------------------
  23. DownloadsList::DownloadsList ()
  24. {
  25. setPreventMultipleSelection(1);
  26. ensure_on_paint = -1;
  27. nohscroll = 1;
  28. setAutoSort(false);
  29. setVirtual(0);
  30. xuihandle = newXuiHandle();
  31. CreateXMLParameters(xuihandle);
  32. DownloadsList::skinObjects.addItem(this);
  33. }
  34. void DownloadsList::CreateXMLParameters(int master_handle)
  35. {
  36. //DOWNLOADSLIST_PARENT::CreateXMLParameters(master_handle);
  37. int numParams = sizeof(params) / sizeof(params[0]);
  38. hintNumberOfParams(xuihandle, numParams);
  39. for (int i = 0;i < numParams;i++)
  40. addParam(xuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
  41. }
  42. // -----------------------------------------------------------------------
  43. DownloadsList::~DownloadsList() {
  44. for (int i = 0; i != this->getNumItems(); i++)
  45. {
  46. const wchar_t * w = (const wchar_t *) this->getItemData(i);
  47. delete w;
  48. }
  49. DownloadsList::skinObjects.removeItem(this);
  50. }
  51. // -----------------------------------------------------------------------
  52. int DownloadsList::onInit()
  53. {
  54. DOWNLOADSLIST_PARENT::onInit();
  55. addColumn(LocalesManager::GetString(L"nullsoft.browser", 19),100);
  56. addColumn(LocalesManager::GetString(L"nullsoft.browser", 18), 95);
  57. ListColumn *urlCol = new ListColumn(LocalesManager::GetString(L"nullsoft.browser", 17), 0);
  58. insertColumn(urlCol);
  59. ListColumn *tCol = new ListColumn(LocalesManager::GetString(L"nullsoft.browser", 20), 0);
  60. insertColumn(tCol);
  61. // Load all previous downloads - we must begin from the end of our list
  62. for (int i = activeDownloads.getNumItems()-1; i != -1; i--)
  63. {
  64. if (activeDownloads.enumItem(i) == NULL)
  65. {
  66. activeDownloads.removeByPos(i);
  67. continue; // Next loop
  68. }
  69. newItem(STATUS_WAITING, activeDownloads.enumItem(i));
  70. }
  71. return 1;
  72. }
  73. // Prohibit list sorting ;)
  74. int DownloadsList::onColumnLabelClick (int col, int x, int y)
  75. {
  76. //do nothing
  77. return 1;
  78. }
  79. int DownloadsList::onColumnDblClick (int col, int x, int y)
  80. {
  81. //do nothing
  82. return 1;
  83. }
  84. // -----------------------------------------------------------------------
  85. int DownloadsList::onResize() {
  86. DOWNLOADSLIST_PARENT::onResize();
  87. if (nohscroll) {
  88. RECT r;
  89. getClientRect(&r);
  90. int nw = r.right-r.left - getColumn(0)->getWidth() - getColumn(1)->getWidth();
  91. ListColumn *cLoc = getColumn(2);
  92. ListColumn *cTit = getColumn(3);
  93. cLoc->setWidth((int)(nw*0.65));
  94. cTit->setWidth((int)(nw*0.35));
  95. }
  96. return 1;
  97. }
  98. // -----------------------------------------------------------------------
  99. void DownloadsList::onDoubleClick(int itemnum)
  100. {
  101. if (getItemData(itemnum) != NULL) wa2.playFile(this->getSubitemText(itemnum, 2));
  102. }
  103. // -----------------------------------------------------------------------
  104. int DownloadsList::onRightClick(int itemnum)
  105. {
  106. DOWNLOADSLIST_PARENT::onRightClick(itemnum);
  107. PopupMenu p;
  108. if (this->getItemData(itemnum) == NULL)
  109. p.addCommand(L"Wait for file to be transferred", 666, 0 , 1);
  110. else
  111. {
  112. p.addCommand(L"Play", 1, 0 , 0);
  113. p.addCommand(L"Enqueue", 2, 0 , 0);
  114. }
  115. int result = p.popAtMouse();
  116. switch (result)
  117. {
  118. case 1: wa2.playFile(this->getSubitemText(itemnum, 2)); break;
  119. case 2: wa2.enqueueFile(this->getSubitemText(itemnum, 2)); break;
  120. }
  121. return 1;
  122. }
  123. // -----------------------------------------------------------------------
  124. int DownloadsList::onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source) {
  125. if (!_wcsicmp(action, L"play_selected"))
  126. {
  127. int sel = getFirstItemSelected();
  128. if (sel > -1)
  129. {
  130. if (getItemData(sel) != NULL) wa2.playFile(this->getSubitemText(sel, 2));
  131. }
  132. else
  133. {
  134. boolean enq = false;
  135. for (int i = 0; i != getNumItems(); i++)
  136. {
  137. if (getItemData(i) != NULL)
  138. {
  139. if (!enq)
  140. {
  141. wa2.playFile(this->getSubitemText(i, 2));
  142. enq = true;
  143. }
  144. else
  145. wa2.enqueueFile(this->getSubitemText(i, 2));
  146. }
  147. }
  148. }
  149. return 1;
  150. }
  151. return DOWNLOADSLIST_PARENT::onAction(action, param, x, y, p1, p2, data, datalen, source);
  152. }
  153. // -----------------------------------------------------------------------
  154. /*int DownloadsList::getTextBold(LPARAM lParam) {
  155. if (WCSCASEEQLSAFE(WASABI_API_SKIN->colortheme_enumColorSet(lParam & 0xFFFF), WASABI_API_SKIN->colortheme_getColorSet())) return 1;
  156. return DOWNLOADSLIST_PARENT::getTextBold(lParam);
  157. }*/
  158. // -----------------------------------------------------------------------
  159. void DownloadsList::onSetVisible(int show) {
  160. DOWNLOADSLIST_PARENT::onSetVisible(show);
  161. /*if (show) loadThemes();
  162. else getDesktopParent()->setFocus();*/
  163. }
  164. // -----------------------------------------------------------------------
  165. int DownloadsList::setXuiParam(int _xuihandle, int xmlattrid, const wchar_t *name, const wchar_t *value) {
  166. if (xuihandle == _xuihandle) {
  167. switch (xmlattrid) {
  168. case CTLIST_NOHSCROLL: nohscroll = WTOI(value); return 1;
  169. }
  170. }
  171. return DOWNLOADSLIST_PARENT::setXuiParam(_xuihandle, xmlattrid, name, value);
  172. }
  173. int DownloadsList::onPaint(Canvas *canvas) {
  174. if (ensure_on_paint > -1) ensureItemVisible(ensure_on_paint);
  175. ensure_on_paint = -1;
  176. DOWNLOADSLIST_PARENT::onPaint(canvas);
  177. return 1;
  178. }
  179. void DownloadsList::newItem(int status, DownloadToken token)
  180. {
  181. uint64_t total=0;
  182. const char *url = 0;
  183. api_httpreceiver *http = WAC_API_DOWNLOADMANAGER->GetReceiver(token);
  184. if (http)
  185. {
  186. total = http->content_length();
  187. if (url == NULL)
  188. {
  189. url = http->get_url();//WAC_API_DOWNLOADMANAGER->GetUrl(token);
  190. if (!url)
  191. {
  192. url = "";
  193. }
  194. }
  195. }
  196. else
  197. {
  198. url = "";
  199. }
  200. uint64_t downloaded = WAC_API_DOWNLOADMANAGER->GetBytesDownloaded(token);
  201. wchar_t text[256] = {0};
  202. if (total)
  203. {
  204. if (total == downloaded)
  205. return; // Delete from list on skin-reload
  206. }
  207. StringCchPrintfW(text, 256, L"%I64u / %d %s", downloaded, total, _(L"bytes"));
  208. switch (status)
  209. {
  210. case STATUS_WAITING:
  211. insertItem(0, _(L"Waiting"), 0);
  212. break;
  213. case STATUS_TRANSFERRING:
  214. insertItem(0, _(L"Transferring"), 0);
  215. break;
  216. case STATUS_FINISHED:
  217. insertItem(0, _(L"Finished"), 0);
  218. break;
  219. case STATUS_ERROR:
  220. insertItem(0, _(L"Error"), 0);
  221. break;
  222. default:
  223. insertItem(0, L"", 0);
  224. break;
  225. }
  226. setSubItem(0, 1, text);
  227. setSubItem(0, 2, AutoWide(url));
  228. }
  229. /**
  230. * Static Managing of downloadlist
  231. * handled via callbacks from MediaDownloader
  232. */
  233. void DownloadsList::onDownloadStart (const char *url, DownloadToken token)
  234. {
  235. for(int i=0; i<skinObjects.getNumItems(); i++)
  236. {
  237. DownloadsList *tmp = skinObjects.enumItem(i);
  238. tmp->newItem(STATUS_WAITING, token);
  239. activeDownloads.addItem(token, 0); // dunno if we will need this later on...
  240. }
  241. }
  242. void DownloadsList::onDownloadTick (DownloadToken token)
  243. {
  244. int n = activeDownloads.searchItem(token);
  245. if (n < 0) return;
  246. uint64_t total=0;
  247. api_httpreceiver *http = WAC_API_DOWNLOADMANAGER->GetReceiver(token);
  248. if (http)
  249. {
  250. total = http->content_length();
  251. }
  252. uint64_t downloaded = WAC_API_DOWNLOADMANAGER->GetBytesDownloaded(token);
  253. uint64_t percent = 0;
  254. wchar_t text[256] = {0};
  255. wchar_t text2[64] = {0};
  256. if (total)
  257. {
  258. percent=downloaded*100;
  259. if (total)
  260. percent/=total;
  261. else
  262. percent=0;
  263. StringCchPrintfW(text, 256, L"%I64u / %d %s", downloaded/1024, total/1024, _(L"KB"));
  264. StringCchPrintfW(text2, 64, L"%s %d%%", _(L"Transferring"), percent);
  265. }
  266. else
  267. {
  268. StringCchPrintfW(text, 256, L"%I64u / %d %s", downloaded, total, _(L"KB"));
  269. StringCchPrintfW(text2, 64, _(L"Transferring"));
  270. }
  271. for(int i=0; i!=skinObjects.getNumItems(); i++)
  272. {
  273. DownloadsList *tmp = skinObjects.enumItem(i);
  274. tmp->setSubItem(n, 1, text);
  275. tmp->setItemLabel(n, text2);
  276. }
  277. }
  278. void DownloadsList::onDownloadEnd (DownloadToken token, const wchar_t * filename)
  279. {
  280. int n = activeDownloads.searchItem(token);
  281. if (n < 0) return;
  282. activeDownloads.setItem(NULL, n); // So we know the download is done!
  283. wchar_t artist[256] = {0};
  284. wchar_t title[256] = {0};
  285. wa2.getMetaData(filename, L"artist", artist, 256);
  286. wa2.getMetaData(filename, L"title", title, 256);
  287. StringW display;
  288. bool hasArtist = !!WCSICMP(artist, L"");
  289. bool hasTitle= !!WCSICMP(title, L"");
  290. StringW url = L"";
  291. for(int i=0; i!=skinObjects.getNumItems(); i++)
  292. {
  293. DownloadsList *tmp = skinObjects.enumItem(i);
  294. if (!WCSICMP(url, L""))
  295. url = tmp->getSubitemText(n, 2);
  296. tmp->setItemLabel(n, _(L"Finished"));
  297. tmp->setSubItem(n, 2, filename);
  298. if (!hasArtist && !hasTitle)
  299. {
  300. PathParserW pp(filename);
  301. display = pp.getLastString();
  302. }
  303. else if (!hasArtist)
  304. display = title;
  305. else if (!hasTitle)
  306. display = artist;
  307. else
  308. display = StringPrintfW(L"%s - %s",artist,title);
  309. tmp->setSubItem(n, 3, display);
  310. tmp->setItemParam(n, STATUS_FINISHED);
  311. }
  312. }
  313. void DownloadsList::onDownloadCancel(DownloadToken token)
  314. {
  315. int n = activeDownloads.searchItem(token);
  316. if (n < 0) return;
  317. activeDownloads.setItem(NULL, n); // So we know the download is done/cancelled!
  318. const wchar_t * url = 0;
  319. for(int i=0; i!=skinObjects.getNumItems(); i++)
  320. {
  321. DownloadsList *tmp = skinObjects.enumItem(i);
  322. tmp->setItemLabel(n, _(L"Cancelled"));
  323. if (!url) url = tmp->getSubitemText(n, 2);
  324. }
  325. SystemObject::onDownloadFinished((!url ? L"" : url), false, L"");
  326. }
  327. void DownloadsList::onDownloadError(DownloadToken token, int code)
  328. {
  329. int n = activeDownloads.searchItem(token);
  330. if (n < 0) return;
  331. activeDownloads.setItem(NULL, n); // So we know the download is done/cancelled!
  332. const wchar_t * url = 0;
  333. for(int i=0; i!=skinObjects.getNumItems(); i++)
  334. {
  335. DownloadsList *tmp = skinObjects.enumItem(i);
  336. wchar_t buf[64] = {0};
  337. StringCchPrintfW(buf, 64, L"%s: %i", _(L"Error"), code);
  338. tmp->setItemLabel(n, buf);
  339. if (!url) url = tmp->getSubitemText(n, 2);
  340. }
  341. SystemObject::onDownloadFinished((!url ? L"" : url), false, L"");
  342. }
  343. PtrList<void> DownloadsList::activeDownloads;
  344. PtrList<DownloadsList> DownloadsList::skinObjects;