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