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