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