]> git.wh0rd.org Git - tt-rss.git/blob - prefs.js
interface tweaks, add info/question/exclamation pics
[tt-rss.git] / prefs.js
1 var xmlhttp = false;
2
3 var active_feed_cat = false;
4 var active_label = false;
5 var active_tab = false;
6 var feed_to_expand = false;
7
8 var piggie_top = -400;
9 var piggie_fwd = true;
10
11 var xmlhttp = Ajax.getTransport();
12
13 var init_params = new Array();
14
15 var caller_subop = false;
16
17 function expand_feed_callback() {
18         if (xmlhttp.readyState == 4) {
19                 try {   
20                         var container = document.getElementById("BRDET-" + feed_to_expand);     
21                         container.innerHTML=xmlhttp.responseText;
22                         container.style.display = "block";
23 //                      p_notify("");
24                 } catch (e) {
25                         exception_error("expand_feed_callback", e);
26                 }
27         }
28 }
29
30 function feedlist_callback() {
31         if (xmlhttp.readyState == 4) {
32                 try {   
33                         var container = document.getElementById('prefContent'); 
34                         container.innerHTML=xmlhttp.responseText;
35                         selectTab("feedConfig", true);
36
37                         if (caller_subop) {
38                                 var tuple = caller_subop.split(":");
39                                 if (tuple[0] == 'editFeed') {
40                                         window.setTimeout('editFeed('+tuple[1]+')', 100);
41                                 }                               
42
43                                 caller_subop = false;
44                         }
45
46                         notify("");
47                 } catch (e) {
48                         exception_error("feedlist_callback", e);
49                 }
50         }
51 }
52
53 function filterlist_callback() {
54         var container = document.getElementById('prefContent');
55         if (xmlhttp.readyState == 4) {
56                 container.innerHTML=xmlhttp.responseText;
57                 notify("");
58         }
59 }
60
61 function labellist_callback() {
62         var container = document.getElementById('prefContent');
63         if (xmlhttp.readyState == 4) {
64                 closeInfoBox();
65                 container.innerHTML=xmlhttp.responseText;
66                 if (active_label) {
67                         var row = document.getElementById("LILRR-" + active_label);
68                         if (row) {
69                                 if (!row.className.match("Selected")) {
70                                         row.className = row.className + "Selected";
71                                 }               
72                         }
73                         var checkbox = document.getElementById("LICHK-" + active_label);
74                         
75                         if (checkbox) {
76                                 checkbox.checked = true;
77                         }
78                 }
79                 notify("");
80         }
81 }
82
83 function labeltest_callback() {
84         var container = document.getElementById('label_test_result');
85         if (xmlhttp.readyState == 4) {
86                 container.innerHTML=xmlhttp.responseText;
87                 notify("");
88         }
89 }
90
91 function feed_browser_callback() {
92         var container = document.getElementById('prefContent');
93         if (xmlhttp.readyState == 4) {
94                 container.innerHTML=xmlhttp.responseText;
95                 notify("");
96         }
97 }
98
99 function userlist_callback() {
100         var container = document.getElementById('prefContent');
101         if (xmlhttp.readyState == 4) {
102                 container.innerHTML=xmlhttp.responseText;
103                 notify("");
104         }
105 }
106
107 function prefslist_callback() {
108         var container = document.getElementById('prefContent');
109         if (xmlhttp.readyState == 4) {
110
111                 container.innerHTML=xmlhttp.responseText;
112                 
113                 notify("");
114         }
115 }
116
117 function gethelp_callback() {
118         var container = document.getElementById('prefHelpBox');
119         if (xmlhttp.readyState == 4) {
120
121                 container.innerHTML = xmlhttp.responseText;
122                 container.style.display = "block";
123
124         }
125 }
126
127
128 function notify_callback() {
129         var container = document.getElementById('notify');
130         if (xmlhttp.readyState == 4) {
131                 container.innerHTML=xmlhttp.responseText;
132         }
133 }
134
135 function updateFeedList(sort_key) {
136
137         if (!xmlhttp_ready(xmlhttp)) {
138                 printLockingError();
139                 return
140         }
141
142 //      document.getElementById("prefContent").innerHTML = "Loading feeds, please wait...";
143
144 //      p_notify("Loading, please wait...");
145
146         var feed_search = document.getElementById("feed_search");
147         var search = "";
148         if (feed_search) { search = feed_search.value; }
149
150         xmlhttp.open("GET", "backend.php?op=pref-feeds" +
151                 "&sort=" + param_escape(sort_key) + 
152                 "&search=" + param_escape(search), true);
153         xmlhttp.onreadystatechange=feedlist_callback;
154         xmlhttp.send(null);
155
156 }
157
158 function updateUsersList(sort_key) {
159
160         if (!xmlhttp_ready(xmlhttp)) {
161                 printLockingError();
162                 return
163         }
164
165 //      document.getElementById("prefContent").innerHTML = "Loading feeds, please wait...";
166
167 //      p_notify("Loading, please wait...");
168
169         xmlhttp.open("GET", "backend.php?op=pref-users&sort="
170                 + param_escape(sort_key), true);
171         xmlhttp.onreadystatechange=userlist_callback;
172         xmlhttp.send(null);
173
174 }
175
176 function addLabel() {
177
178         if (!xmlhttp_ready(xmlhttp)) {
179                 printLockingError();
180                 return
181         }
182
183         var form = document.forms['label_edit_form'];
184
185         var sql_exp = form.sql_exp.value;
186         var description = form.description.value;
187
188         if (sql_exp == "") {
189                 alert("Can't create label: missing SQL expression.");
190                 return false;
191         }
192
193         if (description == "") {
194                 alert("Can't create label: missing caption.");
195                 return false;
196         }
197
198         var query = Form.serialize("label_edit_form");
199
200         xmlhttp.open("GET", "backend.php?op=pref-labels&subop=add&" + query, true);                     
201         xmlhttp.onreadystatechange=infobox_submit_callback;
202         xmlhttp.send(null);
203 }
204
205 function addFeed() {
206
207         if (!xmlhttp_ready(xmlhttp)) {
208                 printLockingError();
209                 return
210         }
211
212         var link = document.getElementById("fadd_link");
213
214         if (link.value.length == 0) {
215                 alert("Error: No feed URL given.");
216         } else if (!isValidURL(link.value)) {
217                 alert("Error: Invalid feed URL.");
218         } else {
219                 notify("Adding feed...");
220
221                 xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=add&from=tt-rss&feed_url=" +
222                         param_escape(link.value), true);
223                 xmlhttp.onreadystatechange=feedlist_callback;
224                 xmlhttp.send(null);
225
226                 link.value = "";
227
228         }
229
230 }
231
232 function addFeedCat() {
233
234         if (!xmlhttp_ready(xmlhttp)) {
235                 printLockingError();
236                 return
237         }
238
239         var cat = document.getElementById("fadd_cat");
240
241         if (cat.value.length == 0) {
242                 alert("Can't add category: no name specified.");
243         } else {
244                 notify("Adding feed category...");
245
246                 xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=editCats&action=add&cat=" +
247                         param_escape(cat.value), true);
248                 xmlhttp.onreadystatechange=infobox_callback;
249                 xmlhttp.send(null);
250
251                 link.value = "";
252
253         }
254
255 }
256 function addUser() {
257
258         if (!xmlhttp_ready(xmlhttp)) {
259                 printLockingError();
260                 return
261         }
262
263         var sqlexp = document.getElementById("uadd_box");
264
265         if (sqlexp.value.length == 0) {
266                 alert("Can't add user: no login specified.");
267         } else {
268                 notify("Adding user...");
269
270                 xmlhttp.open("GET", "backend.php?op=pref-users&subop=add&login=" +
271                         param_escape(sqlexp.value), true);                      
272                         
273                 xmlhttp.onreadystatechange=userlist_callback;
274                 xmlhttp.send(null);
275
276                 sqlexp.value = "";
277         }
278
279 }
280
281 function editLabel(id) {
282
283         if (!xmlhttp_ready(xmlhttp)) {
284                 printLockingError();
285                 return
286         }
287
288         document.getElementById("label_create_btn").disabled = true;
289
290         active_label = id;
291
292         selectTableRowsByIdPrefix('prefLabelList', 'LILRR-', 'LICHK-', false);
293         selectTableRowById('LILRR-'+id, 'LICHK-'+id, true);
294
295         xmlhttp.open("GET", "backend.php?op=pref-labels&subop=edit&id=" +
296                 param_escape(id), true);
297         xmlhttp.onreadystatechange=infobox_callback;
298         xmlhttp.send(null);
299
300 }
301
302 function editUser(id) {
303
304         if (!xmlhttp_ready(xmlhttp)) {
305                 printLockingError();
306                 return
307         }
308
309         selectTableRowsByIdPrefix('prefUserList', 'UMRR-', 'UMCHK-', false);
310         selectTableRowById('UMRR-'+id, 'UMCHK-'+id, true);
311
312         xmlhttp.open("GET", "backend.php?op=pref-users&subop=edit&id=" +
313                 param_escape(id), true);
314         xmlhttp.onreadystatechange=infobox_callback;
315         xmlhttp.send(null);
316
317 }
318
319 function editFilter(id) {
320
321         if (!xmlhttp_ready(xmlhttp)) {
322                 printLockingError();
323                 return
324         }
325
326         document.getElementById("create_filter_btn").disabled = true;
327
328         selectTableRowsByIdPrefix('prefFilterList', 'FILRR-', 'FICHK-', false);
329         selectTableRowById('FILRR-'+id, 'FICHK-'+id, true);
330
331         xmlhttp.open("GET", "backend.php?op=pref-filters&subop=edit&id=" + param_escape(id), true);
332         xmlhttp.onreadystatechange=infobox_callback;
333         xmlhttp.send(null);
334 }
335
336 function editFeed(feed) {
337
338 //      notify("Editing feed...");
339
340         if (!xmlhttp_ready(xmlhttp)) {
341                 printLockingError();
342                 return
343         }
344
345         // clean selection from all rows & select row being edited
346         selectTableRowsByIdPrefix('prefFeedList', 'FEEDR-', 'FRCHK-', false);
347         selectTableRowById('FEEDR-'+feed, 'FRCHK-'+feed, true);
348
349         xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=editfeed&id=" +
350                 param_escape(feed), true);
351
352         xmlhttp.onreadystatechange=infobox_callback;
353         xmlhttp.send(null);
354
355 }
356
357 function editFeedCat(cat) {
358
359         if (!xmlhttp_ready(xmlhttp)) {
360                 printLockingError();
361                 return
362         }
363
364         active_feed_cat = cat;
365
366         xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=editCats&action=edit&id=" +
367                 param_escape(cat), true);
368         xmlhttp.onreadystatechange=infobox_callback;
369         xmlhttp.send(null);
370
371 }
372
373 function getSelectedLabels() {
374         return getSelectedTableRowIds("prefLabelList", "LILRR");
375 }
376
377 function getSelectedUsers() {
378         return getSelectedTableRowIds("prefUserList", "UMRR");
379 }
380
381 function getSelectedFeeds() {
382         return getSelectedTableRowIds("prefFeedList", "FEEDR");
383 }
384
385 function getSelectedFilters() {
386         return getSelectedTableRowIds("prefFilterList", "FILRR");
387 }
388
389 function getSelectedFeedCats() {
390         return getSelectedTableRowIds("prefFeedCatList", "FCATR");
391 }
392
393 function getSelectedFeedsFromBrowser() {
394
395         var list = document.getElementById("browseFeedList");
396         if (!list) list = document.getElementById("browseBigFeedList");
397
398         var selected = new Array();
399         
400         for (i = 0; i < list.childNodes.length; i++) {
401                 var child = list.childNodes[i];
402                 if (child.id && child.id.match("FBROW-")) {
403                         var id = child.id.replace("FBROW-", "");
404                         
405                         var cb = document.getElementById("FBCHK-" + id);
406
407                         if (cb.checked) {
408                                 selected.push(id);
409                         }
410                 }
411         }
412
413         return selected;
414 }
415
416 function removeSelectedLabels() {
417
418         if (!xmlhttp_ready(xmlhttp)) {
419                 printLockingError();
420                 return
421         }
422
423         var sel_rows = getSelectedLabels();
424
425         if (sel_rows.length > 0) {
426
427                 var ok = confirm("Remove selected labels?");
428
429                 if (ok) {
430                         notify("Removing selected labels...");
431         
432                         xmlhttp.open("GET", "backend.php?op=pref-labels&subop=remove&ids="+
433                                 param_escape(sel_rows.toString()), true);
434                         xmlhttp.onreadystatechange=labellist_callback;
435                         xmlhttp.send(null);
436                 }
437         } else {
438                 alert("No labels are selected.");
439         }
440
441         return false;
442 }
443
444 function removeSelectedUsers() {
445
446         if (!xmlhttp_ready(xmlhttp)) {
447                 printLockingError();
448                 return
449         }
450
451         var sel_rows = getSelectedUsers();
452
453         if (sel_rows.length > 0) {
454
455                 var ok = confirm("Remove selected users?");
456
457                 if (ok) {
458                         notify("Removing selected users...");
459         
460                         xmlhttp.open("GET", "backend.php?op=pref-users&subop=remove&ids="+
461                                 param_escape(sel_rows.toString()), true);
462                         xmlhttp.onreadystatechange=userlist_callback;
463                         xmlhttp.send(null);
464                 }
465
466         } else {
467                 alert("No users are selected.");
468         }
469
470         return false;
471 }
472
473 function removeSelectedFilters() {
474
475         if (!xmlhttp_ready(xmlhttp)) {
476                 printLockingError();
477                 return
478         }
479
480         var sel_rows = getSelectedFilters();
481
482         if (sel_rows.length > 0) {
483
484                 var ok = confirm("Remove selected filters?");
485
486                 if (ok) {
487                         notify("Removing selected filters...");
488         
489                         xmlhttp.open("GET", "backend.php?op=pref-filters&subop=remove&ids="+
490                                 param_escape(sel_rows.toString()), true);
491                         xmlhttp.onreadystatechange=filterlist_callback;
492                         xmlhttp.send(null);
493                 }
494         } else {
495                 alert("No filters are selected.");
496         }
497
498         return false;
499 }
500
501
502 function removeSelectedFeeds() {
503
504         if (!xmlhttp_ready(xmlhttp)) {
505                 printLockingError();
506                 return
507         }
508
509         var sel_rows = getSelectedFeeds();
510
511         if (sel_rows.length > 0) {
512
513                 var ok = confirm("Unsubscribe from selected feeds?");
514
515                 if (ok) {
516
517                         notify("Unsubscribing from selected feeds...");
518         
519                         xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=remove&ids="+
520                                 param_escape(sel_rows.toString()), true);
521                         xmlhttp.onreadystatechange=feedlist_callback;
522                         xmlhttp.send(null);
523                 }
524
525         } else {
526
527                 alert("No feeds are selected.");
528
529         }
530         
531         return false;
532 }
533
534 function removeSelectedFeedCats() {
535
536         if (!xmlhttp_ready(xmlhttp)) {
537                 printLockingError();
538                 return
539         }
540
541         var sel_rows = getSelectedFeedCats();
542
543         if (sel_rows.length > 0) {
544
545                 var ok = confirm("Remove selected categories?");
546
547                 if (ok) {
548                         notify("Removing selected categories...");
549         
550                         xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=editCats&action=remove&ids="+
551                                 param_escape(sel_rows.toString()), true);
552                         xmlhttp.onreadystatechange=infobox_callback;
553                         xmlhttp.send(null);
554                 }
555
556         } else {
557
558                 alert("No categories are selected.");
559
560         }
561
562         return false;
563 }
564
565 function feedEditCancel() {
566
567         if (!xmlhttp_ready(xmlhttp)) {
568                 printLockingError();
569                 return
570         }
571
572         closeInfoBox();
573
574         selectPrefRows('feed', false); // cleanup feed selection
575
576         return false;
577 }
578
579 function feedCatEditCancel() {
580
581         if (!xmlhttp_ready(xmlhttp)) {
582                 printLockingError();
583                 return
584         }
585
586         active_feed_cat = false;
587
588 //      notify("Operation cancelled.");
589
590         xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=editCats", true);
591         xmlhttp.onreadystatechange=infobox_callback;
592         xmlhttp.send(null);
593
594         return false;
595 }
596
597 function feedEditSave() {
598
599         try {
600         
601                 if (!xmlhttp_ready(xmlhttp)) {
602                         printLockingError();
603                         return
604                 }
605
606                 // FIXME: add parameter validation
607
608                 var query = Form.serialize("edit_feed_form");
609
610                 notify("Saving feed...");
611
612                 xmlhttp.open("POST", "backend.php", true);
613                 xmlhttp.onreadystatechange=feedlist_callback;
614                 xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
615                 xmlhttp.send(query);
616
617                 closeInfoBox();
618
619                 return false;
620
621         } catch (e) {
622                 exception_error("feedEditSave", e);
623         } 
624 }
625
626 function feedCatEditSave() {
627
628         if (!xmlhttp_ready(xmlhttp)) {
629                 printLockingError();
630                 return
631         }
632
633         notify("Saving category...");
634
635         var query = Form.serialize("feed_cat_edit_form");
636
637         xmlhttp.open("GET", "backend.php?" + query, true);
638         xmlhttp.onreadystatechange=infobox_callback;
639         xmlhttp.send(null);
640
641         active_feed_cat = false;
642
643         return false;
644 }
645
646
647 function labelTest() {
648
649         var container = document.getElementById('label_test_result');
650         container.style.display = "block";
651         container.innerHTML = "<p>Loading, please wait...</p>";
652
653         var form = document.forms['label_edit_form'];
654
655         var sql_exp = form.sql_exp.value;
656         var description = form.description.value;
657
658         xmlhttp.open("GET", "backend.php?op=pref-labels&subop=test&expr=" +
659                 param_escape(sql_exp) + "&descr=" + param_escape(description), true);
660
661         xmlhttp.onreadystatechange=labeltest_callback;
662         xmlhttp.send(null);
663
664         return false;
665 }
666
667 function displayHelpInfobox(topic_id) {
668
669         xmlhttp.open("GET", "backend.php?op=help&tid=" +
670                 param_escape(topic_id) + "&noheaders=1", true);
671
672         xmlhttp.onreadystatechange=infobox_callback;
673         xmlhttp.send(null);
674
675 }
676
677 function labelEditCancel() {
678
679         if (!xmlhttp_ready(xmlhttp)) {
680                 printLockingError();
681                 return
682         }
683
684         document.getElementById("label_create_btn").disabled = false;
685
686         active_label = false;
687
688         selectPrefRows('label', false); // cleanup feed selection
689         closeInfoBox();
690
691         return false;
692 }
693
694 function userEditCancel() {
695
696         if (!xmlhttp_ready(xmlhttp)) {
697                 printLockingError();
698                 return
699         }
700
701         selectPrefRows('user', false); // cleanup feed selection
702         closeInfoBox();
703
704         return false;
705 }
706
707 function filterEditCancel() {
708
709         if (!xmlhttp_ready(xmlhttp)) {
710                 printLockingError();
711                 return
712         }
713
714         document.getElementById("create_filter_btn").disabled = false;
715         
716         selectPrefRows('filter', false); // cleanup feed selection
717         closeInfoBox();
718
719         return false;
720 }
721
722 function labelEditSave() {
723
724         var label = active_label;
725
726         if (!xmlhttp_ready(xmlhttp)) {
727                 printLockingError();
728                 return
729         }
730
731 /*      if (!is_opera()) {
732
733                 var sql_exp = document.forms["label_edit_form"].sql_exp.value;
734                 var description = document.forms["label_edit_form"].description.value;
735         
736                 if (sql_exp.length == 0) {
737                         alert("SQL Expression cannot be blank.");
738                         return false;
739                 }
740         
741                 if (description.length == 0) {
742                         alert("Caption field cannot be blank.");
743                         return false;
744                 }
745         } */
746
747         closeInfoBox();
748
749         notify("Saving label...");
750
751         active_label = false;
752
753         query = Form.serialize("label_edit_form");
754
755         xmlhttp.open("GET", "backend.php?" + query, true);              
756         xmlhttp.onreadystatechange=labellist_callback;
757         xmlhttp.send(null);
758
759         return false;
760 }
761
762 function userEditSave() {
763
764         if (!xmlhttp_ready(xmlhttp)) {
765                 printLockingError();
766                 return
767         }
768
769         var login = document.forms["user_edit_form"].login.value;
770
771         if (login.length == 0) {
772                 alert("Login field cannot be blank.");
773                 return;
774         }
775         
776         notify("Saving user...");
777
778         closeInfoBox();
779
780         var query = Form.serialize("user_edit_form");
781         
782         xmlhttp.open("GET", "backend.php?" + query, true);                      
783         xmlhttp.onreadystatechange=userlist_callback;
784         xmlhttp.send(null);
785
786         return false;
787 }
788
789
790 function filterEditSave() {
791
792         if (!xmlhttp_ready(xmlhttp)) {
793                 printLockingError();
794                 return
795         }
796
797 /*      if (!is_opera()) {
798                 var reg_exp = document.forms["filter_edit_form"].reg_exp.value;
799         
800                 if (reg_exp.length == 0) {
801                         alert("Filter expression field cannot be blank.");
802                         return;
803                 }
804         } */
805
806         notify("Saving filter...");
807
808         var query = Form.serialize("filter_edit_form");
809
810         closeInfoBox();
811
812         document.getElementById("create_filter_btn").disabled = false;
813
814         xmlhttp.open("GET", "backend.php?" + query, true);
815         xmlhttp.onreadystatechange=filterlist_callback;
816         xmlhttp.send(null);
817
818         return false;
819 }
820
821 function editSelectedLabel() {
822         var rows = getSelectedLabels();
823
824         if (rows.length == 0) {
825                 alert("No labels are selected.");
826                 return;
827         }
828
829         if (rows.length > 1) {
830                 alert("Please select only one label.");
831                 return;
832         }
833
834         notify("");
835
836         editLabel(rows[0]);
837
838 }
839
840 function editSelectedUser() {
841         var rows = getSelectedUsers();
842
843         if (rows.length == 0) {
844                 alert("No users are selected.");
845                 return;
846         }
847
848         if (rows.length > 1) {
849                 alert("Please select only one user.");
850                 return;
851         }
852
853         notify("");
854
855         editUser(rows[0]);
856 }
857
858 function resetSelectedUserPass() {
859         var rows = getSelectedUsers();
860
861         if (rows.length == 0) {
862                 alert("No users are selected.");
863                 return;
864         }
865
866         if (rows.length > 1) {
867                 alert("Please select only one user.");
868                 return;
869         }
870
871         var ok = confirm("Reset password of selected user?");
872
873         if (ok) {
874                 notify("Resetting password for selected user...");
875         
876                 var id = rows[0];
877         
878                 xmlhttp.open("GET", "backend.php?op=pref-users&subop=resetPass&id=" +
879                         param_escape(id), true);
880                 xmlhttp.onreadystatechange=userlist_callback;
881                 xmlhttp.send(null);
882         }
883 }
884
885 function selectedUserDetails() {
886
887         if (!xmlhttp_ready(xmlhttp)) {
888                 printLockingError();
889                 return
890         }
891
892         var rows = getSelectedUsers();
893
894         if (rows.length == 0) {
895                 alert("No users are selected.");
896                 return;
897         }
898
899         if (rows.length > 1) {
900                 alert("Please select only one user.");
901                 return;
902         }
903
904         var id = rows[0];
905
906         notify("");
907
908         xmlhttp.open("GET", "backend.php?op=user-details&id=" + id, true);
909         xmlhttp.onreadystatechange=infobox_callback;
910         xmlhttp.send(null);
911
912 }
913
914 function selectedFeedDetails() {
915
916         if (!xmlhttp_ready(xmlhttp)) {
917                 printLockingError();
918                 return
919         }
920
921         var rows = getSelectedFeeds();
922
923         if (rows.length == 0) {
924                 alert("No feeds are selected.");
925                 return;
926         }
927
928         if (rows.length > 1) {
929                 notify("Please select only one feed.");
930                 return;
931         }
932
933 //      var id = rows[0];
934
935         notify("");
936
937         xmlhttp.open("GET", "backend.php?op=feed-details&id=" + 
938                 param_escape(rows.toString()), true);
939         xmlhttp.onreadystatechange=infobox_callback;
940         xmlhttp.send(null);
941
942 }
943
944 function editSelectedFilter() {
945         var rows = getSelectedFilters();
946
947         if (rows.length == 0) {
948                 alert("No filters are selected.");
949                 return;
950         }
951
952         if (rows.length > 1) {
953                 alert("Please select only one filter.");
954                 return;
955         }
956
957         notify("");
958
959         editFilter(rows[0]);
960
961 }
962
963
964 function editSelectedFeed() {
965         var rows = getSelectedFeeds();
966
967         if (rows.length == 0) {
968                 notify("No feeds are selected.");
969                 return;
970         }
971
972         if (rows.length > 1) {
973                 notify("Please select one feed.");
974                 return;
975         }
976
977         notify("");
978
979         editFeed(rows[0]);
980
981 }
982
983 function editSelectedFeedCat() {
984         var rows = getSelectedFeedCats();
985
986         if (rows.length == 0) {
987                 alert("No categories are selected.");
988                 return;
989         }
990
991         if (rows.length > 1) {
992                 alert("Please select only one category.");
993                 return;
994         }
995
996         notify("");
997
998         editFeedCat(rows[0]);
999
1000 }
1001
1002 function piggie_callback() {
1003         var piggie = document.getElementById("piggie");
1004
1005         piggie.style.top = piggie_top;
1006         piggie.style.backgroundColor = "white";
1007         piggie.style.borderWidth = "1px";
1008
1009         if (piggie_fwd && piggie_top < 0) {
1010                 setTimeout("piggie_callback()", 50);
1011                 piggie_top = piggie_top + 10;
1012         } else if (piggie_fwd && piggie_top >= 0) {
1013                 piggie_fwd = false;
1014                 setTimeout("piggie_callback()", 50);
1015         } else if (!piggie_fwd && piggie_top > -400) {
1016                 setTimeout("piggie_callback()", 50);
1017                 piggie_top = piggie_top - 10;
1018         } else if (!piggie_fwd && piggie_top <= -400) {
1019                 piggie.style.display = "none";
1020                 piggie_fwd = true;
1021         }
1022 }
1023
1024 var piggie_opacity = 0;
1025
1026 function piggie2_callback() {
1027         var piggie = document.getElementById("piggie");
1028         piggie.style.top = 0;
1029         piggie.style.opacity = piggie_opacity;
1030         piggie.style.backgroundColor = "transparent";
1031         piggie.style.borderWidth = "0px";
1032
1033         if (piggie_fwd && piggie_opacity < 1) {
1034                 setTimeout("piggie2_callback()", 50);
1035                 piggie_opacity = piggie_opacity + 0.03;
1036         } else if (piggie_fwd && piggie_opacity >= 1) {
1037                 piggie_fwd = false;
1038                 setTimeout("piggie2_callback()", 50);
1039         } else if (!piggie_fwd && piggie_opacity > 0) {
1040                 setTimeout("piggie2_callback()", 50);
1041                 piggie_opacity = piggie_opacity - 0.03;
1042         } else if (!piggie_fwd && piggie_opacity <= 0) {
1043                 piggie.style.display = "none";
1044                 piggie_fwd = true;
1045         }
1046 }
1047
1048 function localPiggieFunction(enable) {
1049         if (enable) {
1050                 debug("I LOVEDED IT!");
1051                 var piggie = document.getElementById("piggie");
1052                 piggie.style.display = "block";
1053
1054                 if (navigator.userAgent.match("Gecko") && Math.random(1) > 0.5) {       
1055                         piggie2_callback();
1056                 } else {
1057                         piggie_callback();
1058                 }
1059         }
1060 }
1061
1062 function validateOpmlImport() {
1063         
1064         var opml_file = document.getElementById("opml_file");
1065
1066         if (opml_file.value.length == 0) {
1067                 alert("No OPML file to upload.");
1068                 return false;
1069         } else {
1070                 return true;
1071         }
1072 }
1073
1074 function updateFilterList(sort_key) {
1075
1076         if (!xmlhttp_ready(xmlhttp)) {
1077                 printLockingError();
1078                 return
1079         }
1080
1081 //      document.getElementById("prefContent").innerHTML = "Loading filters, please wait...";
1082
1083 //      p_notify("Loading, please wait...");
1084
1085         xmlhttp.open("GET", "backend.php?op=pref-filters&sort=" + 
1086                 param_escape(sort_key), true);
1087         xmlhttp.onreadystatechange=filterlist_callback;
1088         xmlhttp.send(null);
1089
1090 }
1091
1092 function updateLabelList(sort_key) {
1093
1094         if (!xmlhttp_ready(xmlhttp)) {
1095                 printLockingError();
1096                 return
1097         }
1098
1099 //      p_notify("Loading, please wait...");
1100
1101 //      document.getElementById("prefContent").innerHTML = "Loading labels, please wait...";
1102
1103         xmlhttp.open("GET", "backend.php?op=pref-labels&sort=" + 
1104                 param_escape(sort_key), true);
1105         xmlhttp.onreadystatechange=labellist_callback;
1106         xmlhttp.send(null);
1107 }
1108
1109 function updatePrefsList() {
1110
1111         if (!xmlhttp_ready(xmlhttp)) {
1112                 printLockingError();
1113                 return
1114         }
1115
1116 //      p_notify("Loading, please wait...");
1117
1118         xmlhttp.open("GET", "backend.php?op=pref-prefs", true);
1119         xmlhttp.onreadystatechange=prefslist_callback;
1120         xmlhttp.send(null);
1121
1122 }
1123
1124 function selectTab(id, noupdate, subop) {
1125
1126 //      alert(id);
1127
1128         if (!id) id = active_tab;
1129
1130         try {
1131
1132                 if (!xmlhttp_ready(xmlhttp)) {
1133                         printLockingError();
1134                         return
1135                 }
1136
1137                 try {
1138                         var c = document.getElementById('prefContent'); 
1139                         c.scrollTop = 0;
1140                 } catch (e) { };
1141
1142                 if (!noupdate) {
1143
1144                         debug("selectTab: " + id + "(NU: " + noupdate + ")");
1145         
1146 //                      notify("Loading, please wait...", true);
1147         
1148                         // close active infobox if needed
1149                         closeInfoBox();
1150         
1151                         // clean up all current selections, just in case
1152                         active_feed_cat = false;
1153                         active_label = false;
1154         
1155                         if (id == "feedConfig") {
1156                                 updateFeedList();
1157                         } else if (id == "filterConfig") {
1158                                 updateFilterList();
1159                         } else if (id == "labelConfig") {
1160                                 updateLabelList();
1161                         } else if (id == "genConfig") {
1162                                 updatePrefsList();
1163                         } else if (id == "userConfig") {
1164                                 updateUsersList();
1165                         } else if (id == "feedBrowser") {
1166                                 updateBigFeedBrowser();
1167                         }
1168                 }
1169         
1170                 var tab = document.getElementById(active_tab + "Tab");
1171         
1172                 if (tab) {
1173                         if (tab.className.match("Selected")) {
1174                                 tab.className = "prefsTab";
1175                         }
1176                 }
1177         
1178                 tab = document.getElementById(id + "Tab");
1179         
1180                 if (tab) {
1181                         if (!tab.className.match("Selected")) {
1182                                 tab.className = tab.className + "Selected";
1183                         }
1184                 }
1185         
1186                 if (active_tab != id) {
1187                         storeInitParam("prefs_active_tab", id);
1188                 }
1189         
1190                 active_tab = id;
1191
1192         } catch (e) {
1193                 exception_error("selectTab", e);
1194         }
1195 }
1196
1197 function backend_sanity_check_callback() {
1198
1199         if (xmlhttp.readyState == 4) {
1200
1201                 try {
1202                 
1203                         if (!xmlhttp.responseXML) {
1204                                 fatalError(3, "[D001, Received reply is not XML]: " + xmlhttp.responseText);
1205                                 return;
1206                         }
1207         
1208                         var reply = xmlhttp.responseXML.firstChild.firstChild;
1209         
1210                         if (!reply) {
1211                                 fatalError(3, "[D002, Invalid RPC reply]: " + xmlhttp.responseText);
1212                                 return;
1213                         }
1214         
1215                         var error_code = reply.getAttribute("error-code");
1216                 
1217                         if (error_code && error_code != 0) {
1218                                 return fatalError(error_code, reply.getAttribute("error-msg"));
1219                         }
1220         
1221                         debug("sanity check ok");
1222
1223                         var params = reply.nextSibling;
1224
1225                         if (params) {
1226                                 debug('reading init-params...');
1227                                 var param = params.firstChild;
1228
1229                                 while (param) {
1230                                         var k = param.getAttribute("key");
1231                                         var v = param.getAttribute("value");
1232                                         debug(k + " => " + v);
1233                                         init_params[k] = v;                                     
1234                                         param = param.nextSibling;
1235                                 }
1236                         }
1237
1238                         init_second_stage();
1239
1240                 } catch (e) {
1241                         exception_error("backend_sanity_check_callback", e);
1242                 }
1243         } 
1244 }
1245
1246 function init_second_stage() {
1247
1248         try {
1249                 active_tab = getInitParam("prefs_active_tab");
1250                 if (!active_tab) active_tab = "genConfig";
1251
1252                 document.onkeydown = pref_hotkey_handler;
1253
1254                 var tab = getURLParam('tab');
1255                 
1256                 caller_subop = getURLParam('subop');
1257
1258                 if (tab) {
1259                         active_tab = tab;
1260                 }
1261
1262                 if (navigator.userAgent.match("Opera")) {       
1263                         setTimeout("selectTab()", 500);
1264                 } else {
1265                         selectTab(active_tab);
1266                 }
1267                 notify("");
1268         } catch (e) {
1269                 exception_error("init_second_stage", e);
1270         }
1271 }
1272
1273 function init() {
1274
1275         try {
1276         
1277                 if (arguments.callee.done) return;
1278                 arguments.callee.done = true;           
1279
1280                 if (getURLParam('debug')) {
1281                         document.getElementById('debug_output').style.display = 'block';
1282                         debug('debug mode activated');
1283                 }
1284
1285                 // IE kludge
1286                 if (!xmlhttp) {
1287                         document.getElementById("prefContent").innerHTML = 
1288                                 "<b>Fatal error:</b> This program needs XmlHttpRequest " + 
1289                                 "to function properly. Your browser doesn't seem to support it.";
1290                         return;
1291                 }
1292
1293                 xmlhttp.open("GET", "backend.php?op=rpc&subop=sanityCheck", true);
1294                 xmlhttp.onreadystatechange=backend_sanity_check_callback;
1295                 xmlhttp.send(null);
1296
1297         } catch (e) {
1298                 exception_error("init", e);
1299         }
1300 }
1301
1302 function categorizeSelectedFeeds() {
1303
1304         if (!xmlhttp_ready(xmlhttp)) {
1305                 printLockingError();
1306                 return
1307         }
1308
1309         var sel_rows = getSelectedFeeds();
1310
1311         var cat_sel = document.getElementById("sfeed_set_fcat");
1312         var cat_id = cat_sel[cat_sel.selectedIndex].value;
1313
1314         if (sel_rows.length > 0) {
1315
1316                 notify("Changing category of selected feeds...");
1317
1318                 xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=categorize&ids="+
1319                         param_escape(sel_rows.toString()) + "&cat_id=" + param_escape(cat_id), true);
1320                 xmlhttp.onreadystatechange=feedlist_callback;
1321                 xmlhttp.send(null);
1322
1323         } else {
1324
1325                 alert("No feeds are selected.");
1326
1327         }
1328
1329 }
1330
1331 function validatePrefsReset() {
1332         return confirm("Reset to defaults?");
1333 }
1334
1335 function browseFeeds(limit) {
1336
1337         xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=browse", true);
1338         xmlhttp.onreadystatechange=infobox_callback;
1339         xmlhttp.send(null);
1340
1341 }
1342
1343 function feedBrowserSubscribe() {
1344         try {
1345
1346                 var selected = getSelectedFeedsFromBrowser();
1347
1348                 if (selected.length > 0) {
1349                         closeInfoBox();
1350                         xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=massSubscribe&ids="+
1351                                 param_escape(selected.toString()), true);
1352                         xmlhttp.onreadystatechange=feedlist_callback;
1353                         xmlhttp.send(null);
1354                 } else {
1355                         alert("No feeds are selected.");
1356                 }
1357
1358         } catch (e) {
1359                 exception_error("feedBrowserSubscribe", e);
1360         }
1361 }
1362
1363 function updateBigFeedBrowser(limit) {
1364
1365         if (!xmlhttp_ready(xmlhttp)) {
1366                 printLockingError();
1367                 return
1368         }
1369
1370 //      p_notify("Loading, please wait...");
1371
1372         var query = "backend.php?op=pref-feed-browser";
1373
1374         var limit_sel = document.getElementById("feedBrowserLimit");
1375
1376         if (limit_sel) {
1377                 var limit = limit_sel[limit_sel.selectedIndex].value;
1378                 query = query + "&limit=" + param_escape(limit);
1379         }
1380
1381         xmlhttp.open("GET", query, true);
1382         xmlhttp.onreadystatechange=feed_browser_callback;
1383         xmlhttp.send(null);
1384 }
1385
1386 function browserToggleExpand(id) {
1387         try {
1388 /*              if (feed_to_expand && feed_to_expand != id) {
1389                         var d = document.getElementById("BRDET-" + feed_to_expand);
1390                         d.style.display = "none";
1391                 } */
1392
1393                 if (!xmlhttp_ready(xmlhttp)) {
1394                         printLockingError();
1395                         return
1396                 }
1397
1398                 var d = document.getElementById("BRDET-" + id);
1399
1400                 if (d.style.display == "block") {               
1401                         d.style.display = "none";
1402                         
1403                 } else {
1404         
1405                         feed_to_expand = id;
1406
1407                         d.style.display = "block";
1408                         d.innerHTML = "Loading, please wait...";
1409
1410                         xmlhttp.open("GET", "backend.php?op=pref-feed-browser&subop=details&id="
1411                                 + param_escape(id), true);
1412                         xmlhttp.onreadystatechange=expand_feed_callback;
1413                         xmlhttp.send(null);
1414                 }
1415
1416         } catch (e) {
1417                 exception_error("browserExpand", e);
1418         }
1419 }
1420
1421 function validateNewPassword(form) {
1422         if (form.OLD_PASSWORD.value == "") {
1423                 alert("Old password cannot be blank");
1424                 return false;
1425         }
1426         if (form.NEW_PASSWORD.value == "") {
1427                 alert("New password cannot be blank");
1428                 return false;
1429         }
1430         return true;
1431 }
1432
1433 function selectPrefRows(kind, select) {
1434
1435         if (kind) {
1436                 var opbarid = false;    
1437                 var nchk = false;
1438                 var nrow = false;
1439                 var lname = false;
1440
1441                 if (kind == "feed") {
1442                         opbarid = "feedOpToolbar";
1443                         nrow = "FEEDR-";
1444                         nchk = "FRCHK-";                        
1445                         lname = "prefFeedList";
1446                 } else if (kind == "fcat") {
1447                         opbarid = "catOpToolbar";
1448                         nrow = "FCATR-";
1449                         nchk = "FCCHK-";
1450                         lname = "prefFeedCatList";
1451                 } else if (kind == "filter") {
1452                         opbarid = "filterOpToolbar";
1453                         nrow = "FILRR-";
1454                         nchk = "FICHK-";
1455                         lname = "prefFilterList";
1456                 } else if (kind == "label") {
1457                         opbarid = "labelOpToolbar";
1458                         nrow = "LILRR-";
1459                         nchk = "LICHK-";
1460                         lname = "prefLabelList";
1461                 } else if (kind == "user") {
1462                         opbarid = "userOpToolbar";
1463                         nrow = "UMRR-";
1464                         nchk = "UMCHK-";
1465                         lname = "prefUserList";
1466                 }
1467
1468                 if (opbarid) {
1469                         selectTableRowsByIdPrefix(lname, nrow, nchk, select);
1470                         disableContainerChildren(opbarid, !select);
1471                 }
1472
1473         } 
1474 }
1475
1476
1477 function toggleSelectPrefRow(sender, kind) {
1478
1479         toggleSelectRow(sender);
1480
1481         if (kind) {
1482                 var opbarid = false;    
1483                 var nsel = -1;
1484                 
1485                 if (kind == "feed") {
1486                         opbarid = "feedOpToolbar";
1487                         nsel = getSelectedFeeds();
1488                 } else if (kind == "fcat") {
1489                         opbarid = "catOpToolbar";
1490                         nsel = getSelectedFeedCats();
1491                 } else if (kind == "filter") {
1492                         opbarid = "filterOpToolbar";
1493                         nsel = getSelectedFilters();
1494                 } else if (kind == "label") {
1495                         opbarid = "labelOpToolbar";
1496                         nsel = getSelectedLabels();
1497                 } else if (kind == "user") {
1498                         opbarid = "userOpToolbar";
1499                         nsel = getSelectedUsers();
1500                 }
1501
1502                 if (opbarid && nsel != -1) {
1503                         disableContainerChildren(opbarid, nsel == false);
1504                 }
1505
1506         } 
1507 }
1508
1509 function toggleSelectFBListRow(sender) {
1510         toggleSelectListRow(sender);
1511         disableContainerChildren("fbrOpToolbar", getSelectedFeedsFromBrowser() == 0);
1512 }
1513
1514 var seq = "";
1515
1516 function pref_hotkey_handler(e) {
1517         try {
1518
1519                 var keycode;
1520         
1521                 if (!hotkeys_enabled) return;
1522         
1523                 if (window.event) {
1524                         keycode = window.event.keyCode;
1525                 } else if (e) {
1526                         keycode = e.which;
1527                 }
1528         
1529                 if (keycode == 13 || keycode == 27) {
1530                         seq = "";
1531                 } else {
1532                         seq = seq + "" + keycode;
1533                 }
1534
1535
1536         if (document.getElementById("piggie")) {
1537         
1538                 if (seq.match("807371717369")) {
1539                         seq = "";
1540                         localPiggieFunction(true);
1541                 } else {
1542                         localPiggieFunction(false);
1543                 }
1544         }
1545
1546         } catch (e) {
1547                 exception_error("pref_hotkey_handler", e);
1548         }
1549 }
1550
1551 function userSwitch() {
1552         var chooser = document.getElementById("userSwitch");
1553         var user = chooser[chooser.selectedIndex].value;
1554         window.location = "prefs.php?swu=" + user;
1555 }
1556
1557 function editFeedCats() {
1558         if (!xmlhttp_ready(xmlhttp)) {
1559                 printLockingError();
1560                 return
1561         }
1562
1563         xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=editCats", true);
1564         xmlhttp.onreadystatechange=infobox_callback;
1565         xmlhttp.send(null);
1566 }
1567
1568 function showFeedsWithErrors() {
1569         displayDlg('feedUpdateErrors');
1570 }
1571
1572