]> Joshua Wise's Git repositories - patchfork.git/blob - std/browser.js
Add support for displaying the year; put the album in italics. (Feature request...
[patchfork.git] / std / browser.js
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 }
This page took 0.118201 seconds and 4 git commands to generate.