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