]> git.wh0rd.org Git - tt-rss.git/blob - prefs.js
prefs: reorganize toolbar buttons
[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         try {
714                 $("subscribe_to_feed_btn").disabled = false;
715                 $("top25_feeds_btn").disabled = false;
716         } catch (e) {
717                 // this button is not always available, no-op if not found
718         }
719
720         closeInfoBox();
721
722         selectPrefRows('feed', false); // cleanup feed selection
723
724         return false;
725 }
726
727 function feedEditSave() {
728
729         try {
730         
731                 // FIXME: add parameter validation
732
733                 var query = Form.serialize("edit_feed_form");
734
735                 notify_progress("Saving feed...");
736
737                 new Ajax.Request("backend.php", {
738                         parameters: query,
739                         onComplete: function(transport) { 
740                                 feedlist_callback2(transport); 
741                         } });
742
743                 closeInfoBox();
744
745                 return false;
746
747         } catch (e) {
748                 exception_error("feedEditSave", e);
749         } 
750 }
751
752 function userEditCancel() {
753
754         selectPrefRows('user', false); // cleanup feed selection
755         closeInfoBox();
756
757         return false;
758 }
759
760 function filterEditCancel() {
761
762         try {
763                 $("create_filter_btn").disabled = false;
764                 selectPrefRows('filter', false); // cleanup feed selection
765         } catch (e) { }
766
767         closeInfoBox();
768
769         return false;
770 }
771
772 function userEditSave() {
773
774         try {
775
776                 var login = document.forms["user_edit_form"].login.value;
777         
778                 if (login.length == 0) {
779                         alert(__("Login field cannot be blank."));
780                         return;
781                 }
782                 
783                 notify_progress("Saving user...");
784         
785                 closeInfoBox();
786         
787                 var query = Form.serialize("user_edit_form");
788                 
789                 new Ajax.Request("backend.php", {
790                         parameters: query,
791                         onComplete: function(transport) { 
792                                 userlist_callback2(transport); 
793                         } });
794         
795         } catch (e) {
796                 exception_error("userEditSave", e);
797         }
798
799         return false;
800
801 }
802
803
804 function filterEditSave() {
805
806         try {
807
808                 notify_progress("Saving filter...");
809         
810                 var query = "?" + Form.serialize("filter_edit_form");
811         
812                 closeInfoBox();
813         
814                 $("create_filter_btn").disabled = false;
815
816                 new Ajax.Request("backend.php", {
817                                 parameters: query,
818                                 onComplete: function(transport) {
819                                                 filterlist_callback2(transport);
820                         } });
821
822         } catch (e) {
823                 exception_error("filterEditSave", e);
824         }
825
826         return false;
827 }
828
829
830 function editSelectedUser() {
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         notify("");
844
845         editUser(rows[0]);
846 }
847
848 function resetSelectedUserPass() {
849
850         try {
851
852                 var rows = getSelectedUsers();
853         
854                 if (rows.length == 0) {
855                         alert(__("No users are selected."));
856                         return;
857                 }
858         
859                 if (rows.length > 1) {
860                         alert(__("Please select only one user."));
861                         return;
862                 }
863         
864                 var ok = confirm(__("Reset password of selected user?"));
865         
866                 if (ok) {
867                         notify_progress("Resetting password for selected user...");
868                 
869                         var id = rows[0];
870                 
871                         var query = "?op=pref-users&subop=resetPass&id=" +
872                                 param_escape(id);
873         
874                         new Ajax.Request("backend.php", {
875                                 parameters: query,
876                                 onComplete: function(transport) { 
877                                         userlist_callback2(transport); 
878                                 } });
879         
880                 }
881
882         } catch (e) {
883                 exception_error("resetSelectedUserPass", e);
884         }
885 }
886
887 function selectedUserDetails() {
888
889         try {
890
891                 var rows = getSelectedUsers();
892         
893                 if (rows.length == 0) {
894                         alert(__("No users are selected."));
895                         return;
896                 }
897         
898                 if (rows.length > 1) {
899                         alert(__("Please select only one user."));
900                         return;
901                 }
902         
903                 notify_progress("Loading, please wait...");
904         
905                 var id = rows[0];
906         
907                 var query = "?op=pref-users&subop=user-details&id=" + id;
908
909                 new Ajax.Request("backend.php", {
910                         parameters: query,
911                         onComplete: function(transport) {
912                                         infobox_callback2(transport);
913                                 } });
914         } catch (e) {
915                 exception_error("selectedUserDetails", e);
916         }
917 }
918
919
920 function editSelectedFilter() {
921         var rows = getSelectedFilters();
922
923         if (rows.length == 0) {
924                 alert(__("No filters are selected."));
925                 return;
926         }
927
928         if (rows.length > 1) {
929                 alert(__("Please select only one filter."));
930                 return;
931         }
932
933         notify("");
934
935         editFilter(rows[0]);
936
937 }
938
939
940 function editSelectedFeed() {
941         var rows = getSelectedFeeds();
942
943         if (rows.length == 0) {
944                 alert(__("No feeds are selected."));
945                 return;
946         }
947
948         if (rows.length > 1) {
949                 return editSelectedFeeds();
950         }
951
952         notify("");
953
954         editFeed(rows[0]);
955
956 }
957
958 function editSelectedFeeds() {
959
960         try {
961                 var rows = getSelectedFeeds();
962         
963                 if (rows.length == 0) {
964                         alert(__("No feeds are selected."));
965                         return;
966                 }
967         
968                 notify("");
969         
970                 disableHotkeys();
971         
972                 notify_progress("Loading, please wait...");
973         
974                 var query = "?op=pref-feeds&subop=editfeeds&ids=" +
975                         param_escape(rows.toString());
976
977                 new Ajax.Request("backend.php", {
978                         parameters: query,
979                         onComplete: function(transport) {
980                                         infobox_callback2(transport);
981                                 } });
982
983         } catch (e) {
984                 exception_error("editSelectedFeeds", e);
985         }
986 }
987
988 function piggie(enable) {
989         if (enable) {
990                 debug("I LOVEDED IT!");
991                 var piggie = $("piggie");
992
993                 Element.show(piggie);
994                 Position.Center(piggie);
995                 Effect.Puff(piggie);
996
997         }
998 }
999
1000 function validateOpmlImport() {
1001         
1002         var opml_file = $("opml_file");
1003
1004         if (opml_file.value.length == 0) {
1005                 alert(__("No OPML file to upload."));
1006                 return false;
1007         } else {
1008                 return true;
1009         }
1010 }
1011
1012 function updateFilterList(sort_key) {
1013         try {
1014
1015                 var filter_search = $("filter_search");
1016                 var search = "";
1017                 if (filter_search) { search = filter_search.value; }
1018         
1019                 var query = "?op=pref-filters&sort=" + 
1020                         param_escape(sort_key) + 
1021                         "&search=" + param_escape(search);
1022
1023                 new Ajax.Request("backend.php", {
1024                                 parameters: query,
1025                                 onComplete: function(transport) {
1026                                                 filterlist_callback2(transport);
1027                         } });
1028
1029         } catch (e) {
1030                 exception_error("updateFilterList", e);
1031         }
1032
1033 }
1034
1035 function updateLabelList(sort_key) {
1036
1037         try {
1038
1039                 var label_search = $("label_search");
1040                 var search = "";
1041                 if (label_search) { search = label_search.value; }
1042         
1043                 var query = "?op=pref-labels&sort=" + 
1044                         param_escape(sort_key) +
1045                         "&search=" + param_escape(search);
1046         
1047                 new Ajax.Request("backend.php", {
1048                         parameters: query,
1049                         onComplete: function(transport) {
1050                                 labellist_callback2(transport);
1051                         } });
1052
1053         } catch (e) {
1054                 exception_error("updateLabelList", e);
1055         }
1056 }
1057
1058 function updatePrefsList() {
1059
1060         var query = "?op=pref-prefs";
1061
1062         new Ajax.Request("backend.php", {
1063                 parameters: query,
1064                 onComplete: function(transport) { 
1065                         prefslist_callback2(transport); 
1066                 } });
1067
1068 }
1069
1070 function selectTab(id, noupdate, subop) {
1071
1072 //      alert(id);
1073
1074         if (!id) id = active_tab;
1075
1076         try {
1077
1078                 try {
1079                         if (id != active_tab) {
1080                                 var c = $('prefContent');       
1081                                 c.scrollTop = 0;
1082                         }
1083                 } catch (e) { };
1084
1085                 if (!noupdate) {
1086
1087                         debug("selectTab: " + id + "(NU: " + noupdate + ")");
1088         
1089                         notify_progress("Loading, please wait...");
1090         
1091                         // close active infobox if needed
1092                         closeInfoBox();
1093         
1094                         // clean up all current selections, just in case
1095                         active_feed_cat = false;
1096
1097 //                      Effect.Fade("prefContent", {duration: 1, to: 0.01, 
1098 //                              queue: { position:'end', scope: 'FEED_TAB', limit: 1 } } );
1099
1100                         if (id == "feedConfig") {
1101                                 updateFeedList();
1102                         } else if (id == "filterConfig") {
1103                                 updateFilterList();
1104                         } else if (id == "labelConfig") {
1105                                 updateLabelList();
1106                         } else if (id == "genConfig") {
1107                                 updatePrefsList();
1108                         } else if (id == "userConfig") {
1109                                 updateUsersList();
1110                         }
1111                 }
1112
1113                 /* clean selection from all tabs */
1114         
1115                 var tabs_holder = $("prefTabs");
1116                 var tab = tabs_holder.firstChild;
1117
1118                 while (tab) {
1119                         if (tab.className && tab.className.match("prefsTabSelected")) {
1120                                 tab.className = "prefsTab";
1121                         }
1122                         tab = tab.nextSibling;
1123                 }
1124
1125                 /* mark new tab as selected */
1126
1127                 tab = $(id + "Tab");
1128         
1129                 if (tab) {
1130                         if (!tab.className.match("Selected")) {
1131                                 tab.className = tab.className + "Selected";
1132                         }
1133                 }
1134         
1135                 active_tab = id;
1136
1137         } catch (e) {
1138                 exception_error("selectTab", e);
1139         }
1140 }
1141
1142 function backend_sanity_check_callback2(transport) {
1143
1144         try {
1145
1146                 if (sanity_check_done) {
1147                         fatalError(11, "Sanity check request received twice. This can indicate "+
1148                       "presence of Firebug or some other disrupting extension. "+
1149                                 "Please disable it and try again.");
1150                         return;
1151                 }
1152
1153                 if (!transport.responseXML) {
1154                         fatalError(3, "Sanity Check: Received reply is not XML", 
1155                                 transport.responseText);
1156                         return;
1157                 }
1158
1159                 var reply = transport.responseXML.firstChild.firstChild;
1160
1161                 if (!reply) {
1162                         fatalError(3, "Sanity Check: Invalid RPC reply", transport.responseText);
1163                         return;
1164                 }
1165
1166                 var error_code = reply.getAttribute("error-code");
1167         
1168                 if (error_code && error_code != 0) {
1169                         return fatalError(error_code, reply.getAttribute("error-msg"));
1170                 }
1171
1172                 debug("sanity check ok");
1173
1174                 var params = reply.nextSibling;
1175
1176                 if (params) {
1177                         debug('reading init-params...');
1178                         var param = params.firstChild;
1179
1180                         while (param) {
1181                                 var k = param.getAttribute("key");
1182                                 var v = param.getAttribute("value");
1183                                 debug(k + " => " + v);
1184                                 init_params[k] = v;                                     
1185                                 param = param.nextSibling;
1186                         }
1187                 }
1188
1189                 sanity_check_done = true;
1190
1191                 init_second_stage();
1192
1193         } catch (e) {
1194                 exception_error("backend_sanity_check_callback", e);
1195         }
1196 }
1197
1198 function init_second_stage() {
1199
1200         try {
1201                 active_tab = getInitParam("prefs_active_tab");
1202                 if (!$(active_tab+"Tab")) active_tab = "genConfig";
1203                 if (!active_tab || active_tab == '0') active_tab = "genConfig";
1204
1205                 document.onkeydown = pref_hotkey_handler;
1206                 document.onmousedown = mouse_down_handler;
1207                 document.onmouseup = mouse_up_handler;
1208
1209                 var tab = getURLParam('tab');
1210                 
1211                 caller_subop = getURLParam('subop');
1212
1213                 if (getURLParam("subopparam")) {
1214                         caller_subop = caller_subop + ":" + getURLParam("subopparam");
1215                 }
1216
1217                 if (tab) {
1218                         active_tab = tab;
1219                 }
1220
1221                 if (navigator.userAgent.match("Opera")) {       
1222                         setTimeout("selectTab()", 500);
1223                 } else {
1224                         selectTab(active_tab);
1225                 }
1226                 notify("");
1227
1228                 loading_set_progress(60);
1229
1230                 setTimeout("hotkey_prefix_timeout()", 5*1000);
1231
1232         } catch (e) {
1233                 exception_error("init_second_stage", e);
1234         }
1235 }
1236
1237 function init() {
1238
1239         try {
1240         
1241                 if (getURLParam('debug')) {
1242                         Element.show("debug_output");
1243                         debug('debug mode activated');
1244                 }
1245
1246                 loading_set_progress(30);
1247
1248                 var query = "?op=rpc&subop=sanityCheck";
1249
1250                 new Ajax.Request("backend.php", {
1251                         parameters: query,
1252                         onComplete: function(transport) { 
1253                                 backend_sanity_check_callback2(transport);
1254                         } });
1255
1256         } catch (e) {
1257                 exception_error("init", e);
1258         }
1259 }
1260
1261 function categorizeSelectedFeeds() {
1262
1263         var sel_rows = getSelectedFeeds();
1264
1265         var cat_sel = $("sfeed_set_fcat");
1266         var cat_id = cat_sel[cat_sel.selectedIndex].value;
1267
1268         if (sel_rows.length > 0) {
1269
1270                 notify_progress("Changing category of selected feeds...");
1271
1272                 var query = "?op=pref-feeds&subop=categorize&ids="+
1273                         param_escape(sel_rows.toString()) + "&cat_id=" + param_escape(cat_id);
1274
1275                 new Ajax.Request("backend.php", {
1276                         parameters: query,
1277                         onComplete: function(transport) { 
1278                                 feedlist_callback2(transport); 
1279                         } });
1280
1281         } else {
1282
1283                 alert(__("No feeds are selected."));
1284
1285         }
1286
1287 }
1288
1289 function validatePrefsReset() {
1290         try {
1291                 var ok = confirm(__("Reset to defaults?"));
1292
1293                 if (ok) {
1294
1295                         var query = Form.serialize("pref_prefs_form");
1296                         query = query + "&subop=reset-config";
1297                         debug(query);
1298
1299                         new Ajax.Request("backend.php", {
1300                                 parameters: query,
1301                                 onComplete: function(transport) { 
1302                                         prefs_reset_callback2(transport);
1303                                 } });
1304
1305                 }
1306
1307         } catch (e) {
1308                 exception_error("validatePrefsSave", e);
1309         }
1310
1311         return false;
1312
1313 }
1314
1315 function feedBrowserSubscribe() {
1316         try {
1317
1318                 var selected = getSelectedFeedsFromBrowser();
1319
1320                 var mode = document.forms['feed_browser'].mode;
1321
1322                 mode = mode[mode.selectedIndex].value;
1323
1324                 if (selected.length > 0) {
1325                         closeInfoBox();
1326
1327                         var query = "?op=pref-feeds&subop=massSubscribe&ids="+
1328                                 param_escape(selected.toString()) + "&mode=" + param_escape(mode);
1329
1330                         new Ajax.Request("backend.php", {
1331                                 parameters: query,
1332                                 onComplete: function(transport) { 
1333                                         feedlist_callback2(transport); 
1334                                 } });
1335
1336                 } else {
1337                         alert(__("No feeds are selected."));
1338                 }
1339
1340         } catch (e) {
1341                 exception_error("feedBrowserSubscribe", e);
1342         }
1343 }
1344
1345 function updateBigFeedBrowserBtn() {
1346         notify_progress("Loading, please wait...");
1347         return updateBigFeedBrowser();
1348 }
1349
1350 function selectPrefRows(kind, select) {
1351
1352         if (kind) {
1353                 var opbarid = false;    
1354                 var nchk = false;
1355                 var nrow = false;
1356                 var lname = false;
1357
1358                 if (kind == "feed") {
1359                         opbarid = "feedOpToolbar";
1360                         nrow = "FEEDR-";
1361                         nchk = "FRCHK-";                        
1362                         lname = "prefFeedList";
1363                 } else if (kind == "fcat") {
1364                         opbarid = "catOpToolbar";
1365                         nrow = "FCATR-";
1366                         nchk = "FCCHK-";
1367                         lname = "prefFeedCatList";
1368                 } else if (kind == "filter") {
1369                         opbarid = "filterOpToolbar";
1370                         nrow = "FILRR-";
1371                         nchk = "FICHK-";
1372                         lname = "prefFilterList";
1373                 } else if (kind == "label") {
1374                         opbarid = "labelOpToolbar";
1375                         nrow = "LILRR-";
1376                         nchk = "LICHK-";
1377                         lname = "prefLabelList";
1378                 } else if (kind == "user") {
1379                         opbarid = "userOpToolbar";
1380                         nrow = "UMRR-";
1381                         nchk = "UMCHK-";
1382                         lname = "prefUserList";
1383                 }
1384
1385                 if (opbarid) {
1386                         selectTableRowsByIdPrefix(lname, nrow, nchk, select);
1387                         disableContainerChildren(opbarid, !select);
1388                 }
1389
1390         } 
1391 }
1392
1393
1394 function toggleSelectPrefRow(sender, kind) {
1395
1396         toggleSelectRow(sender);
1397
1398         if (kind) {
1399                 var opbarid = false;    
1400                 var nsel = -1;
1401                 
1402                 if (kind == "feed") {
1403                         opbarid = "feedOpToolbar";
1404                         nsel = getSelectedFeeds();
1405                 } else if (kind == "fcat") {
1406                         opbarid = "catOpToolbar";
1407                         nsel = getSelectedFeedCats();
1408                 } else if (kind == "filter") {
1409                         opbarid = "filterOpToolbar";
1410                         nsel = getSelectedFilters();
1411                 } else if (kind == "label") {
1412                         opbarid = "labelOpToolbar";
1413                         nsel = getSelectedLabels();
1414                 } else if (kind == "user") {
1415                         opbarid = "userOpToolbar";
1416                         nsel = getSelectedUsers();
1417                 }
1418
1419                 if (opbarid && nsel != -1) {
1420                         disableContainerChildren(opbarid, nsel == false);
1421                 }
1422
1423         } 
1424 }
1425
1426 function toggleSelectFBListRow(sender) {
1427         toggleSelectListRow(sender);
1428         disableContainerChildren("fbrOpToolbar", getSelectedFeedsFromBrowser() == 0);
1429 }
1430
1431 var seq = "";
1432
1433 function pref_hotkey_handler(e) {
1434         try {
1435
1436                 var keycode;
1437                 var shift_key = false;
1438
1439                 var cmdline = $('cmdline');
1440
1441                 try {
1442                         shift_key = e.shiftKey;
1443                 } catch (e) {
1444
1445                 }
1446
1447                 if (window.event) {
1448                         keycode = window.event.keyCode;
1449                 } else if (e) {
1450                         keycode = e.which;
1451                 }
1452
1453                 var keychar = String.fromCharCode(keycode);
1454
1455                 if (keycode == 27) { // escape
1456                         if (Element.visible("hotkey_help_overlay")) {
1457                                 Element.hide("hotkey_help_overlay");
1458                         }
1459                         colorPickerHideAll();
1460                         hotkey_prefix = false;
1461                         closeInfoBox();
1462                 } 
1463
1464                 if (!hotkeys_enabled) {
1465                         debug("hotkeys disabled");
1466                         return;
1467                 }
1468
1469                 if (keycode == 16) return; // ignore lone shift
1470
1471                 if ((keycode == 67 || keycode == 71) && !hotkey_prefix) {
1472                         hotkey_prefix = keycode;
1473
1474                         var date = new Date();
1475                         var ts = Math.round(date.getTime() / 1000);
1476
1477                         hotkey_prefix_pressed = ts;
1478
1479                         cmdline.innerHTML = keychar;
1480                         Element.show(cmdline);
1481
1482                         debug("KP: PREFIX=" + keycode + " CHAR=" + keychar);
1483                         return;
1484                 }
1485
1486                 if (Element.visible("hotkey_help_overlay")) {
1487                         Element.hide("hotkey_help_overlay");
1488                 }
1489
1490                 if (keycode == 13 || keycode == 27) {
1491                         seq = "";
1492                 } else {
1493                         seq = seq + "" + keycode;
1494                 }
1495
1496                 /* Global hotkeys */
1497
1498                 Element.hide(cmdline);
1499
1500                 if (!hotkey_prefix) {
1501
1502                         if (keycode == 68 && shift_key) { // d
1503                                 if (!Element.visible("debug_output")) {
1504                                         Element.show("debug_output");
1505                                         debug('debug mode activated');
1506                                 } else {
1507                                         Element.hide("debug_output");
1508                                 }
1509                                 return;
1510                         }
1511         
1512                         if ((keycode == 191 || keychar == '?') && shift_key) { // ?
1513                                 if (!Element.visible("hotkey_help_overlay")) {
1514                                         //Element.show("hotkey_help_overlay");
1515                                         Effect.Appear("hotkey_help_overlay", {duration : 0.3});
1516                                 } else {
1517                                         Element.hide("hotkey_help_overlay");
1518                                 }
1519                                 return false;
1520                         }
1521
1522                         if (keycode == 191 || keychar == '/') { // /
1523                                 var search_boxes = new Array("label_search", 
1524                                         "feed_search", "filter_search", "user_search", "feed_browser_search");
1525
1526                                 for (var i = 0; i < search_boxes.length; i++) {
1527                                         var elem = $(search_boxes[i]);
1528                                         if (elem) {
1529                                                 focus_element(search_boxes[i]);
1530                                                 return false;
1531                                         }
1532                                 }
1533                         }
1534                 }
1535
1536                 /* Prefix c */
1537
1538                 if (hotkey_prefix == 67) { // c
1539                         hotkey_prefix = false;
1540
1541                         if (keycode == 70) { // f
1542                                 displayDlg("quickAddFilter");
1543                                 return false;
1544                         }
1545
1546                         if (keycode == 83) { // s
1547                                 displayDlg("quickAddFeed");
1548                                 return false;
1549                         }
1550
1551 /*                      if (keycode == 76) { // l
1552                                 displayDlg("quickAddLabel");
1553                                 return false;
1554                         } */
1555
1556                         if (keycode == 85) { // u
1557                                 // no-op
1558                         }
1559
1560                         if (keycode == 67) { // c
1561                                 editFeedCats();
1562                                 return false;
1563                         }
1564
1565                         if (keycode == 84 && shift_key) { // T
1566                                 browseFeeds();
1567                                 return false;
1568                         }
1569
1570                 }
1571
1572                 /* Prefix g */
1573
1574                 if (hotkey_prefix == 71) { // g
1575
1576                         hotkey_prefix = false;
1577
1578                         if (keycode == 49 && $("genConfigTab")) { // 1
1579                                 selectTab("genConfig");
1580                                 return false;
1581                         }
1582
1583                         if (keycode == 50 && $("feedConfigTab")) { // 2
1584                                 selectTab("feedConfig");
1585                                 return false;
1586                         }
1587
1588                         if (keycode == 51 && $("filterConfigTab")) { // 4
1589                                 selectTab("filterConfig");
1590                                 return false;
1591                         }
1592
1593                         if (keycode == 52 && $("labelConfigTab")) { // 5
1594                                 selectTab("labelConfig");
1595                                 return false;
1596                         }
1597
1598                         if (keycode == 53 && $("userConfigTab")) { // 6
1599                                 selectTab("userConfig");
1600                                 return false;
1601                         }
1602
1603                         if (keycode == 88) { // x
1604                                 return gotoMain();
1605                         }
1606
1607                 }
1608
1609                 if ($("piggie")) {
1610         
1611                         if (seq.match("807371717369")) {
1612                                 seq = "";
1613                                 piggie(true);
1614                         } else {
1615                                 piggie(false);
1616                         }
1617                 }
1618
1619                 if (hotkey_prefix) {
1620                         debug("KP: PREFIX=" + hotkey_prefix + " CODE=" + keycode + " CHAR=" + keychar);
1621                 } else {
1622                         debug("KP: CODE=" + keycode + " CHAR=" + keychar);
1623                 }
1624
1625         } catch (e) {
1626                 exception_error("pref_hotkey_handler", e);
1627         }
1628 }
1629
1630 function editFeedCats() {
1631         try {
1632                 $("subscribe_to_feed_btn").disabled = true;
1633         
1634                 try {
1635                         $("top25_feeds_btn").disabled = true;
1636                 } catch (e) {
1637                         // this button is not always available, no-op if not found
1638                 }
1639         
1640                 var query = "?op=pref-feeds&subop=editCats";
1641
1642                 new Ajax.Request("backend.php", {
1643                         parameters: query,
1644                         onComplete: function(transport) {
1645                                 infobox_feed_cat_callback2(transport);
1646                         } });
1647         } catch (e) {
1648                 exception_error("editFeedCats", e);
1649         }
1650 }
1651
1652 function showFeedsWithErrors() {
1653         displayDlg('feedUpdateErrors');
1654 }
1655
1656 function changeUserPassword() {
1657
1658         try {
1659
1660                 var f = document.forms["change_pass_form"];
1661
1662                 if (f) {
1663                         if (f.OLD_PASSWORD.value == "") {
1664                                 new Effect.Highlight(f.OLD_PASSWORD);
1665                                 notify_error("Old password cannot be blank.");
1666                                 return false;
1667                         }
1668
1669                         if (f.NEW_PASSWORD.value == "") {
1670                                 new Effect.Highlight(f.NEW_PASSWORD);
1671                                 notify_error("New password cannot be blank.");
1672                                 return false;
1673                         }
1674
1675                         if (f.CONFIRM_PASSWORD.value == "") {
1676                                 new Effect.Highlight(f.CONFIRM_PASSWORD);
1677                                 notify_error("Entered passwords do not match.");
1678                                 return false;
1679                         }
1680
1681                         if (f.CONFIRM_PASSWORD.value != f.NEW_PASSWORD.value) {
1682                                 new Effect.Highlight(f.CONFIRM_PASSWORD);
1683                                 new Effect.Highlight(f.NEW_PASSWORD);
1684                                 notify_error("Entered passwords do not match.");
1685                                 return false;
1686                         }
1687
1688                 }
1689
1690                 var query = Form.serialize("change_pass_form");
1691         
1692                 notify_progress("Trying to change password...");
1693
1694                 new Ajax.Request("backend.php", {
1695                         parameters: query,
1696                         onComplete: function(transport) { 
1697                                 changepass_callback2(transport); 
1698                         } });
1699
1700
1701         } catch (e) {
1702                 exception_error("changeUserPassword", e);
1703         }
1704         
1705         return false;
1706 }
1707
1708 function changeUserEmail() {
1709
1710         try {
1711
1712                 var query = Form.serialize("change_email_form");
1713         
1714                 notify_progress("Trying to change e-mail...");
1715         
1716                 new Ajax.Request("backend.php", {
1717                         parameters: query,
1718                         onComplete: function(transport) { 
1719                                 notify_callback2(transport); 
1720                         } });
1721
1722         } catch (e) {
1723                 exception_error("changeUserPassword", e);
1724         }
1725         
1726         return false;
1727
1728 }
1729
1730 function feedlistToggleSLAT() {
1731         notify_progress("Loading, please wait...");
1732         updateFeedList()
1733 }
1734
1735 function pubRegenKey() {
1736
1737         var ok = confirm(__("Replace current publishing address with a new one?"));
1738
1739         if (ok) {
1740
1741                 notify_progress("Trying to change address...");
1742
1743                 var query = "?op=rpc&subop=regenPubKey";
1744
1745                 new Ajax.Request("backend.php", {
1746                         parameters: query,
1747                         onComplete: function(transport) {
1748                                         replace_pubkey_callback(transport);
1749                                 } });
1750
1751         }
1752
1753         return false;
1754 }
1755
1756 function validatePrefsSave() {
1757         try {
1758
1759                 var ok = confirm(__("Save current configuration?"));
1760
1761                 if (ok) {
1762
1763                         var query = Form.serialize("pref_prefs_form");
1764                         query = query + "&subop=save-config";
1765                         debug(query);
1766
1767                         new Ajax.Request("backend.php", {
1768                                 parameters: query,
1769                                 onComplete: function(transport) { 
1770                                 notify_callback2(transport); 
1771                         } });
1772
1773                 }
1774
1775         } catch (e) {
1776                 exception_error("validatePrefsSave", e);
1777         }
1778
1779         return false;
1780 }
1781
1782 function feedActionChange() {
1783         try {
1784                 var chooser = $("feedActionChooser");
1785                 var opid = chooser[chooser.selectedIndex].value;
1786
1787                 chooser.selectedIndex = 0;
1788                 feedActionGo(opid);
1789         } catch (e) {
1790                 exception_error("feedActionChange", e);
1791         }
1792 }
1793
1794 function feedActionGo(op) {     
1795         try {
1796                 if (op == "facEdit") {
1797
1798                         var rows = getSelectedFeeds();
1799
1800                         if (rows.length > 1) {
1801                                 editSelectedFeeds();
1802                         } else {
1803                                 editSelectedFeed();
1804                         }
1805                 }
1806
1807                 if (op == "facClear") {
1808                         clearSelectedFeeds();
1809                 }
1810
1811                 if (op == "facPurge") {
1812                         purgeSelectedFeeds();
1813                 }
1814
1815                 if (op == "facEditCats") {
1816                         editFeedCats();
1817                 }
1818
1819                 if (op == "facRescore") {
1820                         rescoreSelectedFeeds();
1821                 }
1822
1823                 if (op == "facUnsubscribe") {
1824                         removeSelectedFeeds();
1825                 }
1826
1827         } catch (e) {
1828                 exception_error("feedActionGo", e);
1829
1830         }
1831 }
1832
1833 function clearFeedArticles(feed_id) {
1834
1835         notify_progress("Clearing feed...");
1836
1837         var query = "?op=pref-feeds&quiet=1&subop=clear&id=" + feed_id;
1838
1839         new Ajax.Request("backend.php", {
1840                 parameters: query,
1841                 onComplete: function(transport) {
1842                                 notify('');
1843                         } });
1844
1845         return false;
1846 }
1847
1848 function rescoreSelectedFeeds() {
1849
1850         var sel_rows = getSelectedFeeds();
1851
1852         if (sel_rows.length > 0) {
1853
1854                 //var ok = confirm(__("Rescore last 100 articles in selected feeds?"));
1855                 var ok = confirm(__("Rescore articles in selected feeds?"));
1856
1857                 if (ok) {
1858                         notify_progress("Rescoring selected feeds...", true);
1859         
1860                         var query = "?op=pref-feeds&subop=rescore&quiet=1&ids="+
1861                                 param_escape(sel_rows.toString());
1862
1863                         new Ajax.Request("backend.php", {
1864                                 parameters: query,
1865                                 onComplete: function(transport) {
1866                                                 notify_callback2(transport);
1867                         } });
1868
1869                 }
1870         } else {
1871                 alert(__("No feeds are selected."));
1872         }
1873
1874         return false;
1875 }
1876
1877 function rescore_all_feeds() {
1878         var ok = confirm(__("Rescore all articles? This operation may take a lot of time."));
1879
1880         if (ok) {
1881                 notify_progress("Rescoring feeds...", true);
1882
1883                 var query = "?op=pref-feeds&subop=rescoreAll&quiet=1";
1884
1885                 new Ajax.Request("backend.php", {
1886                         parameters: query,
1887                         onComplete: function(transport) {
1888                                         notify_callback2(transport);
1889                 } });
1890         }
1891 }
1892
1893 function removeFilter(id, title) {
1894
1895         try {
1896
1897                 var msg = __("Remove filter %s?").replace("%s", title);
1898         
1899                 var ok = confirm(msg);
1900         
1901                 if (ok) {
1902                         closeInfoBox();
1903         
1904                         notify_progress("Removing filter...");
1905                 
1906                         var query = "?op=pref-filters&subop=remove&ids="+
1907                                 param_escape(id);
1908
1909                         new Ajax.Request("backend.php", {
1910                                 parameters: query,
1911                                 onComplete: function(transport) {
1912                                                 filterlist_callback2(transport);
1913                         } });
1914
1915                 }
1916
1917         } catch (e) {
1918                 exception_error("removeFilter", e);
1919         }
1920
1921         return false;
1922 }
1923
1924 function unsubscribeFeed(id, title) {
1925
1926         try {
1927
1928                 var msg = __("Unsubscribe from %s?").replace("%s", title);
1929         
1930                 var ok = confirm(msg);
1931         
1932                 if (ok) {
1933                         closeInfoBox();
1934         
1935                         notify_progress("Removing feed...");
1936                 
1937                         var query = "?op=pref-feeds&subop=remove&ids="+
1938                                 param_escape(id);
1939         
1940                         new Ajax.Request("backend.php", {
1941                                         parameters: query,
1942                                         onComplete: function(transport) {
1943                                                         feedlist_callback2(transport);
1944                                 } });
1945                 }
1946         
1947         } catch (e) {
1948                 exception_error("unsubscribeFeed", e);
1949         }
1950
1951         return false;
1952
1953 }
1954
1955 function feedsEditSave() {
1956         try {
1957
1958                 var ok = confirm(__("Save changes to selected feeds?"));
1959
1960                 if (ok) {
1961
1962                         var f = document.forms["batch_edit_feed_form"];
1963
1964                         var query = Form.serialize("batch_edit_feed_form");
1965
1966                         /* Form.serialize ignores unchecked checkboxes */
1967
1968                         if (!query.match("&hidden=") && 
1969                                         f.hidden.disabled == false) {
1970                                 query = query + "&hidden=false";
1971                         }
1972
1973                         if (!query.match("&rtl_content=") && 
1974                                         f.rtl_content.disabled == false) {
1975                                 query = query + "&rtl_content=false";
1976                         }
1977
1978                         if (!query.match("&private=") && 
1979                                         f.private.disabled == false) {
1980                                 query = query + "&private=false";
1981                         }
1982
1983                         if (!query.match("&cache_images=") && 
1984                                         f.cache_images.disabled == false) {
1985                                 query = query + "&cache_images=false";
1986                         }
1987
1988                         if (!query.match("&include_in_digest=") && 
1989                                         f.include_in_digest.disabled == false) {
1990                                 query = query + "&include_in_digest=false";
1991                         }
1992         
1993                         closeInfoBox();
1994         
1995                         notify_progress("Saving feeds...");
1996         
1997                         new Ajax.Request("backend.php", {
1998                                 parameters: query,
1999                                 onComplete: function(transport) { 
2000                                         feedlist_callback2(transport); 
2001                                 } });
2002
2003                 }
2004
2005                 return false;
2006         } catch (e) {
2007                 exception_error("feedsEditSave", e);
2008         }
2009 }
2010
2011 function batchFeedsToggleField(cb, elem, label) {
2012         try {
2013                 var f = document.forms["batch_edit_feed_form"];
2014                 var l = $(label);
2015
2016                 if (cb.checked) {
2017                         f[elem].disabled = false;
2018
2019                         if (l) {
2020                                 l.className = "";
2021                         };
2022
2023 //                      new Effect.Highlight(f[elem], {duration: 1, startcolor: "#fff7d5",
2024 //                              queue: { position:'end', scope: 'BPEFQ', limit: 1 } } );
2025
2026                 } else {
2027                         f[elem].disabled = true;
2028
2029                         if (l) {
2030                                 l.className = "insensitive";
2031                         };
2032
2033                 }
2034         } catch (e) {
2035                 exception_error("batchFeedsToggleField", e);
2036         }
2037 }
2038
2039 function labelColorReset() {
2040         try {
2041                 var labels = getSelectedLabels();
2042
2043                 var ok = confirm(__("Reset label colors to default?"));
2044
2045                 if (ok) {
2046
2047                         var query = "?op=pref-labels&subop=color-reset&ids="+
2048                                 param_escape(labels.toString());
2049
2050                         new Ajax.Request("backend.php", {
2051                                 parameters: query,
2052                                 onComplete: function(transport) {
2053                                                 labellist_callback2(transport);
2054                                         } });
2055                 }
2056
2057         } catch (e) {
2058                 exception_error("labelColorReset", e);
2059         }
2060 }
2061
2062 function labelColorAsk(id, kind) {
2063         try {
2064
2065                 var p = null
2066
2067                 if (kind == "fg") {
2068                         p = prompt(__("Please enter new label foreground color:"));
2069                 } else {
2070                         p = prompt(__("Please enter new label background color:"));
2071                 }
2072
2073                 if (p != null) {
2074
2075                         var query = "?op=pref-labels&subop=color-set&kind=" + kind +
2076                                 "&ids="+        param_escape(id) + "&color=" + param_escape(p);
2077
2078                         selectPrefRows('label', false);
2079
2080                         var e = $("LICID-" + id);
2081
2082                         if (e) {                
2083                                 if (kind == "fg") {
2084                                         e.style.color = p
2085                                 } else {
2086                                         e.style.backgroundColor = p;
2087                                 }
2088                         }
2089
2090                         new Ajax.Request("backend.php", { parameters: query });
2091                 }
2092
2093         } catch (e) {
2094                 exception_error("labelColorReset", e);
2095         }
2096 }
2097
2098
2099 function colorPicker(id, fg, bg) {
2100         try {
2101                 var picker = $("colorPicker-" + id);
2102
2103                 if (picker) Element.show(picker);
2104
2105         } catch (e) {
2106                 exception_error("colorPicker", e);
2107         }
2108 }
2109
2110 function colorPickerHideAll() {
2111         try {
2112                 if ($("prefLabelList")) {
2113
2114                         var elems = $("prefLabelList").getElementsByTagName("DIV");
2115
2116                         for (var i = 0; i < elems.length; i++) {
2117                                 if (elems[i].id && elems[i].id.match("colorPicker-")) {
2118                                         Element.hide(elems[i]);
2119                                 }
2120                         }
2121                 }
2122
2123         } catch (e) {
2124                 exception_error("colorPickerHideAll", e);
2125         }
2126 }
2127
2128 function colorPickerDo(id, fg, bg) {
2129         try {
2130
2131                 var query = "?op=pref-labels&subop=color-set&kind=both"+
2132                         "&ids=" + param_escape(id) + "&fg=" + param_escape(fg) + 
2133                         "&bg=" + param_escape(bg);
2134
2135                 var e = $("LICID-" + id);
2136
2137                 if (e) {                
2138                         e.style.color = fg;
2139                         e.style.backgroundColor = bg;
2140                 }
2141
2142                 new Ajax.Request("backend.php", { parameters: query });
2143
2144         } catch (e) {
2145                 exception_error("colorPickerDo", e);
2146         }
2147 }
2148
2149 function colorPickerActive(b) {
2150         color_picker_active = b;
2151 }
2152
2153 function mouse_down_handler(e) {
2154         try {
2155
2156                 /* do not prevent right click */
2157                 if (e && e.button && e.button == 2) return;
2158
2159                 if (selection_disabled) {
2160                         document.onselectstart = function() { return false; };
2161                         return false;
2162                 }
2163
2164         } catch (e) {
2165                 exception_error("mouse_down_handler", e);
2166         }
2167 }
2168
2169 function mouse_up_handler(e) {
2170         try {
2171                 mouse_is_down = false;
2172
2173                 if (!selection_disabled) {
2174                         document.onselectstart = null;
2175                 }
2176
2177                 if (!color_picker_active) {
2178                         colorPickerHideAll();
2179                 }
2180
2181         } catch (e) {
2182                 exception_error("mouse_up_handler", e);
2183         }
2184 }
2185