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