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