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