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