]> git.wh0rd.org Git - tt-rss.git/blob - prefs.js
colored labels UI improvements
[tt-rss.git] / prefs.js
1 var active_feed_cat = false;
2 var active_tab = false;
3
4 var init_params = new Array();
5
6 var caller_subop = false;
7 var sanity_check_done = false;
8 var hotkey_prefix = false;
9
10 function replace_pubkey_callback(transport) {
11         try {   
12                 var link = document.getElementById("pubGenAddress");
13
14                 if (transport.responseXML) {
15
16                         var new_link = transport.responseXML.getElementsByTagName("link")[0];
17
18                         if (new_link) {
19                                 link.href = new_link.firstChild.nodeValue;
20                                 //link.innerHTML = new_link.firstChild.nodeValue;
21
22                                 new Effect.Highlight(link);
23
24                                 notify_info("Published feed URL changed.");
25                         } else {
26                                 notify_error("Could not change feed URL.");
27                         }
28
29                 } else {
30                         notify_error("Could not change feed URL.");
31                 }
32         } catch (e) {
33                 exception_error("replace_pubkey_callback", e);
34         }
35 }
36
37 function feedlist_callback2(transport) {
38
39         try {   
40
41                 var container = document.getElementById('prefContent'); 
42                 container.innerHTML=transport.responseText;
43                 selectTab("feedConfig", true);
44
45                 if (caller_subop) {
46                         var tuple = caller_subop.split(":");
47                         if (tuple[0] == 'editFeed') {
48                                 window.setTimeout('editFeed('+tuple[1]+')', 100);
49                         }                               
50
51                         caller_subop = false;
52                 }
53                 if (typeof correctPNG != 'undefined') {
54                         correctPNG();
55                 }
56                 notify("");
57                 remove_splash();
58
59         } catch (e) {
60                 exception_error("feedlist_callback2", e);
61         }
62 }
63
64 /* stub for subscription dialog */
65
66 function dlg_frefresh_callback(transport) {
67         return feedlist_callback2(transport);
68 }
69
70 function filterlist_callback2(transport) {
71         var container = document.getElementById('prefContent');
72         container.innerHTML=transport.responseText;
73         if (typeof correctPNG != 'undefined') {
74                 correctPNG();
75         }
76         notify("");
77         remove_splash();
78 }
79
80 function init_label_inline_editor() {
81         try {
82                 if (document.getElementById("prefLabelList")) {
83                         var elems = document.getElementById("prefLabelList").getElementsByTagName("SPAN");
84
85                         for (var i = 0; i < elems.length; i++) {
86                                 if (elems[i].id && elems[i].id.match("LILT-")) {
87
88                                         var id = elems[i].id.replace("LILT-", "");
89
90                                         new Ajax.InPlaceEditor(elems[i],
91                                                 'backend.php?op=pref-labels&subop=save&id=' + id,
92                                                 {cols: 20, rows: 1});
93
94                                 }
95                         }
96                 }
97
98         } catch (e) {
99                 exception_error("init_label_inline_editor", e);
100         }
101 }
102
103 function labellist_callback2(transport) {
104
105         try {
106
107                 var container = document.getElementById('prefContent');
108                         closeInfoBox();
109                         container.innerHTML=transport.responseText;
110
111                         init_label_inline_editor();
112         
113                         if (typeof correctPNG != 'undefined') {
114                                 correctPNG();
115                         }
116                         notify("");
117                         remove_splash();
118
119         } catch (e) {
120                 exception_error("labellist_callback2", e);
121         }
122 }
123
124 function userlist_callback2(transport) {
125         try {
126                 var container = document.getElementById('prefContent');
127                 if (transport.readyState == 4) {
128                         container.innerHTML=transport.responseText;
129                         notify("");
130                         remove_splash();
131                 }
132         } catch (e) {
133                 exception_error("userlist_callback2", e);
134         }
135 }
136
137 function prefslist_callback2(transport) {
138         try {
139                 var container = document.getElementById('prefContent');
140                 container.innerHTML=transport.responseText;
141                 notify("");
142                 remove_splash();
143         } catch (e) {
144                 exception_error("prefslist_callback2", e);
145         }
146 }
147
148 function notify_callback2(transport) {
149         notify_info(transport.responseText);     
150 }
151
152 function prefs_reset_callback2(transport) {
153         try {
154                 notify_info(transport.responseText);
155                 selectTab();
156         } catch (e) {
157                 exception_error("prefs_reset_callback2", e);
158         }
159 }
160
161
162 function changepass_callback2(transport) {
163         try {
164         
165                         if (transport.responseText.indexOf("ERROR: ") == 0) {
166                                 notify_error(transport.responseText.replace("ERROR: ", ""));
167                         } else {
168                                 notify_info(transport.responseText);
169                                 var warn = document.getElementById("default_pass_warning");
170                                 if (warn) warn.style.display = "none";
171                         }
172         
173                         document.forms['change_pass_form'].reset();
174
175         } catch (e) {
176                 exception_error("changepass_callback2", e);
177         }
178 }
179
180 function init_cat_inline_editor() {
181         try {
182
183                 if (document.getElementById("prefFeedCatList")) {
184                         var elems = document.getElementById("prefFeedCatList").getElementsByTagName("SPAN");
185
186                         for (var i = 0; i < elems.length; i++) {
187                                 if (elems[i].id && elems[i].id.match("FCATT-")) {
188                                         var cat_id = elems[i].id.replace("FCATT-", "");
189                                                 new Ajax.InPlaceEditor(elems[i],
190                                                 'backend.php?op=pref-feeds&subop=editCats&action=save&cid=' + cat_id);
191                                 }
192                         }
193                 }
194
195         } catch (e) {
196                 exception_error("init_cat_inline_editor", e);
197         }
198 }
199
200 function infobox_feed_cat_callback2(transport) {
201         try {
202                 infobox_callback2(transport);
203                 init_cat_inline_editor();
204         } catch (e) {
205                 exception_error("infobox_feed_cat_callback2", e);
206         }
207 }
208
209 function updateFeedList(sort_key) {
210
211         try {
212
213         var feed_search = document.getElementById("feed_search");
214         var search = "";
215         if (feed_search) { search = feed_search.value; }
216
217         var slat = document.getElementById("show_last_article_times");
218
219         var slat_checked = false;
220         if (slat) {
221                 slat_checked = slat.checked;
222         }
223
224         var query = "backend.php?op=pref-feeds" +
225                 "&sort=" + param_escape(sort_key) + 
226                 "&slat=" + param_escape(slat_checked) +
227                 "&search=" + param_escape(search);
228
229         new Ajax.Request(query, {
230                 onComplete: function(transport) { 
231                         feedlist_callback2(transport); 
232                 } });
233         } catch (e) {
234                 exception_error("updateFeedList", e);
235         }
236 }
237
238 function updateUsersList(sort_key) {
239
240         try {
241
242                 var user_search = document.getElementById("user_search");
243                 var search = "";
244                 if (user_search) { search = user_search.value; }
245         
246                 var query = "backend.php?op=pref-users&sort="
247                         + param_escape(sort_key) +
248                         "&search=" + param_escape(search);
249         
250                 new Ajax.Request(query, {
251                         onComplete: function(transport) { 
252                                 userlist_callback2(transport); 
253                         } });
254
255         } catch (e) {
256                 exception_error("updateUsersList", e);
257         }
258 }
259
260 function addLabel() {
261
262         try {
263
264                 var caption = prompt(__("Please enter label caption:"), "");
265         
266                 if (caption == null) { 
267                         return false;
268                 }
269         
270                 if (caption == "") {
271                         alert(__("Can't create label: missing caption."));
272                         return false;
273                 }
274         
275                 // we can be called from some other tab
276                 active_tab = "labelConfig";
277         
278                 query = "backend.php?op=pref-labels&subop=add&caption=" + 
279                         param_escape(caption);
280         
281                 new Ajax.Request(query, {
282                         onComplete: function(transport) {
283                                         infobox_submit_callback2(transport);
284                                 } });
285
286         } catch (e) {
287                 exception_error("addLabel", e);
288         }
289 }
290
291 function addFeed() {
292
293         try {
294
295                 var link = document.getElementById("fadd_link");
296         
297                 if (link.value.length == 0) {
298                         alert(__("Error: No feed URL given."));
299                 } else if (!isValidURL(link.value)) {
300                         alert(__("Error: Invalid feed URL."));
301                 } else {
302                         notify_progress("Adding feed...");
303         
304                         var query = "backend.php?op=pref-feeds&subop=add&from=tt-rss&feed_url=" +
305                                 param_escape(link.value);
306         
307                         new Ajax.Request(query, {
308                                 onComplete: function(transport) {
309                                                 feedlist_callback2(transport);
310                                         } });
311         
312                         link.value = "";
313         
314                 }
315
316         } catch (e) {
317                 exception_error("addFeed", e);
318         }
319
320 }
321
322 function addFeedCat() {
323
324         var cat = document.getElementById("fadd_cat");
325
326         if (cat.value.length == 0) {
327                 alert(__("Can't add category: no name specified."));
328         } else {
329                 notify_progress("Adding feed category...");
330
331                 var query = "backend.php?op=pref-feeds&subop=editCats&action=add&cat=" +
332                         param_escape(cat.value);
333
334                 new Ajax.Request(query, {
335                         onComplete: function(transport) {
336                                         infobox_feed_cat_callback2(transport);
337                                 } });
338
339                 link.value = "";
340
341         }
342 }
343
344 function addUser() {
345
346         try {
347
348                 var login = prompt(__("Please enter login:"), "");
349         
350                 if (login == null) { 
351                         return false;
352                 }
353         
354                 if (login == "") {
355                         alert(__("Can't create user: no login specified."));
356                         return false;
357                 }
358         
359                 notify_progress("Adding user...");
360         
361                 var query = "backend.php?op=pref-users&subop=add&login=" +
362                         param_escape(login);
363                                 
364                 new Ajax.Request(query, {
365                         onComplete: function(transport) { 
366                                 userlist_callback2(transport); 
367                         } });
368
369         } catch (e) {
370                 exception_error("addUser", e);
371         }
372 }
373
374 function editUser(id) {
375
376         try {
377
378                 disableHotkeys();
379
380                 notify_progress("Loading, please wait...");
381
382                 selectTableRowsByIdPrefix('prefUserList', 'UMRR-', 'UMCHK-', false);
383                 selectTableRowById('UMRR-'+id, 'UMCHK-'+id, true);
384
385                 disableContainerChildren("userOpToolbar", false);
386
387                 var query = "backend.php?op=pref-users&subop=edit&id=" +
388                         param_escape(id);
389
390                 new Ajax.Request(query, {
391                         onComplete: function(transport) {
392                                         infobox_callback2(transport);
393                                 } });
394
395         } catch (e) {
396                 exception_error("editUser", e);
397         }
398                 
399 }
400
401 function editFilter(id) {
402
403         try {
404
405                 disableHotkeys();
406
407                 notify_progress("Loading, please wait...");
408
409                 disableContainerChildren("filterOpToolbar", false);
410
411                 selectTableRowsByIdPrefix('prefFilterList', 'FILRR-', 'FICHK-', false);
412                 selectTableRowById('FILRR-'+id, 'FICHK-'+id, true);
413
414                 var query = "backend.php?op=pref-filters&subop=edit&id=" + 
415                         param_escape(id);
416
417                 new Ajax.Request(query, {
418                         onComplete: function(transport) {
419                                         infobox_callback2(transport);
420                                 } });
421         } catch (e) {
422                 exception_error("editFilter", e);
423         }
424 }
425
426 function editFeed(feed) {
427
428         try {
429
430                 disableHotkeys();
431         
432                 notify_progress("Loading, please wait...");
433         
434                 // clean selection from all rows & select row being edited
435                 selectTableRowsByIdPrefix('prefFeedList', 'FEEDR-', 'FRCHK-', false);
436                 selectTableRowById('FEEDR-'+feed, 'FRCHK-'+feed, true);
437         
438                 disableContainerChildren("feedOpToolbar", false);
439         
440                 var query = "backend.php?op=pref-feeds&subop=editfeed&id=" +
441                         param_escape(feed);
442         
443                 new Ajax.Request(query, {
444                         onComplete: function(transport) {
445                                         infobox_callback2(transport);
446                                 } });
447
448         } catch (e) {
449                 exception_error("editFeed", e);
450         }
451 }
452
453 function getSelectedLabels() {
454         return getSelectedTableRowIds("prefLabelList", "LILRR");
455 }
456
457 function getSelectedUsers() {
458         return getSelectedTableRowIds("prefUserList", "UMRR");
459 }
460
461 function getSelectedFeeds() {
462         return getSelectedTableRowIds("prefFeedList", "FEEDR");
463 }
464
465 function getSelectedFilters() {
466         return getSelectedTableRowIds("prefFilterList", "FILRR");
467 }
468
469 function getSelectedFeedCats() {
470         return getSelectedTableRowIds("prefFeedCatList", "FCATR");
471 }
472
473
474 function removeSelectedLabels() {
475
476         var sel_rows = getSelectedLabels();
477
478         if (sel_rows.length > 0) {
479
480                 var ok = confirm(__("Remove selected labels?"));
481
482                 if (ok) {
483                         notify_progress("Removing selected labels...");
484         
485                         var query = "backend.php?op=pref-labels&subop=remove&ids="+
486                                 param_escape(sel_rows.toString());
487
488                         new Ajax.Request(query, {
489                                 onComplete: function(transport) {
490                                                 labellist_callback2(transport);
491                                         } });
492
493                 }
494         } else {
495                 alert(__("No labels are selected."));
496         }
497
498         return false;
499 }
500
501 function removeSelectedUsers() {
502
503         try {
504
505                 var sel_rows = getSelectedUsers();
506         
507                 if (sel_rows.length > 0) {
508         
509                         var ok = confirm(__("Remove selected users?"));
510         
511                         if (ok) {
512                                 notify_progress("Removing selected users...");
513                 
514                                 var query = "backend.php?op=pref-users&subop=remove&ids="+
515                                         param_escape(sel_rows.toString());
516         
517                                 new Ajax.Request(query, {
518                                         onComplete: function(transport) { 
519                                                 userlist_callback2(transport); 
520                                         } });
521         
522                         }
523         
524                 } else {
525                         alert(__("No users are selected."));
526                 }
527
528         } catch (e) {
529                 exception_error("removeSelectedUsers", e);
530         }
531
532         return false;
533 }
534
535 function removeSelectedFilters() {
536
537         try {
538
539                 var sel_rows = getSelectedFilters();
540         
541                 if (sel_rows.length > 0) {
542         
543                         var ok = confirm(__("Remove selected filters?"));
544         
545                         if (ok) {
546                                 notify_progress("Removing selected filters...");
547                 
548                                 var query = "backend.php?op=pref-filters&subop=remove&ids="+
549                                         param_escape(sel_rows.toString());
550         
551                                 new Ajax.Request(query, {
552                                                 onComplete: function(transport) {
553                                                                 filterlist_callback2(transport);
554                                         } });
555         
556                         }
557                 } else {
558                         alert(__("No filters are selected."));
559                 }
560
561         } catch (e) {
562                 exception_error("removeSelectedFilters", e);
563         }
564
565         return false;
566 }
567
568
569 function removeSelectedFeeds() {
570
571         try {
572
573                 var sel_rows = getSelectedFeeds();
574         
575                 if (sel_rows.length > 0) {
576         
577                         var ok = confirm(__("Unsubscribe from selected feeds?"));
578         
579                         if (ok) {
580         
581                                 notify_progress("Unsubscribing from selected feeds...");
582                 
583                                 var query = "backend.php?op=pref-feeds&subop=remove&ids="+
584                                         param_escape(sel_rows.toString());
585         
586                                 new Ajax.Request(query, {
587                                         onComplete: function(transport) {
588                                                         feedlist_callback2(transport);
589                                                 } });
590                         }
591         
592                 } else {
593                         alert(__("No feeds are selected."));
594                 }
595
596         } catch (e) {
597                 exception_error("removeSelectedFeeds", e);
598         }
599         
600         return false;
601 }
602
603 function clearSelectedFeeds() {
604
605         var sel_rows = getSelectedFeeds();
606
607         if (sel_rows.length > 1) {
608                 alert(__("Please select only one feed."));
609                 return;
610         }
611
612         if (sel_rows.length > 0) {
613
614                 var ok = confirm(__("Erase all non-starred articles in selected feed?"));
615
616                 if (ok) {
617                         notify_progress("Clearing selected feed...");
618                         clearFeedArticles(sel_rows[0]);
619                 }
620
621         } else {
622
623                 alert(__("No feeds are selected."));
624
625         }
626         
627         return false;
628 }
629
630 function purgeSelectedFeeds() {
631
632         var sel_rows = getSelectedFeeds();
633
634         if (sel_rows.length > 0) {
635
636                 var pr = prompt(__("How many days of articles to keep (0 - use default)?"), "0");
637
638                 if (pr != undefined) {
639                         notify_progress("Purging selected feed...");
640
641                         var query = "backend.php?op=rpc&subop=purge&ids="+
642                                 param_escape(sel_rows.toString()) + "&days=" + pr;
643
644                         debug(query);
645
646                         new Ajax.Request(query, {
647                                 onComplete: function(transport) {
648                                         notify('');
649                                 } });
650                 }
651
652         } else {
653
654                 alert(__("No feeds are selected."));
655
656         }
657         
658         return false;
659 }
660
661 function removeSelectedFeedCats() {
662
663         var sel_rows = getSelectedFeedCats();
664
665         if (sel_rows.length > 0) {
666
667                 var ok = confirm(__("Remove selected categories?"));
668
669                 if (ok) {
670                         notify_progress("Removing selected categories...");
671         
672                         var query = "backend.php?op=pref-feeds&subop=editCats&action=remove&ids="+
673                                 param_escape(sel_rows.toString());
674
675                         new Ajax.Request(query, {
676                                 onComplete: function(transport) {
677                                         infobox_feed_cat_callback2(transport);
678                                 } });
679
680                 }
681
682         } else {
683
684                 alert(__("No categories are selected."));
685
686         }
687
688         return false;
689 }
690
691 function feedEditCancel() {
692
693         try {
694                 document.getElementById("subscribe_to_feed_btn").disabled = false;
695                 document.getElementById("top25_feeds_btn").disabled = false;
696         } catch (e) {
697                 // this button is not always available, no-op if not found
698         }
699
700         closeInfoBox();
701
702         selectPrefRows('feed', false); // cleanup feed selection
703
704         return false;
705 }
706
707 function feedEditSave() {
708
709         try {
710         
711                 // FIXME: add parameter validation
712
713                 var query = Form.serialize("edit_feed_form");
714
715                 notify_progress("Saving feed...");
716
717                 new Ajax.Request("backend.php", {
718                         parameters: query,
719                         onComplete: function(transport) { 
720                                 feedlist_callback2(transport); 
721                         } });
722
723                 closeInfoBox();
724
725                 return false;
726
727         } catch (e) {
728                 exception_error("feedEditSave", e);
729         } 
730 }
731
732 function userEditCancel() {
733
734         selectPrefRows('user', false); // cleanup feed selection
735         closeInfoBox();
736
737         return false;
738 }
739
740 function filterEditCancel() {
741
742         try {
743                 document.getElementById("create_filter_btn").disabled = false;
744                 selectPrefRows('filter', false); // cleanup feed selection
745         } catch (e) { }
746
747         closeInfoBox();
748
749         return false;
750 }
751
752 function userEditSave() {
753
754         try {
755
756                 var login = document.forms["user_edit_form"].login.value;
757         
758                 if (login.length == 0) {
759                         alert(__("Login field cannot be blank."));
760                         return;
761                 }
762                 
763                 notify_progress("Saving user...");
764         
765                 closeInfoBox();
766         
767                 var query = Form.serialize("user_edit_form");
768                 
769                 new Ajax.Request("backend.php", {
770                         parameters: query,
771                         onComplete: function(transport) { 
772                                 userlist_callback2(transport); 
773                         } });
774         
775         } catch (e) {
776                 exception_error("userEditSave", e);
777         }
778
779         return false;
780
781 }
782
783
784 function filterEditSave() {
785
786         try {
787
788                 notify_progress("Saving filter...");
789         
790                 var query = "backend.php?" + Form.serialize("filter_edit_form");
791         
792                 closeInfoBox();
793         
794                 document.getElementById("create_filter_btn").disabled = false;
795
796                 new Ajax.Request(query, {
797                                 onComplete: function(transport) {
798                                                 filterlist_callback2(transport);
799                         } });
800
801         } catch (e) {
802                 exception_error("filterEditSave", e);
803         }
804
805         return false;
806 }
807
808
809 function editSelectedUser() {
810         var rows = getSelectedUsers();
811
812         if (rows.length == 0) {
813                 alert(__("No users are selected."));
814                 return;
815         }
816
817         if (rows.length > 1) {
818                 alert(__("Please select only one user."));
819                 return;
820         }
821
822         notify("");
823
824         editUser(rows[0]);
825 }
826
827 function resetSelectedUserPass() {
828
829         try {
830
831                 var rows = getSelectedUsers();
832         
833                 if (rows.length == 0) {
834                         alert(__("No users are selected."));
835                         return;
836                 }
837         
838                 if (rows.length > 1) {
839                         alert(__("Please select only one user."));
840                         return;
841                 }
842         
843                 var ok = confirm(__("Reset password of selected user?"));
844         
845                 if (ok) {
846                         notify_progress("Resetting password for selected user...");
847                 
848                         var id = rows[0];
849                 
850                         var query = "backend.php?op=pref-users&subop=resetPass&id=" +
851                                 param_escape(id);
852         
853                         new Ajax.Request(query, {
854                                 onComplete: function(transport) { 
855                                         userlist_callback2(transport); 
856                                 } });
857         
858                 }
859
860         } catch (e) {
861                 exception_error("resetSelectedUserPass", e);
862         }
863 }
864
865 function selectedUserDetails() {
866
867         try {
868
869                 var rows = getSelectedUsers();
870         
871                 if (rows.length == 0) {
872                         alert(__("No users are selected."));
873                         return;
874                 }
875         
876                 if (rows.length > 1) {
877                         alert(__("Please select only one user."));
878                         return;
879                 }
880         
881                 notify_progress("Loading, please wait...");
882         
883                 var id = rows[0];
884         
885                 var query = "backend.php?op=pref-users&subop=user-details&id=" + id;
886
887                 new Ajax.Request(query, {
888                         onComplete: function(transport) {
889                                         infobox_callback2(transport);
890                                 } });
891         } catch (e) {
892                 exception_error("selectedUserDetails", e);
893         }
894 }
895
896
897 function editSelectedFilter() {
898         var rows = getSelectedFilters();
899
900         if (rows.length == 0) {
901                 alert(__("No filters are selected."));
902                 return;
903         }
904
905         if (rows.length > 1) {
906                 alert(__("Please select only one filter."));
907                 return;
908         }
909
910         notify("");
911
912         editFilter(rows[0]);
913
914 }
915
916
917 function editSelectedFeed() {
918         var rows = getSelectedFeeds();
919
920         if (rows.length == 0) {
921                 alert(__("No feeds are selected."));
922                 return;
923         }
924
925         if (rows.length > 1) {
926                 alert(__("Please select one feed."));
927                 return;
928         }
929
930         notify("");
931
932         editFeed(rows[0]);
933
934 }
935
936 function editSelectedFeeds() {
937
938         try {
939                 var rows = getSelectedFeeds();
940         
941                 if (rows.length == 0) {
942                         alert(__("No feeds are selected."));
943                         return;
944                 }
945         
946                 notify("");
947         
948                 disableHotkeys();
949         
950                 notify_progress("Loading, please wait...");
951         
952                 var query = "backend.php?op=pref-feeds&subop=editfeeds&ids=" +
953                         param_escape(rows.toString());
954
955                 new Ajax.Request(query, {
956                         onComplete: function(transport) {
957                                         infobox_callback2(transport);
958                                 } });
959
960         } catch (e) {
961                 exception_error("editSelectedFeeds", e);
962         }
963 }
964
965 function piggie(enable) {
966         if (enable) {
967                 debug("I LOVEDED IT!");
968                 var piggie = document.getElementById("piggie");
969
970                 Element.show(piggie);
971                 Position.Center(piggie);
972                 Effect.Puff(piggie);
973
974         }
975 }
976
977 function validateOpmlImport() {
978         
979         var opml_file = document.getElementById("opml_file");
980
981         if (opml_file.value.length == 0) {
982                 alert(__("No OPML file to upload."));
983                 return false;
984         } else {
985                 return true;
986         }
987 }
988
989 function updateFilterList(sort_key) {
990         try {
991
992                 var filter_search = document.getElementById("filter_search");
993                 var search = "";
994                 if (filter_search) { search = filter_search.value; }
995         
996                 var query = "backend.php?op=pref-filters&sort=" + 
997                         param_escape(sort_key) + 
998                         "&search=" + param_escape(search);
999
1000                 new Ajax.Request(query, {
1001                                 onComplete: function(transport) {
1002                                                 filterlist_callback2(transport);
1003                         } });
1004
1005         } catch (e) {
1006                 exception_error("updateFilterList", e);
1007         }
1008
1009 }
1010
1011 function updateLabelList(sort_key) {
1012
1013         try {
1014
1015                 var label_search = document.getElementById("label_search");
1016                 var search = "";
1017                 if (label_search) { search = label_search.value; }
1018         
1019                 var query = "backend.php?op=pref-labels&sort=" + 
1020                         param_escape(sort_key) +
1021                         "&search=" + param_escape(search);
1022         
1023                 new Ajax.Request(query, {
1024                         onComplete: function(transport) {
1025                                 labellist_callback2(transport);
1026                         } });
1027
1028         } catch (e) {
1029                 exception_error("updateLabelList", e);
1030         }
1031 }
1032
1033 function updatePrefsList() {
1034
1035         var query = "backend.php?op=pref-prefs";
1036
1037         new Ajax.Request(query, {
1038                 onComplete: function(transport) { 
1039                         prefslist_callback2(transport); 
1040                 } });
1041
1042 }
1043
1044 function selectTab(id, noupdate, subop) {
1045
1046 //      alert(id);
1047
1048         if (!id) id = active_tab;
1049
1050         try {
1051
1052                 try {
1053                         var c = document.getElementById('prefContent'); 
1054                         c.scrollTop = 0;
1055                 } catch (e) { };
1056
1057                 if (!noupdate) {
1058
1059                         debug("selectTab: " + id + "(NU: " + noupdate + ")");
1060         
1061                         notify_progress("Loading, please wait...");
1062         
1063                         // close active infobox if needed
1064                         closeInfoBox();
1065         
1066                         // clean up all current selections, just in case
1067                         active_feed_cat = false;
1068
1069 //                      Effect.Fade("prefContent", {duration: 1, to: 0.01, 
1070 //                              queue: { position:'end', scope: 'FEED_TAB', limit: 1 } } );
1071
1072                         if (id == "feedConfig") {
1073                                 updateFeedList();
1074                         } else if (id == "filterConfig") {
1075                                 updateFilterList();
1076                         } else if (id == "labelConfig") {
1077                                 updateLabelList();
1078                         } else if (id == "genConfig") {
1079                                 updatePrefsList();
1080                         } else if (id == "userConfig") {
1081                                 updateUsersList();
1082                         }
1083                 }
1084
1085                 /* clean selection from all tabs */
1086         
1087                 var tabs_holder = document.getElementById("prefTabs");
1088                 var tab = tabs_holder.firstChild;
1089
1090                 while (tab) {
1091                         if (tab.className && tab.className.match("prefsTabSelected")) {
1092                                 tab.className = "prefsTab";
1093                         }
1094                         tab = tab.nextSibling;
1095                 }
1096
1097                 /* mark new tab as selected */
1098
1099                 tab = document.getElementById(id + "Tab");
1100         
1101                 if (tab) {
1102                         if (!tab.className.match("Selected")) {
1103                                 tab.className = tab.className + "Selected";
1104                         }
1105                 }
1106         
1107                 active_tab = id;
1108
1109         } catch (e) {
1110                 exception_error("selectTab", e);
1111         }
1112 }
1113
1114 function backend_sanity_check_callback2(transport) {
1115
1116         try {
1117
1118                 if (sanity_check_done) {
1119                         fatalError(11, "Sanity check request received twice. This can indicate "+
1120                       "presence of Firebug or some other disrupting extension. "+
1121                                 "Please disable it and try again.");
1122                         return;
1123                 }
1124
1125                 if (!transport.responseXML) {
1126                         fatalError(3, "Sanity Check: Received reply is not XML", 
1127                                 transport.responseText);
1128                         return;
1129                 }
1130
1131                 var reply = transport.responseXML.firstChild.firstChild;
1132
1133                 if (!reply) {
1134                         fatalError(3, "Sanity Check: Invalid RPC reply", transport.responseText);
1135                         return;
1136                 }
1137
1138                 var error_code = reply.getAttribute("error-code");
1139         
1140                 if (error_code && error_code != 0) {
1141                         return fatalError(error_code, reply.getAttribute("error-msg"));
1142                 }
1143
1144                 debug("sanity check ok");
1145
1146                 var params = reply.nextSibling;
1147
1148                 if (params) {
1149                         debug('reading init-params...');
1150                         var param = params.firstChild;
1151
1152                         while (param) {
1153                                 var k = param.getAttribute("key");
1154                                 var v = param.getAttribute("value");
1155                                 debug(k + " => " + v);
1156                                 init_params[k] = v;                                     
1157                                 param = param.nextSibling;
1158                         }
1159                 }
1160
1161                 sanity_check_done = true;
1162
1163                 init_second_stage();
1164
1165         } catch (e) {
1166                 exception_error("backend_sanity_check_callback", e);
1167         }
1168 }
1169
1170 function init_second_stage() {
1171
1172         try {
1173                 active_tab = getInitParam("prefs_active_tab");
1174                 if (!document.getElementById(active_tab+"Tab")) active_tab = "genConfig";
1175                 if (!active_tab || active_tab == '0') active_tab = "genConfig";
1176
1177                 document.onkeydown = pref_hotkey_handler;
1178
1179                 var tab = getURLParam('tab');
1180                 
1181                 caller_subop = getURLParam('subop');
1182
1183                 if (getURLParam("subopparam")) {
1184                         caller_subop = caller_subop + ":" + getURLParam("subopparam");
1185                 }
1186
1187                 if (tab) {
1188                         active_tab = tab;
1189                 }
1190
1191                 if (navigator.userAgent.match("Opera")) {       
1192                         setTimeout("selectTab()", 500);
1193                 } else {
1194                         selectTab(active_tab);
1195                 }
1196                 notify("");
1197
1198                 loading_set_progress(60);
1199
1200         } catch (e) {
1201                 exception_error("init_second_stage", e);
1202         }
1203 }
1204
1205 function init() {
1206
1207         try {
1208         
1209                 if (arguments.callee.done) return;
1210                 arguments.callee.done = true;           
1211
1212                 if (getURLParam('debug')) {
1213                         Element.show("debug_output");
1214                         debug('debug mode activated');
1215                 }
1216
1217                 loading_set_progress(30);
1218
1219                 var query = "backend.php?op=rpc&subop=sanityCheck";
1220
1221                 new Ajax.Request(query, {
1222                         onComplete: function(transport) { 
1223                                 backend_sanity_check_callback2(transport);
1224                         } });
1225
1226         } catch (e) {
1227                 exception_error("init", e);
1228         }
1229 }
1230
1231 function categorizeSelectedFeeds() {
1232
1233         var sel_rows = getSelectedFeeds();
1234
1235         var cat_sel = document.getElementById("sfeed_set_fcat");
1236         var cat_id = cat_sel[cat_sel.selectedIndex].value;
1237
1238         if (sel_rows.length > 0) {
1239
1240                 notify_progress("Changing category of selected feeds...");
1241
1242                 var query = "backend.php?op=pref-feeds&subop=categorize&ids="+
1243                         param_escape(sel_rows.toString()) + "&cat_id=" + param_escape(cat_id);
1244
1245                 new Ajax.Request(query, {
1246                         onComplete: function(transport) { 
1247                                 feedlist_callback2(transport); 
1248                         } });
1249
1250         } else {
1251
1252                 alert(__("No feeds are selected."));
1253
1254         }
1255
1256 }
1257
1258 function validatePrefsReset() {
1259         try {
1260                 var ok = confirm(__("Reset to defaults?"));
1261
1262                 if (ok) {
1263
1264                         var query = Form.serialize("pref_prefs_form");
1265                         query = query + "&subop=reset-config";
1266                         debug(query);
1267
1268                         new Ajax.Request("backend.php", {
1269                                 parameters: query,
1270                                 onComplete: function(transport) { 
1271                                         prefs_reset_callback2(transport);
1272                                 } });
1273
1274                 }
1275
1276         } catch (e) {
1277                 exception_error("validatePrefsSave", e);
1278         }
1279
1280         return false;
1281
1282 }
1283
1284 function feedBrowserSubscribe() {
1285         try {
1286
1287                 var selected = getSelectedFeedsFromBrowser();
1288
1289                 if (selected.length > 0) {
1290                         closeInfoBox();
1291
1292                         var query = "backend.php?op=pref-feeds&subop=massSubscribe&ids="+
1293                                 param_escape(selected.toString());
1294
1295                         new Ajax.Request(query, {
1296                                 onComplete: function(transport) { 
1297                                         feedlist_callback2(transport); 
1298                                 } });
1299
1300                 } else {
1301                         alert(__("No feeds are selected."));
1302                 }
1303
1304         } catch (e) {
1305                 exception_error("feedBrowserSubscribe", e);
1306         }
1307 }
1308
1309 function updateBigFeedBrowserBtn() {
1310         notify_progress("Loading, please wait...");
1311         return updateBigFeedBrowser();
1312 }
1313
1314 function selectPrefRows(kind, select) {
1315
1316         if (kind) {
1317                 var opbarid = false;    
1318                 var nchk = false;
1319                 var nrow = false;
1320                 var lname = false;
1321
1322                 if (kind == "feed") {
1323                         opbarid = "feedOpToolbar";
1324                         nrow = "FEEDR-";
1325                         nchk = "FRCHK-";                        
1326                         lname = "prefFeedList";
1327                 } else if (kind == "fcat") {
1328                         opbarid = "catOpToolbar";
1329                         nrow = "FCATR-";
1330                         nchk = "FCCHK-";
1331                         lname = "prefFeedCatList";
1332                 } else if (kind == "filter") {
1333                         opbarid = "filterOpToolbar";
1334                         nrow = "FILRR-";
1335                         nchk = "FICHK-";
1336                         lname = "prefFilterList";
1337                 } else if (kind == "label") {
1338                         opbarid = "labelOpToolbar";
1339                         nrow = "LILRR-";
1340                         nchk = "LICHK-";
1341                         lname = "prefLabelList";
1342                 } else if (kind == "user") {
1343                         opbarid = "userOpToolbar";
1344                         nrow = "UMRR-";
1345                         nchk = "UMCHK-";
1346                         lname = "prefUserList";
1347                 }
1348
1349                 if (opbarid) {
1350                         selectTableRowsByIdPrefix(lname, nrow, nchk, select);
1351                         disableContainerChildren(opbarid, !select);
1352                 }
1353
1354         } 
1355 }
1356
1357
1358 function toggleSelectPrefRow(sender, kind) {
1359
1360         toggleSelectRow(sender);
1361
1362         if (kind) {
1363                 var opbarid = false;    
1364                 var nsel = -1;
1365                 
1366                 if (kind == "feed") {
1367                         opbarid = "feedOpToolbar";
1368                         nsel = getSelectedFeeds();
1369                 } else if (kind == "fcat") {
1370                         opbarid = "catOpToolbar";
1371                         nsel = getSelectedFeedCats();
1372                 } else if (kind == "filter") {
1373                         opbarid = "filterOpToolbar";
1374                         nsel = getSelectedFilters();
1375                 } else if (kind == "label") {
1376                         opbarid = "labelOpToolbar";
1377                         nsel = getSelectedLabels();
1378                 } else if (kind == "user") {
1379                         opbarid = "userOpToolbar";
1380                         nsel = getSelectedUsers();
1381                 }
1382
1383                 if (opbarid && nsel != -1) {
1384                         disableContainerChildren(opbarid, nsel == false);
1385                 }
1386
1387         } 
1388 }
1389
1390 function toggleSelectFBListRow(sender) {
1391         toggleSelectListRow(sender);
1392         disableContainerChildren("fbrOpToolbar", getSelectedFeedsFromBrowser() == 0);
1393 }
1394
1395 var seq = "";
1396
1397 function pref_hotkey_handler(e) {
1398         try {
1399
1400                 var keycode;
1401                 var shift_key = false;
1402
1403                 try {
1404                         shift_key = e.shiftKey;
1405                 } catch (e) {
1406
1407                 }
1408
1409                 if (window.event) {
1410                         keycode = window.event.keyCode;
1411                 } else if (e) {
1412                         keycode = e.which;
1413                 }
1414
1415                 var keychar = String.fromCharCode(keycode);
1416
1417                 if (keycode == 27) { // escape
1418                         if (Element.visible("hotkey_help_overlay")) {
1419                                 Element.hide("hotkey_help_overlay");
1420                         }
1421                         hotkey_prefix = false;
1422                         closeInfoBox();
1423                 } 
1424
1425                 if (!hotkeys_enabled) {
1426                         debug("hotkeys disabled");
1427                         return;
1428                 }
1429
1430                 if (keycode == 16) return; // ignore lone shift
1431
1432                 if ((keycode == 67 || keycode == 71) && !hotkey_prefix) {
1433                         hotkey_prefix = keycode;
1434                         debug("KP: PREFIX=" + keycode + " CHAR=" + keychar);
1435                         return;
1436                 }
1437
1438                 if (Element.visible("hotkey_help_overlay")) {
1439                         Element.hide("hotkey_help_overlay");
1440                 }
1441
1442                 if (keycode == 13 || keycode == 27) {
1443                         seq = "";
1444                 } else {
1445                         seq = seq + "" + keycode;
1446                 }
1447
1448                 /* Global hotkeys */
1449
1450                 if (!hotkey_prefix) {
1451
1452                         if (keycode == 68 && shift_key) { // d
1453                                 if (!Element.visible("debug_output")) {
1454                                         Element.show("debug_output");
1455                                         debug('debug mode activated');
1456                                 } else {
1457                                         Element.hide("debug_output");
1458                                 }
1459                                 return;
1460                         }
1461         
1462                         if ((keycode == 191 || keychar == '?') && shift_key) { // ?
1463                                 if (!Element.visible("hotkey_help_overlay")) {
1464                                         //Element.show("hotkey_help_overlay");
1465                                         Effect.Appear("hotkey_help_overlay", {duration : 0.3});
1466                                 } else {
1467                                         Element.hide("hotkey_help_overlay");
1468                                 }
1469                                 return false;
1470                         }
1471
1472                         if (keycode == 191 || keychar == '/') { // /
1473                                 var search_boxes = new Array("label_search", 
1474                                         "feed_search", "filter_search", "user_search", "feed_browser_search");
1475
1476                                 for (var i = 0; i < search_boxes.length; i++) {
1477                                         var elem = document.getElementById(search_boxes[i]);
1478                                         if (elem) {
1479                                                 focus_element(search_boxes[i]);
1480                                                 return false;
1481                                         }
1482                                 }
1483                         }
1484                 }
1485
1486                 /* Prefix c */
1487
1488                 if (hotkey_prefix == 67) { // c
1489                         hotkey_prefix = false;
1490
1491                         if (keycode == 70) { // f
1492                                 displayDlg("quickAddFilter");
1493                                 return false;
1494                         }
1495
1496                         if (keycode == 83) { // s
1497                                 displayDlg("quickAddFeed");
1498                                 return false;
1499                         }
1500
1501 /*                      if (keycode == 76) { // l
1502                                 displayDlg("quickAddLabel");
1503                                 return false;
1504                         } */
1505
1506                         if (keycode == 85) { // u
1507                                 // no-op
1508                         }
1509
1510                         if (keycode == 67) { // c
1511                                 editFeedCats();
1512                                 return false;
1513                         }
1514
1515                         if (keycode == 84 && shift_key) { // T
1516                                 browseFeeds();
1517                                 return false;
1518                         }
1519
1520                 }
1521
1522                 /* Prefix g */
1523
1524                 if (hotkey_prefix == 71) { // g
1525
1526                         hotkey_prefix = false;
1527
1528                         if (keycode == 49 && document.getElementById("genConfigTab")) { // 1
1529                                 selectTab("genConfig");
1530                                 return false;
1531                         }
1532
1533                         if (keycode == 50 && document.getElementById("feedConfigTab")) { // 2
1534                                 selectTab("feedConfig");
1535                                 return false;
1536                         }
1537
1538                         if (keycode == 51 && document.getElementById("filterConfigTab")) { // 4
1539                                 selectTab("filterConfig");
1540                                 return false;
1541                         }
1542
1543                         if (keycode == 52 && document.getElementById("labelConfigTab")) { // 5
1544                                 selectTab("labelConfig");
1545                                 return false;
1546                         }
1547
1548                         if (keycode == 53 && document.getElementById("userConfigTab")) { // 6
1549                                 selectTab("userConfig");
1550                                 return false;
1551                         }
1552
1553                         if (keycode == 88) { // x
1554                                 return gotoMain();
1555                         }
1556
1557                 }
1558
1559                 if (document.getElementById("piggie")) {
1560         
1561                         if (seq.match("807371717369")) {
1562                                 seq = "";
1563                                 piggie(true);
1564                         } else {
1565                                 piggie(false);
1566                         }
1567                 }
1568
1569                 if (hotkey_prefix) {
1570                         debug("KP: PREFIX=" + hotkey_prefix + " CODE=" + keycode + " CHAR=" + keychar);
1571                 } else {
1572                         debug("KP: CODE=" + keycode + " CHAR=" + keychar);
1573                 }
1574
1575         } catch (e) {
1576                 exception_error("pref_hotkey_handler", e);
1577         }
1578 }
1579
1580 function editFeedCats() {
1581         try {
1582                 document.getElementById("subscribe_to_feed_btn").disabled = true;
1583         
1584                 try {
1585                         document.getElementById("top25_feeds_btn").disabled = true;
1586                 } catch (e) {
1587                         // this button is not always available, no-op if not found
1588                 }
1589         
1590                 var query = "backend.php?op=pref-feeds&subop=editCats";
1591
1592                 new Ajax.Request(query, {
1593                         onComplete: function(transport) {
1594                                 infobox_feed_cat_callback2(transport);
1595                         } });
1596         } catch (e) {
1597                 exception_error("editFeedCats", e);
1598         }
1599 }
1600
1601 function showFeedsWithErrors() {
1602         displayDlg('feedUpdateErrors');
1603 }
1604
1605 function changeUserPassword() {
1606
1607         try {
1608
1609                 var f = document.forms["change_pass_form"];
1610
1611                 if (f) {
1612                         if (f.OLD_PASSWORD.value == "") {
1613                                 new Effect.Highlight(f.OLD_PASSWORD);
1614                                 notify_error("Old password cannot be blank.");
1615                                 return false;
1616                         }
1617
1618                         if (f.NEW_PASSWORD.value == "") {
1619                                 new Effect.Highlight(f.NEW_PASSWORD);
1620                                 notify_error("New password cannot be blank.");
1621                                 return false;
1622                         }
1623
1624                         if (f.CONFIRM_PASSWORD.value == "") {
1625                                 new Effect.Highlight(f.CONFIRM_PASSWORD);
1626                                 notify_error("Entered passwords do not match.");
1627                                 return false;
1628                         }
1629
1630                         if (f.CONFIRM_PASSWORD.value != f.NEW_PASSWORD.value) {
1631                                 new Effect.Highlight(f.CONFIRM_PASSWORD);
1632                                 new Effect.Highlight(f.NEW_PASSWORD);
1633                                 notify_error("Entered passwords do not match.");
1634                                 return false;
1635                         }
1636
1637                 }
1638
1639                 var query = Form.serialize("change_pass_form");
1640         
1641                 notify_progress("Trying to change password...");
1642
1643                 new Ajax.Request("backend.php", {
1644                         parameters: query,
1645                         onComplete: function(transport) { 
1646                                 changepass_callback2(transport); 
1647                         } });
1648
1649
1650         } catch (e) {
1651                 exception_error("changeUserPassword", e);
1652         }
1653         
1654         return false;
1655 }
1656
1657 function changeUserEmail() {
1658
1659         try {
1660
1661                 var query = Form.serialize("change_email_form");
1662         
1663                 notify_progress("Trying to change e-mail...");
1664         
1665                 new Ajax.Request("backend.php", {
1666                         parameters: query,
1667                         onComplete: function(transport) { 
1668                                 notify_callback2(transport); 
1669                         } });
1670
1671         } catch (e) {
1672                 exception_error("changeUserPassword", e);
1673         }
1674         
1675         return false;
1676
1677 }
1678
1679 function feedlistToggleSLAT() {
1680         notify_progress("Loading, please wait...");
1681         updateFeedList()
1682 }
1683
1684 function pubRegenKey() {
1685
1686         var ok = confirm(__("Replace current publishing address with a new one?"));
1687
1688         if (ok) {
1689
1690                 notify_progress("Trying to change address...");
1691
1692                 var query = "backend.php?op=rpc&subop=regenPubKey";
1693
1694                 new Ajax.Request(query, {
1695                         onComplete: function(transport) {
1696                                         replace_pubkey_callback(transport);
1697                                 } });
1698
1699         }
1700
1701         return false;
1702 }
1703
1704 function validatePrefsSave() {
1705         try {
1706
1707                 var ok = confirm(__("Save current configuration?"));
1708
1709                 if (ok) {
1710
1711                         var query = Form.serialize("pref_prefs_form");
1712                         query = query + "&subop=save-config";
1713                         debug(query);
1714
1715                         new Ajax.Request("backend.php", {
1716                                 parameters: query,
1717                                 onComplete: function(transport) { 
1718                                 notify_callback2(transport); 
1719                         } });
1720
1721                 }
1722
1723         } catch (e) {
1724                 exception_error("validatePrefsSave", e);
1725         }
1726
1727         return false;
1728 }
1729
1730 function feedActionChange() {
1731         try {
1732                 var chooser = document.getElementById("feedActionChooser");
1733                 var opid = chooser[chooser.selectedIndex].value;
1734
1735                 chooser.selectedIndex = 0;
1736                 feedActionGo(opid);
1737         } catch (e) {
1738                 exception_error("feedActionChange", e);
1739         }
1740 }
1741
1742 function feedActionGo(op) {     
1743         try {
1744                 if (op == "facEdit") {
1745
1746                         var rows = getSelectedFeeds();
1747
1748                         if (rows.length > 1) {
1749                                 editSelectedFeeds();
1750                         } else {
1751                                 editSelectedFeed();
1752                         }
1753                 }
1754
1755                 if (op == "facClear") {
1756                         clearSelectedFeeds();
1757                 }
1758
1759                 if (op == "facPurge") {
1760                         purgeSelectedFeeds();
1761                 }
1762
1763                 if (op == "facEditCats") {
1764                         editFeedCats();
1765                 }
1766
1767                 if (op == "facRescore") {
1768                         rescoreSelectedFeeds();
1769                 }
1770
1771                 if (op == "facUnsubscribe") {
1772                         removeSelectedFeeds();
1773                 }
1774
1775         } catch (e) {
1776                 exception_error("feedActionGo", e);
1777
1778         }
1779 }
1780
1781 function clearFeedArticles(feed_id) {
1782
1783         notify_progress("Clearing feed...");
1784
1785         var query = "backend.php?op=pref-feeds&quiet=1&subop=clear&id=" + feed_id;
1786
1787         new Ajax.Request(query, {
1788                 onComplete: function(transport) {
1789                                 notify('');
1790                         } });
1791
1792         return false;
1793 }
1794
1795 function rescoreSelectedFeeds() {
1796
1797         var sel_rows = getSelectedFeeds();
1798
1799         if (sel_rows.length > 0) {
1800
1801                 //var ok = confirm(__("Rescore last 100 articles in selected feeds?"));
1802                 var ok = confirm(__("Rescore articles in selected feeds?"));
1803
1804                 if (ok) {
1805                         notify_progress("Rescoring selected feeds...", true);
1806         
1807                         var query = "backend.php?op=pref-feeds&subop=rescore&quiet=1&ids="+
1808                                 param_escape(sel_rows.toString());
1809
1810                         new Ajax.Request(query, {
1811                                 onComplete: function(transport) {
1812                                                 notify_callback2(transport);
1813                         } });
1814
1815                 }
1816         } else {
1817                 alert(__("No feeds are selected."));
1818         }
1819
1820         return false;
1821 }
1822
1823 function rescore_all_feeds() {
1824         var ok = confirm(__("Rescore all articles? This operation may take a lot of time."));
1825
1826         if (ok) {
1827                 notify_progress("Rescoring feeds...", true);
1828
1829                 var query = "backend.php?op=pref-feeds&subop=rescoreAll&quiet=1";
1830
1831                 new Ajax.Request(query, {
1832                         onComplete: function(transport) {
1833                                         notify_callback2(transport);
1834                 } });
1835         }
1836 }
1837
1838 function removeFilter(id, title) {
1839
1840         try {
1841
1842                 var msg = __("Remove filter %s?").replace("%s", title);
1843         
1844                 var ok = confirm(msg);
1845         
1846                 if (ok) {
1847                         closeInfoBox();
1848         
1849                         notify_progress("Removing filter...");
1850                 
1851                         var query = "backend.php?op=pref-filters&subop=remove&ids="+
1852                                 param_escape(id);
1853
1854                         new Ajax.Request(query, {
1855                                 onComplete: function(transport) {
1856                                                 filterlist_callback2(transport);
1857                         } });
1858
1859                 }
1860
1861         } catch (e) {
1862                 exception_error("removeFilter", e);
1863         }
1864
1865         return false;
1866 }
1867
1868 function unsubscribeFeed(id, title) {
1869
1870         try {
1871
1872                 var msg = __("Unsubscribe from %s?").replace("%s", title);
1873         
1874                 var ok = confirm(msg);
1875         
1876                 if (ok) {
1877                         closeInfoBox();
1878         
1879                         notify_progress("Removing feed...");
1880                 
1881                         var query = "backend.php?op=pref-feeds&subop=remove&ids="+
1882                                 param_escape(id);
1883         
1884                         new Ajax.Request(query, {
1885                                         onComplete: function(transport) {
1886                                                         feedlist_callback2(transport);
1887                                 } });
1888                 }
1889         
1890         } catch (e) {
1891                 exception_error("unsubscribeFeed", e);
1892         }
1893
1894         return false;
1895
1896 }
1897
1898 function feedsEditSave() {
1899         try {
1900
1901                 var ok = confirm(__("Save changes to selected feeds?"));
1902
1903                 if (ok) {
1904
1905                         var f = document.forms["batch_edit_feed_form"];
1906
1907                         var query = Form.serialize("batch_edit_feed_form");
1908
1909                         /* Form.serialize ignores unchecked checkboxes */
1910
1911                         if (!query.match("&hidden=") && 
1912                                         f.hidden.disabled == false) {
1913                                 query = query + "&hidden=false";
1914                         }
1915
1916                         if (!query.match("&rtl_content=") && 
1917                                         f.rtl_content.disabled == false) {
1918                                 query = query + "&rtl_content=false";
1919                         }
1920
1921                         if (!query.match("&private=") && 
1922                                         f.private.disabled == false) {
1923                                 query = query + "&private=false";
1924                         }
1925
1926                         if (!query.match("&cache_images=") && 
1927                                         f.cache_images.disabled == false) {
1928                                 query = query + "&cache_images=false";
1929                         }
1930
1931                         if (!query.match("&include_in_digest=") && 
1932                                         f.include_in_digest.disabled == false) {
1933                                 query = query + "&include_in_digest=false";
1934                         }
1935         
1936                         closeInfoBox();
1937         
1938                         notify_progress("Saving feeds...");
1939         
1940                         new Ajax.Request("backend.php", {
1941                                 parameters: query,
1942                                 onComplete: function(transport) { 
1943                                         feedlist_callback2(transport); 
1944                                 } });
1945
1946                 }
1947
1948                 return false;
1949         } catch (e) {
1950                 exception_error("feedsEditSave", e);
1951         }
1952 }
1953
1954 function batchFeedsToggleField(cb, elem, label) {
1955         try {
1956                 var f = document.forms["batch_edit_feed_form"];
1957                 var l = document.getElementById(label);
1958
1959                 if (cb.checked) {
1960                         f[elem].disabled = false;
1961
1962                         if (l) {
1963                                 l.className = "";
1964                         };
1965
1966 //                      new Effect.Highlight(f[elem], {duration: 1, startcolor: "#fff7d5",
1967 //                              queue: { position:'end', scope: 'BPEFQ', limit: 1 } } );
1968
1969                 } else {
1970                         f[elem].disabled = true;
1971
1972                         if (l) {
1973                                 l.className = "insensitive";
1974                         };
1975
1976                 }
1977         } catch (e) {
1978                 exception_error("batchFeedsToggleField", e);
1979         }
1980 }
1981
1982 function labelColorReset() {
1983         try {
1984                 var labels = getSelectedLabels();
1985
1986                 var ok = confirm(__("Clear colors of labels?"));
1987
1988                 if (ok) {
1989
1990                         var query = "backend.php?op=pref-labels&subop=color-reset&ids="+
1991                                 param_escape(labels.toString());
1992
1993                         new Ajax.Request(query, {
1994                                 onComplete: function(transport) {
1995                                                 labellist_callback2(transport);
1996                                         } });
1997                 }
1998
1999         } catch (e) {
2000                 exception_error("labelColorReset", e);
2001         }
2002 }
2003
2004 function labelColorSet(kind) {
2005         try {
2006                 var labels = getSelectedLabels();
2007
2008                 var p = null
2009
2010                 if (kind == "fg") {
2011                         p = prompt(__("Please enter new label foreground color:"));
2012                 } else {
2013                         p = prompt(__("Please enter new label background color:"));
2014                 }
2015
2016                 if (p != null) {
2017
2018                         var query = "backend.php?op=pref-labels&subop=color-set&kind=" + kind +
2019                                 "&ids="+        param_escape(labels.toString()) + "&color=" + param_escape(p);
2020
2021                         selectPrefRows('label', false);
2022
2023                         for (var i = 0; i < labels.length; i++) {
2024                                 var e = document.getElementById("LICID-" + labels[i]);
2025                                 if (e) {
2026                                         if (kind == "fg") {
2027                                                 e.style.color = p;
2028                                         } else {
2029                                                 e.style.backgroundColor = p;
2030                                         }
2031                                 }
2032                         }
2033
2034                         new Ajax.Request(query);
2035                 }
2036
2037         } catch (e) {
2038                 exception_error("labelColorReset", e);
2039         }
2040 }
2041
2042
2043 /*
2044 function colorPicker(caller, id, fg, bg) {
2045         try {
2046                 var picker = document.getElementById("colorPicker");
2047
2048
2049                 picker.style.left = caller.offsetLeft;
2050                 picker.style.top = caller.offsetTop;
2051
2052         } catch (e) {
2053                 exception_error("colorPicker", e);
2054         }
2055 }*/