]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | Pitchfork Music Player Daemon Client | |
3 | Copyright (C) 2007 Roger Bystrøm | |
4 | ||
5 | This program is free software; you can redistribute it and/or modify | |
6 | it under the terms of the GNU General Public License as published by | |
7 | the Free Software Foundation; version 2 of the License. | |
8 | ||
9 | This program is distributed in the hope that it will be useful, | |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | GNU General Public License for more details. | |
13 | ||
14 | You should have received a copy of the GNU General Public License along | |
15 | with this program; if not, write to the Free Software Foundation, Inc., | |
16 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
17 | */ | |
18 | ||
19 | /* this is so broken that I can hardly describe it */ | |
20 | ||
21 | var BROWSER_ID = "browser_"; | |
22 | var BROWSE_FILE = 0; | |
23 | var BROWSE_ARTIST = 1; | |
24 | var BROWSE_ALBUM = 2; | |
25 | var BROWSE_SEARCH = 3; | |
26 | ||
27 | var blist; | |
28 | ||
29 | var BROWSE_SEARCH_OPTS; | |
30 | ||
31 | function BrowserList(browser) { | |
32 | this.open_name = ""; | |
33 | this.open = null; | |
34 | this.first = null; | |
35 | this.type = BROWSE_FILE; | |
36 | this.type_name = new Array(); | |
37 | this.type_name[BROWSE_FILE] = LANG.FILESYSTEM; | |
38 | this.type_name[BROWSE_ARTIST] = LANG.ARTIST; | |
39 | this.type_name[BROWSE_ALBUM] = LANG.ALBUM; | |
40 | this.browser = browser; | |
41 | this.search = new KeySearch(null); // this is for key-typing in the fields, not the search field | |
42 | this.search_select = null; // jeje.. search field et al. | |
43 | this.search_field = null; | |
44 | this.search_opt = null; | |
45 | this.act_buttons = null; | |
46 | this.open_popup = null; | |
47 | this.eventListener = null; | |
48 | } | |
49 | ||
50 | function BrowserWindow(value) { | |
51 | this.value = value; | |
52 | this.next = null; | |
53 | } | |
54 | ||
55 | BrowserList.prototype.get_window_by_value = function (elem) { | |
56 | var w = this.first; | |
57 | while(w!=null) { | |
58 | if(w.value==elem) | |
59 | return w; | |
60 | w = w.next; | |
61 | } | |
62 | return null; | |
63 | } | |
64 | BrowserList.prototype.get_last_window = function() { | |
65 | var w = this.first; | |
66 | while(w.next!=null) | |
67 | w = w.next; | |
68 | return w; | |
69 | } | |
70 | ||
71 | BrowserList.prototype.get_previous_window = function(node) { | |
72 | var w = this.first; | |
73 | while(w!=null&&w.next!=node) | |
74 | w = w.next; | |
75 | return w; | |
76 | } | |
77 | BrowserList.prototype.get_next_window = function(node) { | |
78 | var w = this.first; | |
79 | while(w) { | |
80 | if(w==node) | |
81 | return w.next; | |
82 | w = w.next; | |
83 | } | |
84 | return null; | |
85 | } | |
86 | ||
87 | function dirlist_init() { | |
88 | BROWSE_SEARCH_OPTS = new Array(LANG.ANYTAG, LANG.ARTIST, LANG.TITLE, | |
89 | LANG.ALBUM, LANG.GENRE, LANG.FILENAME, LANG.COMPOSER, | |
90 | LANG.PERFORMER, LANG.DATE, LANG.LYRICS); | |
91 | ||
92 | remove_children(pl_overlay_write); | |
93 | send_command("dirlist", dirlist_init_handler); | |
94 | } | |
95 | ||
96 | function dirlist_init_handler(response) { | |
97 | if(response=="failure") { | |
98 | show_status_bar(LANG.E_FAILED_LOAD_DIR); | |
99 | } | |
100 | else { | |
101 | var ul; | |
102 | var ul_tmp = null; | |
103 | blist = new BrowserList(pl_overlay_write); | |
104 | var stuff = create_node("div"); | |
105 | stuff.className = "browse_type_container"; | |
106 | ||
107 | for(var i=0; i<blist.type_name.length; i++) { | |
108 | var n = create_node("p"); | |
109 | n.className = "browse_type"; | |
110 | n.appendChild(create_txt(blist.type_name[i])); | |
111 | stuff.appendChild(n); | |
112 | if(i==BROWSE_FILE) | |
113 | add_listener(n, "click", browse_file_init); | |
114 | else if(i==BROWSE_ARTIST) | |
115 | add_listener(n, "click", browse_artist_init); | |
116 | else if(i==BROWSE_ALBUM) | |
117 | add_listener(n, "click", browse_album_init); | |
118 | add_listener(n, "mousedown", stop_event); | |
119 | ||
120 | } | |
121 | ||
122 | var search = blist.search_select = create_search_choices(BROWSE_SEARCH_OPTS, browse_search_change); | |
123 | stuff.appendChild(search); | |
124 | var opt = blist.search_opt = create_node("option", "bs_search"); | |
125 | opt.value = "-1"; | |
126 | opt.appendChild(create_txt("Search:")); | |
127 | insert_first(opt, search); | |
128 | search.selectedIndex = 0; | |
129 | search.id ="browse_search_select"; | |
130 | ||
131 | blist.search_field = search = create_node("input", "browse_search_field"); | |
132 | search.className = "browse_type"; | |
133 | search.size = "20"; | |
134 | /* make sure it doesn't get captured by someone else */ | |
135 | add_listener(search, "keydown", stop_propagation); | |
136 | add_listener(search, "keyup", browser_search_field_keyhandler); | |
137 | search.disabled = "disabled"; | |
138 | stuff.appendChild(search); | |
139 | ||
140 | var update = create_node("p"); | |
141 | update.className = "browse_type"; | |
142 | update.appendChild(create_txt(LANG.UPDATE_DB)); | |
143 | add_listener(update, "click", send_update_db_cmd); | |
144 | stuff.appendChild(update); | |
145 | ||
146 | blist.browser.appendChild(stuff); | |
147 | ||
148 | var buttons = blist.act_buttons = create_node("ul", "browser_act_buttons"); | |
149 | var btn; | |
150 | ||
151 | var bl = new Array(); | |
152 | for(var i=0; i<BROWSER_NUM; i++) { | |
153 | ul = create_node("ul", BROWSER_ID + i); | |
154 | bl[i] = ul; | |
155 | ul.className = "browser_field"; | |
156 | blist.browser.appendChild(ul); | |
157 | setup_dirlist_listeners(ul); | |
158 | ||
159 | btn = create_node("li", "browser_btn_add_" + i); | |
160 | btn.className = "browser_button_add"; | |
161 | if(i>0) | |
162 | btn.style.left = 29*i + "%"; | |
163 | btn.setAttribute("field", i); | |
164 | btn.appendChild(create_txt(LANG.ADD)); | |
165 | add_listener(btn, "click", browser_multi_add); | |
166 | buttons.appendChild(btn); | |
167 | } | |
168 | add_listener(buttons, "mousedown", stop_event); | |
169 | blist.browser.appendChild(buttons); | |
170 | /* link it up */ | |
171 | var last = null; | |
172 | for(var i=0; i<BROWSER_NUM; i++) { | |
173 | var bw = new BrowserWindow(bl[i]); | |
174 | if(i==0) | |
175 | blist.first = last = bw; | |
176 | else | |
177 | last = last.next = bw; | |
178 | } | |
179 | ||
180 | browser_fill_entry(blist.first.value, response, 0, ""); | |
181 | } | |
182 | } | |
183 | ||
184 | /* opts: array with options | |
185 | onchange_cb: what to call when something changes | |
186 | return: search box | |
187 | */ | |
188 | function create_search_choices(opts, onchange_cb) { | |
189 | var search = create_node("select"); | |
190 | search.className = "browse_type"; | |
191 | add_listener(search, "change", onchange_cb); | |
192 | var opt = null; | |
193 | for(var i=0; i<opts.length; i++) { | |
194 | opt = create_node("option"); | |
195 | opt.value = i; | |
196 | opt.appendChild(create_txt(opts[i])); | |
197 | search.appendChild(opt); | |
198 | } | |
199 | return search; | |
200 | } | |
201 | ||
202 | function browse_file_init() { | |
203 | browse_style_changed(BROWSE_FILE); | |
204 | } | |
205 | function browse_album_init() { | |
206 | browse_style_changed(BROWSE_ALBUM); | |
207 | } | |
208 | function browse_artist_init() { | |
209 | browse_style_changed(BROWSE_ARTIST); | |
210 | } | |
211 | function browse_search_change(e) { | |
212 | /* this is when opening the search browser */ | |
213 | if(blist.type!=BROWSE_SEARCH) { | |
214 | var w = blist.first; | |
215 | while(w) { | |
216 | browser_clear_window(w.value); | |
217 | w = w.next; | |
218 | } | |
219 | browse_style_changed(BROWSE_SEARCH); | |
220 | browser_search_field_enable(); | |
221 | } | |
222 | else { | |
223 | } | |
224 | } | |
225 | ||
226 | function browse_style_changed(type) { | |
227 | if(type==blist.type) | |
228 | return; | |
229 | ||
230 | /* this is when switching back to normal view from search */ | |
231 | if(blist.type==BROWSE_SEARCH) { | |
232 | var w = blist.first; | |
233 | while(w) { | |
234 | w.value.style.display = ""; | |
235 | w.value.style.width = ""; | |
236 | w = w.next; | |
237 | } | |
238 | browser_search_field_clear(); | |
239 | insert_first(blist.search_opt, blist.search_select); | |
240 | blist.search_opt.selected = "selected"; | |
241 | blist.search_select.blur(); // just in case it is selected.. | |
242 | browser_act_buttons_display(true); | |
243 | } | |
244 | else if(type==BROWSE_SEARCH) { | |
245 | // only show first | |
246 | var w = blist.first.next; | |
247 | while(w) { | |
248 | w.value.style.display = "none"; | |
249 | w = w.next; | |
250 | } | |
251 | ||
252 | blist.first.value.style.width = "95%"; | |
253 | browser_act_buttons_display(false); | |
254 | remove_node(blist.search_opt); | |
255 | } | |
256 | blist.type = type; | |
257 | if(type!=BROWSE_SEARCH) | |
258 | browser_open_single_item(blist.first.value); | |
259 | } | |
260 | function setup_dirlist_listeners(ul) { | |
261 | add_listener(ul, "click", browser_click); | |
262 | /* no text selection support: */ | |
263 | add_listener(ul, "mousedown", prevent_dirlist_default); | |
264 | } | |
265 | ||
266 | function prevent_dirlist_default(e) { | |
267 | if(e.target.hasAttribute("diritem")||e.target.parentNode.hasAttribute("diritem")) | |
268 | stop_event(e); | |
269 | } | |
270 | ||
271 | function browser_fill_entry(entry, resp, strip, parent_dir) { | |
272 | if(!strip) | |
273 | strip = 0; | |
274 | var p = null; | |
275 | var type = null; | |
276 | ||
277 | /* adding parent */ | |
278 | if(strip>0&&resp) { | |
279 | if(blist.type==BROWSE_FILE) { | |
280 | var tmp = add_li(entry, "< ..", entry.id + "_parent"); | |
281 | tmp.setAttribute("dirtype", "parent"); | |
282 | var name; | |
283 | ||
284 | out: | |
285 | for(var t in resp) { | |
286 | for(var i in resp[t]) { | |
287 | name = resp[t][i]; | |
288 | break out; | |
289 | } | |
290 | } | |
291 | ||
292 | if(name.substring) { | |
293 | name = name.substring(0,strip-1); | |
294 | tmp.setAttribute("diritem", name); | |
295 | entry.setAttribute("dirlist", name); | |
296 | } | |
297 | entry.setAttribute("parent_dir", parent_dir); | |
298 | } | |
299 | else { | |
300 | entry.setAttribute("dirlist", blist.open_name); | |
301 | entry.setAttribute("parent_dir", parent_dir); | |
302 | } | |
303 | } | |
304 | else { | |
305 | entry.setAttribute("dirlist", ""); | |
306 | } | |
307 | var strip_name = null; | |
308 | var rtype = null; | |
309 | for(var type in resp) { | |
310 | for(var idx in resp[type]) { | |
311 | name = resp[type][idx]; | |
312 | rtype = type; | |
313 | if(type=="filelist") { | |
314 | if(typeof(name['Title'])!='undefined'&&name["Title"].length) { | |
315 | strip_name = name["Title"]; | |
316 | name = name["file"]; | |
317 | } | |
318 | else { | |
319 | name = name["file"]; | |
320 | strip_name = name.substring(name.lastIndexOf(DIR_SEPARATOR)+1); | |
321 | } | |
322 | rtype = "file"; | |
323 | } | |
324 | else if(!name.substring) { | |
325 | continue; | |
326 | } | |
327 | else strip_name = name; | |
328 | ||
329 | if(type=="directory") { | |
330 | strip_name = name.substring(strip); | |
331 | } | |
332 | else if(type=="file"&&name.lastIndexOf(DIR_SEPARATOR)>=0) { | |
333 | strip_name = name.substring(name.lastIndexOf(DIR_SEPARATOR)+1); | |
334 | } | |
335 | ||
336 | var l = create_node("li", null, strip_name); | |
337 | l.setAttribute("diritem", name); | |
338 | l.setAttribute("dirtype", rtype); | |
339 | entry.appendChild(l); | |
340 | if(type=="playlist") | |
341 | add_playlist_hover(l); | |
342 | } | |
343 | } | |
344 | } | |
345 | ||
346 | function add_playlist_hover(l) { | |
347 | var h = create_node("div"); | |
348 | h.className = "playlist_hover"; | |
349 | var img = create_node("img"); | |
350 | img.src = IMAGE.BROWSER_PLAYLIST_REMOVE; | |
351 | img.className = "fakelink"; | |
352 | h.appendChild(img); | |
353 | add_listener(img, "click", show_remove_playlist); | |
354 | insert_first(h,l); | |
355 | } | |
356 | ||
357 | function show_remove_playlist(e) { | |
358 | var t = e.target.parentNode.parentNode; | |
359 | var name = t.getAttribute("diritem"); | |
360 | var content = document.createDocumentFragment(); | |
361 | content.appendChild(create_txt(LANG.CONFIRM_REMOVE + " '" + name + "'?")); | |
362 | var yes = create_node("span"); | |
363 | yes.className = "fakelink"; | |
364 | yes.appendChild(create_txt(" Yes,")); | |
365 | content.appendChild(yes); | |
366 | ||
367 | var no = create_node("span"); | |
368 | no.className = "fakelink"; | |
369 | no.appendChild(create_txt(" No")); | |
370 | content.appendChild(no); | |
371 | ||
372 | if(blist.open_popup) | |
373 | destroy_open_popup(); | |
374 | var pop = new Popup(document.body, content); | |
375 | blist.open_popup = pop; | |
376 | blist.eventListener = add_listener(document.body, "click", destroy_open_popup); | |
377 | add_listener(yes, "click", function() { remove_playlist(t) ; destroy_open_popup(); }); | |
378 | add_listener(no, "click", destroy_open_popup); | |
379 | pop.popup.style.padding = "5px 5px 5px 5px"; | |
380 | pop.popup.style.position = "absolute"; | |
381 | pop.popup.style.left = "80px"; | |
382 | pop.popup.style.top = "500px"; | |
383 | pop.popup.style.margin = "0 auto"; | |
384 | pop.show(); | |
385 | } | |
386 | ||
387 | function destroy_open_popup() { | |
388 | var blist = window.blist; // jic | |
389 | if(blist.open_popup) { | |
390 | blist.open_popup.destroy(); | |
391 | blist.open_popup = null; | |
392 | } | |
393 | if(blist.eventListener) { | |
394 | blist.eventListener.unregister(); | |
395 | blist.eventListener = null; | |
396 | } | |
397 | } | |
398 | ||
399 | function remove_playlist(elem) { | |
400 | var item = elem.getAttribute("diritem"); | |
401 | send_command("playlist_rm=" + encodeURIComponent(item), remove_playlist_cb); | |
402 | remove_node(elem); | |
403 | } | |
404 | ||
405 | function remove_playlist_cb(e) { | |
406 | if(e!="ok") { | |
407 | show_status_bar(LANG.E_FAILED_ADD); | |
408 | hide_status_bar(STATUS_DEFAULT_TIMEOUT); | |
409 | } | |
410 | } | |
411 | ||
412 | function browser_click(e) { | |
413 | stop_event(e); | |
414 | var elem = e.target; | |
415 | ||
416 | if(!elem||!elem.hasAttribute) return; | |
417 | ||
418 | /* test if we got one of the direct children as targets */ | |
419 | if(elem.parentNode&&elem.parentNode.hasAttribute("diritem")) | |
420 | elem = elem.parentNode; | |
421 | ||
422 | if(elem.hasAttribute&&elem.hasAttribute("diritem")) { | |
423 | e.stopPropagation(); | |
424 | var container = elem.parentNode; | |
425 | blist.search.focus = container; | |
426 | if(e.ctrlKey||e.metaKey) { | |
427 | if(is_node_selected(elem)) | |
428 | unselect_node(elem); | |
429 | else | |
430 | select_node(elem); | |
431 | // safari workaround | |
432 | container.className = container.className; | |
433 | } | |
434 | else if (e.shiftKey) { | |
435 | var sel_node = find_first_selected_node(container, elem); | |
436 | unselect_all_nodes(container); | |
437 | if(sel_node==null) { | |
438 | select_node(elem); | |
439 | } | |
440 | else { | |
441 | if(elem.hasAttribute("needle")) | |
442 | select_range(elem, sel_node); | |
443 | else | |
444 | select_range(sel_node, elem); | |
445 | } | |
446 | if(elem.hasAttribute("needle")) | |
447 | elem.removeAttribute("needle"); | |
448 | // safari workaround | |
449 | container.className = container.className; | |
450 | } | |
451 | else { | |
452 | browser_open_single_item(container, elem, e.detail==2); | |
453 | } | |
454 | } | |
455 | } | |
456 | ||
457 | function browser_open_single_item(container, elem, doubleclick) { | |
458 | unselect_all_nodes(container); | |
459 | var type; | |
460 | if(elem) { | |
461 | type = elem.getAttribute("dirtype"); | |
462 | select_node(elem); | |
463 | // safari workaround | |
464 | container.className = container.className; | |
465 | } | |
466 | else { | |
467 | type = "other"; | |
468 | } | |
469 | var b_id = blist.get_window_by_value(container); | |
470 | ||
471 | if(!doubleclick) { | |
472 | if(type=="directory"||type=="artist"||type=="album") { | |
473 | var diritem = elem.getAttribute("diritem") | |
474 | ||
475 | blist.open = b_id.next; | |
476 | blist.open_name = diritem; | |
477 | ||
478 | /* test if already open */ | |
479 | if(blist.open!=null) { | |
480 | // this item is already opened | |
481 | if(blist.open.value.getAttribute("dirlist")==diritem) | |
482 | return; | |
483 | } | |
484 | ||
485 | /* remove all entries in following rows */ | |
486 | var tmp = b_id.next; | |
487 | while(tmp!=null) { | |
488 | if(tmp.value.hasAttribute("dirlist")) | |
489 | tmp.value.removeAttribute("dirlist"); | |
490 | if(tmp.value.hasAttribute("parent_dir")) | |
491 | tmp.value.removeAttribute("parent_dir"); | |
492 | remove_children(tmp.value); | |
493 | tmp = tmp.next; | |
494 | } | |
495 | if(blist.type==BROWSE_ARTIST||blist.type==BROWSE_ALBUM){ | |
496 | var artist, album; | |
497 | if(blist.open == blist.get_last_window()) { | |
498 | if(blist.type==BROWSE_ARTIST) { | |
499 | artist = b_id.value.getAttribute("dirlist"); | |
500 | album = diritem; | |
501 | } | |
502 | else { | |
503 | album = b_id.value.getAttribute("dirlist"); | |
504 | artist = diritem; | |
505 | } | |
506 | send_command("searchfile&artist=" + encodeURIComponent(artist) + "&album=" + encodeURIComponent(album), browser_click_cb); | |
507 | return; | |
508 | } | |
509 | else if(blist.open==null) { | |
510 | // don't open | |
511 | return; | |
512 | } | |
513 | // else do as usual... | |
514 | } | |
515 | send_command("dirlist=" + encodeURIComponent(blist.open_name) + "&type=" + blist.type, browser_click_cb); | |
516 | } | |
517 | else if(type=="parent"||type=="other") { | |
518 | blist.open = blist.first; | |
519 | if(type=="parent") | |
520 | blist.open_name = blist.first.value.getAttribute("parent_dir"); | |
521 | else blist.open_name = ""; | |
522 | ||
523 | var w = blist.first; | |
524 | if(type=="parent") // || switch type... | |
525 | while(w!=null&&w!=b_id) | |
526 | w = w.next; | |
527 | while(w!=null){ | |
528 | browser_clear_window(w.value); | |
529 | w = w.next; | |
530 | } | |
531 | ||
532 | if(blist.first.value.getAttribute("dirlist")!=""||type=="other") { // already at top | |
533 | send_command("dirlist=" + encodeURIComponent(blist.open_name) + "&type=" + blist.type, browser_click_cb); | |
534 | } | |
535 | } | |
536 | } | |
537 | else if(doubleclick&&type!="parent") { | |
538 | var diritem = elem.getAttribute("diritem") | |
539 | blink_node(elem, DEFAULT_BLINK_COLOR); | |
540 | if(elem.getAttribute("dirtype")=="playlist") { | |
541 | send_command("playlist_load=" + encodeURIComponent(diritem), null, LANG.WAIT_ADDING); | |
542 | } | |
543 | else if((blist.type==BROWSE_ARTIST||blist.type==BROWSE_ALBUM)&&elem.getAttribute("dirtype")!="file") { | |
544 | var artist, album; | |
545 | if(b_id == blist.first.next) { | |
546 | if(blist.type==BROWSE_ARTIST) { | |
547 | artist = b_id.value.getAttribute("dirlist"); | |
548 | album = diritem; | |
549 | } | |
550 | else { | |
551 | album = b_id.value.getAttribute("dirlist"); | |
552 | artist = diritem; | |
553 | } | |
554 | send_command("searchadd&artist=" + encodeURIComponent(artist) + "&album=" + | |
555 | encodeURIComponent(album), browser_add_cb, LANG.WAIT_ADDING); | |
556 | } | |
557 | else if(b_id==blist.first) { | |
558 | var cmd = "searchadd&"; | |
559 | if(blist.type==BROWSE_ARTIST) { | |
560 | cmd+="artist="; | |
561 | } | |
562 | else { | |
563 | cmd+="album="; | |
564 | } | |
565 | cmd += encodeURIComponent(diritem); | |
566 | send_command(cmd, browser_add_cb, LANG.WAIT_ADDING); | |
567 | } | |
568 | } | |
569 | else { | |
570 | // else do as usual... | |
571 | send_command("add=" + encodeURIComponent(diritem), browser_add_cb, LANG.WAIT_ADDING); | |
572 | } | |
573 | } | |
574 | } | |
575 | ||
576 | function browser_click_cb(response) { | |
577 | var strip = 0; | |
578 | var parent_dir = null; | |
579 | if(blist.open==null) { | |
580 | // got to move it | |
581 | var last = blist.get_last_window(); | |
582 | var first = blist.first; | |
583 | var prev = blist.get_previous_window(last); | |
584 | parent_dir = prev.value.getAttribute("dirlist"); | |
585 | var tmp = first.value; | |
586 | ||
587 | while(tmp.hasChildNodes()) { | |
588 | remove_node(tmp.lastChild); | |
589 | } | |
590 | remove_node(tmp); | |
591 | insert_after(tmp, last.value); | |
592 | last.next = first; | |
593 | blist.first = first.next; | |
594 | first.next = null; | |
595 | blist.open = blist.get_last_window(); | |
596 | } | |
597 | else if (blist.open==blist.first) { | |
598 | parent_dir = blist.first.value.getAttribute("parent_dir"); | |
599 | if(parent_dir) | |
600 | parent_dir = parent_dir.substring(0,parent_dir.lastIndexOf(DIR_SEPARATOR)); | |
601 | ||
602 | var first = blist.first; | |
603 | var last = blist.get_last_window(); | |
604 | var prev = blist.get_previous_window(last); | |
605 | var tmp = last.value; | |
606 | while(tmp.hasChildNodes()) | |
607 | remove_node(tmp.lastChild); | |
608 | remove_node(tmp); | |
609 | insert_before(tmp, first.value) | |
610 | blist.first = last; | |
611 | last.next = first; | |
612 | prev.next = null; | |
613 | blist.open = blist.first; | |
614 | } | |
615 | var b = blist.open; | |
616 | var prev = blist.get_previous_window(b); | |
617 | if(parent_dir==null&&prev!=null) { | |
618 | parent_dir = prev.value.getAttribute("dirlist"); | |
619 | } | |
620 | else if(parent_dir==null) { | |
621 | parent_dir = ""; | |
622 | } | |
623 | ||
624 | if(blist.open_name.length>0) | |
625 | strip = blist.open_name.length + 1; | |
626 | ||
627 | browser_fill_entry(b.value, response, strip, parent_dir); | |
628 | blist.open_name = ""; | |
629 | blist.open = null; | |
630 | } | |
631 | ||
632 | function browser_add_cb(response) { | |
633 | if(response!="ok") { | |
634 | show_status_bar(LANG.E_FAILED_ADD); | |
635 | hide_status_bar(STATUS_DEFAULT_TIMEOUT); | |
636 | } | |
637 | } | |
638 | ||
639 | function pl_overlay_open_cb(height) { | |
640 | var elem = null; | |
641 | var i=0; | |
642 | var w = blist.first; | |
643 | while(w != null ) { | |
644 | /* this makes room for the top (filesys, artist, search et al.) and bottom (add etc) */ | |
645 | w.value.style.height = (height - 40)+ "px"; | |
646 | w = w.next; | |
647 | } | |
648 | blist.search.listener = keyboard_register_listener(browser_key_search, KEYBOARD_MATCH_ALL, KEYBOARD_NO_KEY, true); | |
649 | // TODO, maybe set broswer_focus | |
650 | } | |
651 | ||
652 | function pl_overlay_close_cb() { | |
653 | keyboard_remove_listener(blist.search.listener); | |
654 | } | |
655 | ||
656 | function browser_key_search(e) { | |
657 | if(!blist.search.focus) { | |
658 | return; | |
659 | } | |
660 | var clear_time = 1000; | |
661 | ||
662 | var c = blist.search.focus.childNodes; | |
663 | ||
664 | if(e.keyCode==38||e.keyCode==40||e.keyCode==37||e.keyCode==39) { | |
665 | var it = null; | |
666 | // find first selected node | |
667 | for(var i=0; i < c.length; i++) { | |
668 | if(is_node_selected(c[i])) { | |
669 | it = c[i]; | |
670 | break; | |
671 | } | |
672 | } | |
673 | if(it) { | |
674 | var win = null; | |
675 | if(e.keyCode==40&&it.nextSibling) { | |
676 | it = it.nextSibling; | |
677 | } | |
678 | else if(e.keyCode==38&&it.previousSibling) { | |
679 | it = it.previousSibling; | |
680 | } | |
681 | else if(e.keyCode==37) { // left | |
682 | // todo | |
683 | //win = blist.get_previous_window(blist.get_window_by_value(blist.search.focus)); | |
684 | it = null; | |
685 | } | |
686 | else if(e.keyCode==39) { // right | |
687 | // todo | |
688 | //win = blist.get_next_window(blist.get_window_by_value(blist.search.focus)); | |
689 | it = null; | |
690 | } | |
691 | else it = null; | |
692 | if(it) { | |
693 | unselect_all_nodes(blist.search.focus); | |
694 | select_node(it); | |
695 | scrollIntoView(it, false); | |
696 | blist.search.item = it; | |
697 | } | |
698 | else if (win) { | |
699 | win = win.value; | |
700 | blist.search.focus = win; | |
701 | unselect_all_nodes(win); | |
702 | select_node(win.firstChild) | |
703 | } | |
704 | blist.search.term = ""; | |
705 | } | |
706 | } | |
707 | else { | |
708 | var s = blist.search.term + String.fromCharCode(e.keyCode); | |
709 | blist.search.term = s = s.toLowerCase(); | |
710 | ||
711 | for(var i=0; i<c.length; i++) { | |
712 | var c_name = get_node_content(c[i]); | |
713 | if(!c_name||!c_name.toLowerCase) | |
714 | continue; | |
715 | c_name = c_name.toLowerCase(); | |
716 | if(c_name.indexOf(s)==0) { | |
717 | unselect_all_nodes(blist.search.focus); | |
718 | select_node(c[i]); | |
719 | scrollIntoView(c[i], false); | |
720 | blist.search.item = c[i]; | |
721 | break; | |
722 | } | |
723 | } | |
724 | } | |
725 | clearTimeout(blist.search.timer); | |
726 | blist.search.timer = setTimeout(browser_clear_search_term, clear_time); | |
727 | } | |
728 | function browser_clear_window(win) { | |
729 | remove_children(win); | |
730 | if(win.hasAttribute("dirlist")) | |
731 | win.removeAttribute("dirlist"); | |
732 | if(win.hasAttribute("parent_dir")) | |
733 | win.removeAttribute("parent_dir"); | |
734 | } | |
735 | ||
736 | /* clear key-search */ | |
737 | function browser_clear_search_term() { | |
738 | blist.search.term = ""; | |
739 | if(blist.search.focus&&blist.search.item) { | |
740 | browser_open_single_item(blist.search.focus, blist.search.item); | |
741 | blist.search.item = null; | |
742 | } | |
743 | } | |
744 | ||
745 | function KeySearch(listener) { | |
746 | this.listener = listener; | |
747 | this.focus = null; | |
748 | this.term = ""; | |
749 | this.timer = null; | |
750 | } | |
751 | ||
752 | /* clear search field */ | |
753 | function browser_search_field_clear() { | |
754 | blist.search_field.value = ""; | |
755 | blist.search_field.disabled = "disabled"; | |
756 | blist.search_field.blur(); | |
757 | } | |
758 | ||
759 | function browser_search_field_enable() { | |
760 | blist.search_field.disabled = ""; | |
761 | blist.search_field.focus(); | |
762 | } | |
763 | ||
764 | function browser_search_field_keyhandler(e) { | |
765 | if(e.keyCode&&e.keyCode==RETURN_KEY_CODE) { | |
766 | if(blist.search_field.value.trim().length>0) { | |
767 | send_command("metasearch=" + blist.search_select.value + "&s=" + encodeURIComponent(blist.search_field.value), | |
768 | browser_search_field_keyhandler_cb, LANG.WAIT_SEARCHING); | |
769 | } | |
770 | else { | |
771 | remove_children(blist.first.value); | |
772 | } | |
773 | } | |
774 | } | |
775 | ||
776 | function browser_search_field_keyhandler_cb(resp) { | |
777 | var dst = blist.first.value; | |
778 | remove_children(dst); | |
779 | if(typeof(resp)!='undefined'&&resp!="failed") { | |
780 | for(var i=0; i<resp.length; i++) { | |
781 | var file = resp[i]["file"]; | |
782 | var artist = resp[i]["Artist"]; | |
783 | var title = resp[i]["Title"]; | |
784 | var name = ""; | |
785 | if(title==null||!title.length) { | |
786 | name = file.substring(file.lastIndexOf(DIR_SEPARATOR)+1); | |
787 | } | |
788 | else { | |
789 | name = artist + " - " + title; | |
790 | } | |
791 | ||
792 | var l = add_li(dst, name, dst.id + "_" + i); | |
793 | l.setAttribute("diritem", file); | |
794 | l.setAttribute("dirtype", "file"); | |
795 | /* used to match css selector */ | |
796 | l.setAttribute("btype", "search"); | |
797 | l.appendChild(create_node("br")); | |
798 | var fspan = create_node("span", null, file); | |
799 | l.appendChild(fspan); | |
800 | } | |
801 | } | |
802 | } | |
803 | ||
804 | function browser_act_buttons_display(visible) { | |
805 | var btn = blist.act_buttons.childNodes; | |
806 | for(var i=1; i<btn.length; i++) { | |
807 | btn[i].style.display = (visible?"":"none"); | |
808 | } | |
809 | } | |
810 | ||
811 | ||
812 | function browser_multi_add(e) { | |
813 | var target = e.target; | |
814 | if(!target||!target.hasAttribute("field")) | |
815 | return; | |
816 | var field = parseInt(target.getAttribute("field")); | |
817 | var container = blist.first; | |
818 | /* find what field we belong to */ | |
819 | for(var i=0; i<field&&container; i++) { | |
820 | container = container.next; | |
821 | } | |
822 | if(container) { | |
823 | var add = get_attribute_from_selected_elems(container.value, "diritem"); | |
824 | var type = get_attribute_from_selected_elems(container.value, "dirtype"); | |
825 | if(add.length<=0||add.length!=type.length) { // add.length must always equal type.length | |
826 | //debug("a: " + add.length + ", t: " + type.length); | |
827 | return; | |
828 | } | |
829 | var cmd=""; | |
830 | if(blist.type==BROWSE_ARTIST||blist.type==BROWSE_ALBUM) { | |
831 | if(container==blist.first.next) { | |
832 | if(blist.type==BROWSE_ARTIST) | |
833 | cmd+="baseartist:"; | |
834 | else cmd+="basealbum:"; | |
835 | var dirlist = container.value.getAttribute("dirlist"); | |
836 | cmd+=dirlist+"\n"; | |
837 | } | |
838 | } | |
839 | for(var i=0; i<add.length; i++) { | |
840 | if(type[i]=="parent") | |
841 | continue; | |
842 | cmd+= type[i]; | |
843 | cmd+= ":"; | |
844 | cmd+= add[i]; | |
845 | cmd+= "\n"; | |
846 | } | |
847 | blink_node(target, DEFAULT_BLINK_COLOR); | |
848 | send_command("ma", browser_multi_add_cb, LANG.WAIT_ADDING, false, cmd); | |
849 | } | |
850 | } | |
851 | ||
852 | function browser_multi_add_cb(res) { | |
853 | if(res!="ok") { | |
854 | show_status_bar(LANG.E_FAILED_ADD); | |
855 | hide_status_bar(STATUS_DEFAULT_TIMEOUT); | |
856 | } | |
857 | } |