]> git.wh0rd.org Git - tt-rss.git/blob - js/prefs.js
mail plugin: only mail unique articles
[tt-rss.git] / js / prefs.js
1 var init_params = new Array();
2
3 var hotkey_prefix = false;
4 var hotkey_prefix_pressed = false;
5
6 var seq = "";
7
8 function notify_callback2(transport, sticky) {
9         notify_info(transport.responseText, sticky);
10 }
11
12 function updateFeedList(sort_key) {
13
14         var user_search = $("feed_search");
15         var search = "";
16         if (user_search) { search = user_search.value; }
17
18         new Ajax.Request("backend.php", {
19                 parameters: "?op=pref-feeds&search=" + param_escape(search),
20                 onComplete: function(transport) {
21                         dijit.byId('feedConfigTab').attr('content', transport.responseText);
22                         selectTab("feedConfig", true);
23                         notify("");
24                 } });
25 }
26
27
28 function updateUsersList(sort_key) {
29         try {
30                 var user_search = $("user_search");
31                 var search = "";
32                 if (user_search) { search = user_search.value; }
33
34                 var query = "?op=pref-users&sort="
35                         + param_escape(sort_key) +
36                         "&search=" + param_escape(search);
37
38                 new Ajax.Request("backend.php", {
39                         parameters: query,
40                         onComplete: function(transport) {
41                                 dijit.byId('userConfigTab').attr('content', transport.responseText);
42                                 selectTab("userConfig", true)
43                                 notify("");
44                         } });
45
46         } catch (e) {
47                 exception_error("updateUsersList", e);
48         }
49 }
50
51 function addUser() {
52
53         try {
54
55                 var login = prompt(__("Please enter login:"), "");
56
57                 if (login == null) {
58                         return false;
59                 }
60
61                 if (login == "") {
62                         alert(__("Can't create user: no login specified."));
63                         return false;
64                 }
65
66                 notify_progress("Adding user...");
67
68                 var query = "?op=pref-users&method=add&login=" +
69                         param_escape(login);
70
71                 new Ajax.Request("backend.php", {
72                         parameters: query,
73                         onComplete: function(transport) {
74                                 notify_callback2(transport);
75                                 updateUsersList();
76                         } });
77
78         } catch (e) {
79                 exception_error("addUser", e);
80         }
81 }
82
83 function editUser(id, event) {
84
85         try {
86                 var query = "backend.php?op=pref-users&method=edit&id=" +
87                         param_escape(id);
88
89                 if (dijit.byId("userEditDlg"))
90                         dijit.byId("userEditDlg").destroyRecursive();
91
92                 dialog = new dijit.Dialog({
93                         id: "userEditDlg",
94                         title: __("User Editor"),
95                         style: "width: 600px",
96                         execute: function() {
97                                 if (this.validate()) {
98
99                                         notify_progress("Saving data...", true);
100
101                                         var query = dojo.formToQuery("user_edit_form");
102
103                                         new Ajax.Request("backend.php", {
104                                                 parameters: query,
105                                                 onComplete: function(transport) {
106                                                         dialog.hide();
107                                                         updateUsersList();
108                                                 }});
109                                 }
110                         },
111                         href: query});
112
113                 dialog.show();
114
115         } catch (e) {
116                 exception_error("editUser", e);
117         }
118
119 }
120
121 function editFilter(id) {
122         try {
123
124                 var query = "backend.php?op=pref-filters&method=edit&id=" + param_escape(id);
125
126                 if (dijit.byId("feedEditDlg"))
127                         dijit.byId("feedEditDlg").destroyRecursive();
128
129                 if (dijit.byId("filterEditDlg"))
130                         dijit.byId("filterEditDlg").destroyRecursive();
131
132                 dialog = new dijit.Dialog({
133                         id: "filterEditDlg",
134                         title: __("Edit Filter"),
135                         style: "width: 600px",
136                         test: function() {
137                                 var query = "backend.php?" + dojo.formToQuery("filter_edit_form") + "&savemode=test";
138
139                                 if (dijit.byId("filterTestDlg"))
140                                         dijit.byId("filterTestDlg").destroyRecursive();
141
142                                 var test_dlg = new dijit.Dialog({
143                                         id: "filterTestDlg",
144                                         title: "Test Filter",
145                                         style: "width: 600px",
146                                         href: query});
147
148                                 test_dlg.show();
149                         },
150                         selectRules: function(select) {
151                                 $$("#filterDlg_Matches input[type=checkbox]").each(function(e) {
152                                         e.checked = select;
153                                         if (select)
154                                                 e.parentNode.addClassName("Selected");
155                                         else
156                                                 e.parentNode.removeClassName("Selected");
157                                 });
158                         },
159                         selectActions: function(select) {
160                                 $$("#filterDlg_Actions input[type=checkbox]").each(function(e) {
161                                         e.checked = select;
162
163                                         if (select)
164                                                 e.parentNode.addClassName("Selected");
165                                         else
166                                                 e.parentNode.removeClassName("Selected");
167
168                                 });
169                         },
170                         editRule: function(e) {
171                                 var li = e.parentNode;
172                                 var rule = li.getElementsByTagName("INPUT")[1].value;
173                                 addFilterRule(li, rule);
174                         },
175                         editAction: function(e) {
176                                 var li = e.parentNode;
177                                 var action = li.getElementsByTagName("INPUT")[1].value;
178                                 addFilterAction(li, action);
179                         },
180                         removeFilter: function() {
181                                 var msg = __("Remove filter?");
182
183                                 if (confirm(msg)) {
184                                         this.hide();
185
186                                         notify_progress("Removing filter...");
187
188                                         var id = this.attr('value').id;
189
190                                         var query = "?op=pref-filters&method=remove&ids="+
191                                                 param_escape(id);
192
193                                         new Ajax.Request("backend.php", {
194                                                 parameters: query,
195                                                 onComplete: function(transport) {
196                                                         updateFilterList();
197                                                 } });
198                                 }
199                         },
200                         addAction: function() { addFilterAction(); },
201                         addRule: function() { addFilterRule(); },
202                         deleteAction: function() {
203                                 $$("#filterDlg_Actions li.[class*=Selected]").each(function(e) { e.parentNode.removeChild(e) });
204                         },
205                         deleteRule: function() {
206                                 $$("#filterDlg_Matches li.[class*=Selected]").each(function(e) { e.parentNode.removeChild(e) });
207                         },
208                         execute: function() {
209                                 if (this.validate()) {
210
211                                         notify_progress("Saving data...", true);
212
213                                         var query = dojo.formToQuery("filter_edit_form");
214
215                                         console.log(query);
216
217                                         new Ajax.Request("backend.php", {
218                                                 parameters: query,
219                                                 onComplete: function(transport) {
220                                                         dialog.hide();
221                                                         updateFilterList();
222                                                 }});
223                                 }
224                         },
225                         href: query});
226
227                 dialog.show();
228
229
230         } catch (e) {
231                 exception_error("editFilter", e);
232         }
233 }
234
235 function getSelectedLabels() {
236         var tree = dijit.byId("labelTree");
237         var items = tree.model.getCheckedItems();
238         var rv = [];
239
240         items.each(function(item) {
241                 rv.push(tree.model.store.getValue(item, 'bare_id'));
242         });
243
244         return rv;
245 }
246
247 function getSelectedUsers() {
248         return getSelectedTableRowIds("prefUserList");
249 }
250
251 function getSelectedFeeds() {
252         var tree = dijit.byId("feedTree");
253         var items = tree.model.getCheckedItems();
254         var rv = [];
255
256         items.each(function(item) {
257                 if (item.id[0].match("FEED:"))
258                         rv.push(tree.model.store.getValue(item, 'bare_id'));
259         });
260
261         return rv;
262 }
263
264 function getSelectedCategories() {
265         var tree = dijit.byId("feedTree");
266         var items = tree.model.getCheckedItems();
267         var rv = [];
268
269         items.each(function(item) {
270                 if (item.id[0].match("CAT:"))
271                         rv.push(tree.model.store.getValue(item, 'bare_id'));
272         });
273
274         return rv;
275 }
276
277 function getSelectedFilters() {
278         var tree = dijit.byId("filterTree");
279         var items = tree.model.getCheckedItems();
280         var rv = [];
281
282         items.each(function(item) {
283                 rv.push(tree.model.store.getValue(item, 'bare_id'));
284         });
285
286         return rv;
287
288 }
289
290 function removeSelectedLabels() {
291
292         var sel_rows = getSelectedLabels();
293
294         if (sel_rows.length > 0) {
295
296                 var ok = confirm(__("Remove selected labels?"));
297
298                 if (ok) {
299                         notify_progress("Removing selected labels...");
300
301                         var query = "?op=pref-labels&method=remove&ids="+
302                                 param_escape(sel_rows.toString());
303
304                         new Ajax.Request("backend.php", {
305                                 parameters: query,
306                                 onComplete: function(transport) {
307                                                 updateLabelList();
308                                         } });
309
310                 }
311         } else {
312                 alert(__("No labels are selected."));
313         }
314
315         return false;
316 }
317
318 function removeSelectedUsers() {
319
320         try {
321
322                 var sel_rows = getSelectedUsers();
323
324                 if (sel_rows.length > 0) {
325
326                         var ok = confirm(__("Remove selected users? Neither default admin nor your account will be removed."));
327
328                         if (ok) {
329                                 notify_progress("Removing selected users...");
330
331                                 var query = "?op=pref-users&method=remove&ids="+
332                                         param_escape(sel_rows.toString());
333
334                                 new Ajax.Request("backend.php", {
335                                         parameters: query,
336                                         onComplete: function(transport) {
337                                                 updateUsersList();
338                                         } });
339
340                         }
341
342                 } else {
343                         alert(__("No users are selected."));
344                 }
345
346         } catch (e) {
347                 exception_error("removeSelectedUsers", e);
348         }
349
350         return false;
351 }
352
353 function removeSelectedFilters() {
354
355         try {
356
357                 var sel_rows = getSelectedFilters();
358
359                 if (sel_rows.length > 0) {
360
361                         var ok = confirm(__("Remove selected filters?"));
362
363                         if (ok) {
364                                 notify_progress("Removing selected filters...");
365
366                                 var query = "?op=pref-filters&method=remove&ids="+
367                                         param_escape(sel_rows.toString());
368
369                                 new Ajax.Request("backend.php", {
370                                                 parameters: query,
371                                                 onComplete: function(transport) {
372                                                         updateFilterList();
373                                                 } });
374                         }
375                 } else {
376                         alert(__("No filters are selected."));
377                 }
378
379         } catch (e) {
380                 exception_error("removeSelectedFilters", e);
381         }
382
383         return false;
384 }
385
386
387 function removeSelectedFeeds() {
388
389         try {
390
391                 var sel_rows = getSelectedFeeds();
392
393                 if (sel_rows.length > 0) {
394
395                         var ok = confirm(__("Unsubscribe from selected feeds?"));
396
397                         if (ok) {
398
399                                 notify_progress("Unsubscribing from selected feeds...", true);
400
401                                 var query = "?op=pref-feeds&method=remove&ids="+
402                                         param_escape(sel_rows.toString());
403
404                                 console.log(query);
405
406                                 new Ajax.Request("backend.php", {
407                                         parameters: query,
408                                         onComplete: function(transport) {
409                                                 updateFeedList();
410                                                 } });
411                         }
412
413                 } else {
414                         alert(__("No feeds are selected."));
415                 }
416
417         } catch (e) {
418                 exception_error("removeSelectedFeeds", e);
419         }
420
421         return false;
422 }
423
424 function clearSelectedFeeds() {
425
426         var sel_rows = getSelectedFeeds();
427
428         if (sel_rows.length > 1) {
429                 alert(__("Please select only one feed."));
430                 return;
431         }
432
433         if (sel_rows.length > 0) {
434
435                 var ok = confirm(__("Erase all non-starred articles in selected feed?"));
436
437                 if (ok) {
438                         notify_progress("Clearing selected feed...");
439                         clearFeedArticles(sel_rows[0]);
440                 }
441
442         } else {
443
444                 alert(__("No feeds are selected."));
445
446         }
447
448         return false;
449 }
450
451 function purgeSelectedFeeds() {
452
453         var sel_rows = getSelectedFeeds();
454
455         if (sel_rows.length > 0) {
456
457                 var pr = prompt(__("How many days of articles to keep (0 - use default)?"), "0");
458
459                 if (pr != undefined) {
460                         notify_progress("Purging selected feed...");
461
462                         var query = "?op=rpc&method=purge&ids="+
463                                 param_escape(sel_rows.toString()) + "&days=" + pr;
464
465                         console.log(query);
466
467                         new Ajax.Request("prefs.php",   {
468                                 parameters: query,
469                                 onComplete: function(transport) {
470                                         notify('');
471                                 } });
472                 }
473
474         } else {
475
476                 alert(__("No feeds are selected."));
477
478         }
479
480         return false;
481 }
482
483 function editSelectedUser() {
484         var rows = getSelectedUsers();
485
486         if (rows.length == 0) {
487                 alert(__("No users are selected."));
488                 return;
489         }
490
491         if (rows.length > 1) {
492                 alert(__("Please select only one user."));
493                 return;
494         }
495
496         notify("");
497
498         editUser(rows[0]);
499 }
500
501 function resetSelectedUserPass() {
502
503         try {
504
505                 var rows = getSelectedUsers();
506
507                 if (rows.length == 0) {
508                         alert(__("No users are selected."));
509                         return;
510                 }
511
512                 if (rows.length > 1) {
513                         alert(__("Please select only one user."));
514                         return;
515                 }
516
517                 var ok = confirm(__("Reset password of selected user?"));
518
519                 if (ok) {
520                         notify_progress("Resetting password for selected user...");
521
522                         var id = rows[0];
523
524                         var query = "?op=pref-users&method=resetPass&id=" +
525                                 param_escape(id);
526
527                         new Ajax.Request("backend.php", {
528                                 parameters: query,
529                                 onComplete: function(transport) {
530                                         notify_info(transport.responseText, true);
531                                 } });
532
533                 }
534
535         } catch (e) {
536                 exception_error("resetSelectedUserPass", e);
537         }
538 }
539
540 function selectedUserDetails() {
541
542         try {
543
544                 var rows = getSelectedUsers();
545
546                 if (rows.length == 0) {
547                         alert(__("No users are selected."));
548                         return;
549                 }
550
551                 if (rows.length > 1) {
552                         alert(__("Please select only one user."));
553                         return;
554                 }
555
556                 var id = rows[0];
557
558                 var query = "backend.php?op=pref-users&method=userdetails&id=" + id;
559
560                 if (dijit.byId("userDetailsDlg"))
561                         dijit.byId("userDetailsDlg").destroyRecursive();
562
563                 dialog = new dijit.Dialog({
564                         id: "userDetailsDlg",
565                         title: __("User details"),
566                         style: "width: 600px",
567                         execute: function() {
568                                 dialog.hide();
569                         },
570                         href: query});
571
572                 dialog.show();
573
574         } catch (e) {
575                 exception_error("selectedUserDetails", e);
576         }
577 }
578
579
580 function editSelectedFilter() {
581         var rows = getSelectedFilters();
582
583         if (rows.length == 0) {
584                 alert(__("No filters are selected."));
585                 return;
586         }
587
588         if (rows.length > 1) {
589                 alert(__("Please select only one filter."));
590                 return;
591         }
592
593         notify("");
594
595         editFilter(rows[0]);
596
597 }
598
599 function joinSelectedFilters() {
600         var rows = getSelectedFilters();
601
602         if (rows.length == 0) {
603                 alert(__("No filters are selected."));
604                 return;
605         }
606
607         var ok = confirm(__("Combine selected filters?"));
608
609         if (ok) {
610                 notify_progress("Joining filters...");
611
612                 var query = "?op=pref-filters&method=join&ids="+
613                         param_escape(rows.toString());
614
615                 console.log(query);
616
617                 new Ajax.Request("backend.php", {
618                         parameters: query,
619                         onComplete: function(transport) {
620                                         updateFilterList();
621                         } });
622         }
623 }
624
625 function editSelectedFeed() {
626         var rows = getSelectedFeeds();
627
628         if (rows.length == 0) {
629                 alert(__("No feeds are selected."));
630                 return;
631         }
632
633         if (rows.length > 1) {
634                 return editSelectedFeeds();
635         }
636
637         notify("");
638
639         editFeed(rows[0], {});
640
641 }
642
643 function editSelectedFeeds() {
644
645         try {
646                 var rows = getSelectedFeeds();
647
648                 if (rows.length == 0) {
649                         alert(__("No feeds are selected."));
650                         return;
651                 }
652
653                 notify_progress("Loading, please wait...");
654
655                 var query = "backend.php?op=pref-feeds&method=editfeeds&ids=" +
656                         param_escape(rows.toString());
657
658                 console.log(query);
659
660                 if (dijit.byId("feedEditDlg"))
661                         dijit.byId("feedEditDlg").destroyRecursive();
662
663                 new Ajax.Request("backend.php", {
664                         parameters: query,
665                         onComplete: function(transport) {
666
667                                 notify("");
668
669                                 var dialog = new dijit.Dialog({
670                                         id: "feedEditDlg",
671                                         title: __("Edit Multiple Feeds"),
672                                         style: "width: 600px",
673                                         getChildByName: function (name) {
674                                                 var rv = null;
675                                                 this.getChildren().each(
676                                                         function(child) {
677                                                                 if (child.name == name) {
678                                                                         rv = child;
679                                                                         return;
680                                                                 }
681                                                         });
682                                                 return rv;
683                                         },
684                                         toggleField: function (checkbox, elem, label) {
685                                                 this.getChildByName(elem).attr('disabled', !checkbox.checked);
686
687                                                 if ($(label))
688                                                         if (checkbox.checked)
689                                                                 $(label).removeClassName('insensitive');
690                                                         else
691                                                                 $(label).addClassName('insensitive');
692
693                                         },
694                                         execute: function() {
695                                                 if (this.validate() && confirm(__("Save changes to selected feeds?"))) {
696                                                         var query = dojo.objectToQuery(this.attr('value'));
697
698                                                         /* Form.serialize ignores unchecked checkboxes */
699
700                                                         if (!query.match("&private=") &&
701                                                                         this.getChildByName('private').attr('disabled') == false) {
702                                                                 query = query + "&private=false";
703                                                         }
704
705                                                         try {
706                                                                 if (!query.match("&cache_images=") &&
707                                                                                 this.getChildByName('cache_images').attr('disabled') == false) {
708                                                                         query = query + "&cache_images=false";
709                                                                 }
710                                                         } catch (e) { }
711
712                                                         try {
713                                                                 if (!query.match("&hide_images=") &&
714                                                                                 this.getChildByName('hide_images').attr('disabled') == false) {
715                                                                         query = query + "&hide_images=false";
716                                                                 }
717                                                         } catch (e) { }
718
719                                                         if (!query.match("&include_in_digest=") &&
720                                                                         this.getChildByName('include_in_digest').attr('disabled') == false) {
721                                                                 query = query + "&include_in_digest=false";
722                                                         }
723
724                                                         if (!query.match("&always_display_enclosures=") &&
725                                                                         this.getChildByName('always_display_enclosures').attr('disabled') == false) {
726                                                                 query = query + "&always_display_enclosures=false";
727                                                         }
728
729                                                         if (!query.match("&mark_unread_on_update=") &&
730                                                                         this.getChildByName('mark_unread_on_update').attr('disabled') == false) {
731                                                                 query = query + "&mark_unread_on_update=false";
732                                                         }
733
734                                                         console.log(query);
735
736                                                         notify_progress("Saving data...", true);
737
738                                                         new Ajax.Request("backend.php", {
739                                                                 parameters: query,
740                                                                 onComplete: function(transport) {
741                                                                         dialog.hide();
742                                                                         updateFeedList();
743                                                         }});
744                                                 }
745                                         },
746                                         content: transport.responseText});
747
748                                         dialog.show();
749
750                         } });
751
752         } catch (e) {
753                 exception_error("editSelectedFeeds", e);
754         }
755 }
756
757 function opmlImportComplete(iframe) {
758         try {
759                 if (!iframe.contentDocument.body.innerHTML) return false;
760
761                 Element.show(iframe);
762
763                 notify('');
764
765                 if (dijit.byId('opmlImportDlg'))
766                         dijit.byId('opmlImportDlg').destroyRecursive();
767
768                 var content = iframe.contentDocument.body.innerHTML;
769
770                 dialog = new dijit.Dialog({
771                         id: "opmlImportDlg",
772                         title: __("OPML Import"),
773                         style: "width: 600px",
774                         onCancel: function() {
775                                 updateFeedList();
776                                 updateFilterList();
777                                 updateLabelList();
778                         },
779                         execute: function() {
780                                 updateFeedList();
781                                 updateFilterList();
782                                 updateLabelList();
783                                 this.hide();
784                         },
785                         content: content});
786
787                 dialog.show();
788
789         } catch (e) {
790                 exception_error("opmlImportComplete", e);
791         }
792 }
793
794 function opmlImport() {
795
796         var opml_file = $("opml_file");
797
798         if (opml_file.value.length == 0) {
799                 alert(__("Please choose an OPML file first."));
800                 return false;
801         } else {
802                 notify_progress("Importing, please wait...", true);
803
804                 Element.show("upload_iframe");
805
806                 return true;
807         }
808 }
809
810
811 function updateFilterList() {
812         var user_search = $("filter_search");
813         var search = "";
814         if (user_search) { search = user_search.value; }
815
816         new Ajax.Request("backend.php", {
817                 parameters: "?op=pref-filters&search=" + param_escape(search),
818                 onComplete: function(transport) {
819                         dijit.byId('filterConfigTab').attr('content', transport.responseText);
820                         notify("");
821                 } });
822 }
823
824 function updateLabelList() {
825         new Ajax.Request("backend.php", {
826                 parameters: "?op=pref-labels",
827                 onComplete: function(transport) {
828                         dijit.byId('labelConfigTab').attr('content', transport.responseText);
829                         notify("");
830                 } });
831 }
832
833 function updatePrefsList() {
834         new Ajax.Request("backend.php", {
835                 parameters: "?op=pref-prefs",
836                 onComplete: function(transport) {
837                         dijit.byId('genConfigTab').attr('content', transport.responseText);
838                         notify("");
839                 } });
840 }
841
842 function updateSystemList() {
843         new Ajax.Request("backend.php", {
844                 parameters: "?op=pref-system",
845                 onComplete: function(transport) {
846                         dijit.byId('systemConfigTab').attr('content', transport.responseText);
847                         notify("");
848                 } });
849 }
850
851 function selectTab(id, noupdate, method) {
852         try {
853                 if (!noupdate) {
854                         notify_progress("Loading, please wait...");
855
856                         if (id == "feedConfig") {
857                                 updateFeedList();
858                         } else if (id == "filterConfig") {
859                                 updateFilterList();
860                         } else if (id == "labelConfig") {
861                                 updateLabelList();
862                         } else if (id == "genConfig") {
863                                 updatePrefsList();
864                         } else if (id == "userConfig") {
865                                 updateUsersList();
866                         } else if (id == "systemConfig") {
867                                 updateSystemList();
868                         }
869
870                         var tab = dijit.byId(id + "Tab");
871                         dijit.byId("pref-tabs").selectChild(tab);
872
873                 }
874
875         } catch (e) {
876                 exception_error("selectTab", e);
877         }
878 }
879
880 function init_second_stage() {
881         try {
882
883                 document.onkeydown = pref_hotkey_handler;
884                 loading_set_progress(50);
885                 notify("");
886
887                 dojo.addOnLoad(function() {
888                         var tab = getURLParam('tab');
889
890                         if (tab) {
891                                 tab = dijit.byId(tab + "Tab");
892                                 if (tab) dijit.byId("pref-tabs").selectChild(tab);
893                         }
894
895                         var method = getURLParam('method');
896
897                         if (method == 'editFeed') {
898                                 var param = getURLParam('methodparam');
899
900                                 window.setTimeout('editFeed(' + param + ')', 100);
901                         }
902                 });
903
904                 setTimeout("hotkey_prefix_timeout()", 5*1000);
905
906         } catch (e) {
907                 exception_error("init_second_stage", e);
908         }
909 }
910
911 function init() {
912
913         try {
914                 dojo.registerModulePath("lib", "..");
915                 dojo.registerModulePath("fox", "../../js/");
916
917                 dojo.require("dijit.ColorPalette");
918                 dojo.require("dijit.Dialog");
919                 dojo.require("dijit.form.Button");
920                 dojo.require("dijit.form.CheckBox");
921                 dojo.require("dijit.form.DropDownButton");
922                 dojo.require("dijit.form.FilteringSelect");
923                 dojo.require("dijit.form.Form");
924                 dojo.require("dijit.form.RadioButton");
925                 dojo.require("dijit.form.Select");
926                 dojo.require("dijit.form.SimpleTextarea");
927                 dojo.require("dijit.form.TextBox");
928                 dojo.require("dijit.form.ValidationTextBox");
929                 dojo.require("dijit.InlineEditBox");
930                 dojo.require("dijit.layout.AccordionContainer");
931                 dojo.require("dijit.layout.BorderContainer");
932                 dojo.require("dijit.layout.ContentPane");
933                 dojo.require("dijit.layout.TabContainer");
934                 dojo.require("dijit.Menu");
935                 dojo.require("dijit.ProgressBar");
936                 dojo.require("dijit.ProgressBar");
937                 dojo.require("dijit.Toolbar");
938                 dojo.require("dijit.Tree");
939                 dojo.require("dijit.tree.dndSource");
940                 dojo.require("dojo.data.ItemFileWriteStore");
941
942                 dojo.require("lib.CheckBoxTree");
943                 dojo.require("fox.PrefFeedTree");
944                 dojo.require("fox.PrefFilterTree");
945                 dojo.require("fox.PrefLabelTree");
946
947                 dojo.parser.parse();
948
949                 dojo.addOnLoad(function() {
950                         loading_set_progress(50);
951
952                         var clientTzOffset = new Date().getTimezoneOffset() * 60;
953
954                         new Ajax.Request("backend.php", {
955                                 parameters: {op: "rpc", method: "sanityCheck",
956                                         clientTzOffset: clientTzOffset },
957                                         onComplete: function(transport) {
958                                         backend_sanity_check_callback(transport);
959                                 } });
960                 });
961
962         } catch (e) {
963                 exception_error("init", e);
964         }
965 }
966
967 function validatePrefsReset() {
968         try {
969                 var ok = confirm(__("Reset to defaults?"));
970
971                 if (ok) {
972
973                         query = "?op=pref-prefs&method=resetconfig";
974                         console.log(query);
975
976                         new Ajax.Request("backend.php", {
977                                 parameters: query,
978                                 onComplete: function(transport) {
979                                         updatePrefsList();
980                                         notify_info(transport.responseText);
981                                 } });
982
983                 }
984
985         } catch (e) {
986                 exception_error("validatePrefsReset", e);
987         }
988
989         return false;
990
991 }
992
993 function pref_hotkey_handler(e) {
994         try {
995
996                 if (e.target.nodeName == "INPUT" || e.target.nodeName == "TEXTAREA") return;
997
998                 var keycode = false;
999                 var shift_key = false;
1000
1001                 var cmdline = $('cmdline');
1002
1003                 try {
1004                         shift_key = e.shiftKey;
1005                 } catch (e) {
1006
1007                 }
1008
1009                 if (window.event) {
1010                         keycode = window.event.keyCode;
1011                 } else if (e) {
1012                         keycode = e.which;
1013                 }
1014
1015                 var keychar = String.fromCharCode(keycode);
1016
1017                 if (keycode == 27) { // escape
1018                         hotkey_prefix = false;
1019                 }
1020
1021                 if (keycode == 16) return; // ignore lone shift
1022                 if (keycode == 17) return; // ignore lone ctrl
1023
1024                 if (!shift_key) keychar = keychar.toLowerCase();
1025
1026                 var hotkeys = getInitParam("hotkeys");
1027
1028                 if (!hotkey_prefix && hotkeys[0].indexOf(keychar) != -1) {
1029
1030                         var date = new Date();
1031                         var ts = Math.round(date.getTime() / 1000);
1032
1033                         hotkey_prefix = keychar;
1034                         hotkey_prefix_pressed = ts;
1035
1036                         cmdline.innerHTML = keychar;
1037                         Element.show(cmdline);
1038
1039                         return true;
1040                 }
1041
1042                 Element.hide(cmdline);
1043
1044                 var hotkey = keychar.search(/[a-zA-Z0-9]/) != -1 ? keychar : "(" + keycode + ")";
1045                 hotkey = hotkey_prefix ? hotkey_prefix + " " + hotkey : hotkey;
1046                 hotkey_prefix = false;
1047
1048                 var hotkey_action = false;
1049                 var hotkeys = getInitParam("hotkeys");
1050
1051                 for (sequence in hotkeys[1]) {
1052                         if (sequence == hotkey) {
1053                                 hotkey_action = hotkeys[1][sequence];
1054                                 break;
1055                         }
1056                 }
1057
1058                 switch (hotkey_action) {
1059                 case "feed_subscribe":
1060                         quickAddFeed();
1061                         return false;
1062                 case "create_label":
1063                         addLabel();
1064                         return false;
1065                 case "create_filter":
1066                         quickAddFilter();
1067                         return false;
1068                 case "help_dialog":
1069                         //helpDialog("prefs");
1070                         return false;
1071                 default:
1072                         console.log("unhandled action: " + hotkey_action + "; hotkey: " + hotkey);
1073                 }
1074
1075         } catch (e) {
1076                 exception_error("hotkey_handler", e);
1077         }
1078 }
1079
1080 function removeCategory(id, item) {
1081         try {
1082
1083                 var ok = confirm(__("Remove category %s? Any nested feeds would be placed into Uncategorized.").replace("%s", item.name));
1084
1085                 if (ok) {
1086                         var query = "?op=pref-feeds&method=removeCat&ids="+
1087                                 param_escape(id);
1088
1089                         notify_progress("Removing category...");
1090
1091                         new Ajax.Request("backend.php", {
1092                                 parameters: query,
1093                                 onComplete: function(transport) {
1094                                         notify('');
1095                                         updateFeedList();
1096                                 } });
1097                         }
1098
1099         } catch (e) {
1100                 exception_error("removeCategory", e);
1101         }
1102 }
1103
1104 function removeSelectedCategories() {
1105
1106         var sel_rows = getSelectedCategories();
1107
1108         if (sel_rows.length > 0) {
1109
1110                 var ok = confirm(__("Remove selected categories?"));
1111
1112                 if (ok) {
1113                         notify_progress("Removing selected categories...");
1114
1115                         var query = "?op=pref-feeds&method=removeCat&ids="+
1116                                 param_escape(sel_rows.toString());
1117
1118                         new Ajax.Request("backend.php", {
1119                                 parameters: query,
1120                                 onComplete: function(transport) {
1121                                                 updateFeedList();
1122                                         } });
1123
1124                 }
1125         } else {
1126                 alert(__("No categories are selected."));
1127         }
1128
1129         return false;
1130 }
1131
1132 function createCategory() {
1133         try {
1134                 var title = prompt(__("Category title:"));
1135
1136                 if (title) {
1137
1138                         notify_progress("Creating category...");
1139
1140                         var query = "?op=pref-feeds&method=addCat&cat=" +
1141                                 param_escape(title);
1142
1143                         new Ajax.Request("backend.php", {
1144                                 parameters: query,
1145                                 onComplete: function(transport) {
1146                                         notify('');
1147                                         updateFeedList();
1148                                 } });
1149                 }
1150
1151         } catch (e) {
1152                 exception_error("createCategory", e);
1153         }
1154 }
1155
1156 function showInactiveFeeds() {
1157         try {
1158                 var query = "backend.php?op=pref-feeds&method=inactiveFeeds";
1159
1160                 if (dijit.byId("inactiveFeedsDlg"))
1161                         dijit.byId("inactiveFeedsDlg").destroyRecursive();
1162
1163                 dialog = new dijit.Dialog({
1164                         id: "inactiveFeedsDlg",
1165                         title: __("Feeds without recent updates"),
1166                         style: "width: 600px",
1167                         getSelectedFeeds: function() {
1168                                 return getSelectedTableRowIds("prefInactiveFeedList");
1169                         },
1170                         removeSelected: function() {
1171                                 var sel_rows = this.getSelectedFeeds();
1172
1173                                 console.log(sel_rows);
1174
1175                                 if (sel_rows.length > 0) {
1176                                         var ok = confirm(__("Remove selected feeds?"));
1177
1178                                         if (ok) {
1179                                                 notify_progress("Removing selected feeds...", true);
1180
1181                                                 var query = "?op=pref-feeds&method=remove&ids="+
1182                                                         param_escape(sel_rows.toString());
1183
1184                                                 new Ajax.Request("backend.php", {
1185                                                         parameters: query,
1186                                                         onComplete: function(transport) {
1187                                                                 notify('');
1188                                                                 dialog.hide();
1189                                                                 updateFeedList();
1190                                                         } });
1191                                         }
1192
1193                                 } else {
1194                                         alert(__("No feeds are selected."));
1195                                 }
1196                         },
1197                         execute: function() {
1198                                 if (this.validate()) {
1199                                 }
1200                         },
1201                         href: query});
1202
1203                 dialog.show();
1204
1205         } catch (e) {
1206                 exception_error("showInactiveFeeds", e);
1207         }
1208
1209 }
1210
1211 function opmlRegenKey() {
1212
1213         try {
1214                 var ok = confirm(__("Replace current OPML publishing address with a new one?"));
1215
1216                 if (ok) {
1217
1218                         notify_progress("Trying to change address...", true);
1219
1220                         var query = "?op=pref-feeds&method=regenOPMLKey";
1221
1222                         new Ajax.Request("backend.php", {
1223                                 parameters: query,
1224                                 onComplete: function(transport) {
1225                                                 var reply = JSON.parse(transport.responseText);
1226
1227                                                 var new_link = reply.link;
1228
1229                                                 var e = $('pub_opml_url');
1230
1231                                                 if (new_link) {
1232                                                         e.href = new_link;
1233                                                         e.innerHTML = new_link;
1234
1235                                                         new Effect.Highlight(e);
1236
1237                                                         notify('');
1238
1239                                                 } else {
1240                                                         notify_error("Could not change feed URL.");
1241                                                 }
1242                                 } });
1243                 }
1244         } catch (e) {
1245                 exception_error("opmlRegenKey", e);
1246         }
1247         return false;
1248 }
1249
1250 function feedActionChange() {
1251         try {
1252                 var chooser = $("feedActionChooser");
1253                 var opid = chooser[chooser.selectedIndex].value;
1254
1255                 chooser.selectedIndex = 0;
1256                 feedActionGo(opid);
1257         } catch (e) {
1258                 exception_error("feedActionChange", e);
1259         }
1260 }
1261
1262 function feedActionGo(op) {
1263         try {
1264                 if (op == "facEdit") {
1265
1266                         var rows = getSelectedFeeds();
1267
1268                         if (rows.length > 1) {
1269                                 editSelectedFeeds();
1270                         } else {
1271                                 editSelectedFeed();
1272                         }
1273                 }
1274
1275                 if (op == "facClear") {
1276                         clearSelectedFeeds();
1277                 }
1278
1279                 if (op == "facPurge") {
1280                         purgeSelectedFeeds();
1281                 }
1282
1283                 if (op == "facEditCats") {
1284                         editFeedCats();
1285                 }
1286
1287                 if (op == "facRescore") {
1288                         rescoreSelectedFeeds();
1289                 }
1290
1291                 if (op == "facUnsubscribe") {
1292                         removeSelectedFeeds();
1293                 }
1294
1295         } catch (e) {
1296                 exception_error("feedActionGo", e);
1297
1298         }
1299 }
1300
1301 function clearFeedArticles(feed_id) {
1302
1303         notify_progress("Clearing feed...");
1304
1305         var query = "?op=pref-feeds&quiet=1&method=clear&id=" + feed_id;
1306
1307         new Ajax.Request("backend.php", {
1308                 parameters: query,
1309                 onComplete: function(transport) {
1310                                 notify('');
1311                         } });
1312
1313         return false;
1314 }
1315
1316 function rescoreSelectedFeeds() {
1317
1318         var sel_rows = getSelectedFeeds();
1319
1320         if (sel_rows.length > 0) {
1321
1322                 //var ok = confirm(__("Rescore last 100 articles in selected feeds?"));
1323                 var ok = confirm(__("Rescore articles in selected feeds?"));
1324
1325                 if (ok) {
1326                         notify_progress("Rescoring selected feeds...", true);
1327
1328                         var query = "?op=pref-feeds&method=rescore&quiet=1&ids="+
1329                                 param_escape(sel_rows.toString());
1330
1331                         new Ajax.Request("backend.php", {
1332                                 parameters: query,
1333                                 onComplete: function(transport) {
1334                                                 notify_callback2(transport);
1335                         } });
1336
1337                 }
1338         } else {
1339                 alert(__("No feeds are selected."));
1340         }
1341
1342         return false;
1343 }
1344
1345 function rescore_all_feeds() {
1346         var ok = confirm(__("Rescore all articles? This operation may take a lot of time."));
1347
1348         if (ok) {
1349                 notify_progress("Rescoring feeds...", true);
1350
1351                 var query = "?op=pref-feeds&method=rescoreAll&quiet=1";
1352
1353                 new Ajax.Request("backend.php", {
1354                         parameters: query,
1355                         onComplete: function(transport) {
1356                                         notify_callback2(transport);
1357                 } });
1358         }
1359 }
1360
1361 function labelColorReset() {
1362         try {
1363                 var labels = getSelectedLabels();
1364
1365                 if (labels.length > 0) {
1366                         var ok = confirm(__("Reset selected labels to default colors?"));
1367
1368                         if (ok) {
1369                                 var query = "?op=pref-labels&method=colorreset&ids="+
1370                                         param_escape(labels.toString());
1371
1372                                 new Ajax.Request("backend.php", {
1373                                         parameters: query,
1374                                         onComplete: function(transport) {
1375                                                 updateLabelList();
1376                                         } });
1377                         }
1378
1379                 } else {
1380                         alert(__("No labels are selected."));
1381                 }
1382
1383         } catch (e) {
1384                 exception_error("labelColorReset", e);
1385         }
1386 }
1387
1388
1389 function inPreferences() {
1390         return true;
1391 }
1392
1393 function editProfiles() {
1394         try {
1395
1396                 if (dijit.byId("profileEditDlg"))
1397                         dijit.byId("profileEditDlg").destroyRecursive();
1398
1399                 var query = "backend.php?op=pref-prefs&method=editPrefProfiles";
1400
1401                 dialog = new dijit.Dialog({
1402                         id: "profileEditDlg",
1403                         title: __("Settings Profiles"),
1404                         style: "width: 600px",
1405                         getSelectedProfiles: function() {
1406                                 return getSelectedTableRowIds("prefFeedProfileList");
1407                         },
1408                         removeSelected: function() {
1409                                 var sel_rows = this.getSelectedProfiles();
1410
1411                                 if (sel_rows.length > 0) {
1412                                         var ok = confirm(__("Remove selected profiles? Active and default profiles will not be removed."));
1413
1414                                         if (ok) {
1415                                                 notify_progress("Removing selected profiles...", true);
1416
1417                                                 var query = "?op=rpc&method=remprofiles&ids="+
1418                                                         param_escape(sel_rows.toString());
1419
1420                                                 new Ajax.Request("backend.php", {
1421                                                         parameters: query,
1422                                                         onComplete: function(transport) {
1423                                                                 notify('');
1424                                                                 editProfiles();
1425                                                         } });
1426
1427                                         }
1428
1429                                 } else {
1430                                         alert(__("No profiles are selected."));
1431                                 }
1432                         },
1433                         activateProfile: function() {
1434                                 var sel_rows = this.getSelectedProfiles();
1435
1436                                 if (sel_rows.length == 1) {
1437
1438                                         var ok = confirm(__("Activate selected profile?"));
1439
1440                                         if (ok) {
1441                                                 notify_progress("Loading, please wait...");
1442
1443                                                 var query = "?op=rpc&method=setprofile&id="+
1444                                                         param_escape(sel_rows.toString());
1445
1446                                                 new Ajax.Request("backend.php", {
1447                                                         parameters: query,
1448                                                         onComplete: function(transport) {
1449                                                                 window.location.reload();
1450                                                         } });
1451                                         }
1452
1453                                 } else {
1454                                         alert(__("Please choose a profile to activate."));
1455                                 }
1456                         },
1457                         addProfile: function() {
1458                                 if (this.validate()) {
1459                                         notify_progress("Creating profile...", true);
1460
1461                                         var query = "?op=rpc&method=addprofile&title=" +
1462                                                 param_escape(dialog.attr('value').newprofile);
1463
1464                                         new Ajax.Request("backend.php", {
1465                                                 parameters: query,
1466                                                 onComplete: function(transport) {
1467                                                         notify('');
1468                                                         editProfiles();
1469                                                 } });
1470
1471                                 }
1472                         },
1473                         execute: function() {
1474                                 if (this.validate()) {
1475                                 }
1476                         },
1477                         href: query});
1478
1479                 dialog.show();
1480         } catch (e) {
1481                 exception_error("editProfiles", e);
1482         }
1483 }
1484
1485 function activatePrefProfile() {
1486
1487         var sel_rows = getSelectedFeedCats();
1488
1489         if (sel_rows.length == 1) {
1490
1491                 var ok = confirm(__("Activate selected profile?"));
1492
1493                 if (ok) {
1494                         notify_progress("Loading, please wait...");
1495
1496                         var query = "?op=rpc&method=setprofile&id="+
1497                                 param_escape(sel_rows.toString());
1498
1499                         new Ajax.Request("backend.php", {
1500                                 parameters: query,
1501                                 onComplete: function(transport) {
1502                                         window.location.reload();
1503                                 } });
1504                 }
1505
1506         } else {
1507                 alert(__("Please choose a profile to activate."));
1508         }
1509
1510         return false;
1511 }
1512
1513 function clearFeedAccessKeys() {
1514
1515         var ok = confirm(__("This will invalidate all previously generated feed URLs. Continue?"));
1516
1517         if (ok) {
1518                 notify_progress("Clearing URLs...");
1519
1520                 var query = "?op=pref-feeds&method=clearKeys";
1521
1522                 new Ajax.Request("backend.php", {
1523                         parameters: query,
1524                         onComplete: function(transport) {
1525                                 notify_info("Generated URLs cleared.");
1526                         } });
1527         }
1528
1529         return false;
1530 }
1531
1532 function resetFilterOrder() {
1533         try {
1534                 notify_progress("Loading, please wait...");
1535
1536                 new Ajax.Request("backend.php", {
1537                         parameters: "?op=pref-filters&method=filtersortreset",
1538                         onComplete: function(transport) {
1539                                 updateFilterList();
1540                         } });
1541
1542
1543         } catch (e) {
1544                 exception_error("resetFilterOrder");
1545         }
1546 }
1547
1548
1549 function resetFeedOrder() {
1550         try {
1551                 notify_progress("Loading, please wait...");
1552
1553                 new Ajax.Request("backend.php", {
1554                         parameters: "?op=pref-feeds&method=feedsortreset",
1555                         onComplete: function(transport) {
1556                                 updateFeedList();
1557                         } });
1558
1559
1560         } catch (e) {
1561                 exception_error("resetFeedOrder");
1562         }
1563 }
1564
1565 function resetCatOrder() {
1566         try {
1567                 notify_progress("Loading, please wait...");
1568
1569                 new Ajax.Request("backend.php", {
1570                         parameters: "?op=pref-feeds&method=catsortreset",
1571                         onComplete: function(transport) {
1572                                 updateFeedList();
1573                         } });
1574
1575
1576         } catch (e) {
1577                 exception_error("resetCatOrder");
1578         }
1579 }
1580
1581 function editCat(id, item, event) {
1582         try {
1583                 var new_name = prompt(__('Rename category to:'), item.name);
1584
1585                 if (new_name && new_name != item.name) {
1586
1587                         notify_progress("Loading, please wait...");
1588
1589                         new Ajax.Request("backend.php", {
1590                         parameters: {
1591                                 op: 'pref-feeds',
1592                                 method: 'renamecat',
1593                                 id: id,
1594                                 title: new_name,
1595                         },
1596                         onComplete: function(transport) {
1597                                 updateFeedList();
1598                         } });
1599                 }
1600
1601         } catch (e) {
1602                 exception_error("editCat", e);
1603         }
1604 }
1605
1606 function editLabel(id, event) {
1607         try {
1608                 var query = "backend.php?op=pref-labels&method=edit&id=" +
1609                         param_escape(id);
1610
1611                 if (dijit.byId("labelEditDlg"))
1612                         dijit.byId("labelEditDlg").destroyRecursive();
1613
1614                 dialog = new dijit.Dialog({
1615                         id: "labelEditDlg",
1616                         title: __("Label Editor"),
1617                         style: "width: 600px",
1618                         setLabelColor: function(id, fg, bg) {
1619
1620                                 var kind = '';
1621                                 var color = '';
1622
1623                                 if (fg && bg) {
1624                                         kind = 'both';
1625                                 } else if (fg) {
1626                                         kind = 'fg';
1627                                         color = fg;
1628                                 } else if (bg) {
1629                                         kind = 'bg';
1630                                         color = bg;
1631                                 }
1632
1633                                 var query = "?op=pref-labels&method=colorset&kind="+kind+
1634                                         "&ids=" + param_escape(id) + "&fg=" + param_escape(fg) +
1635                                         "&bg=" + param_escape(bg) + "&color=" + param_escape(color);
1636
1637                 //              console.log(query);
1638
1639                                 var e = $("LICID-" + id);
1640
1641                                 if (e) {
1642                                         if (fg) e.style.color = fg;
1643                                         if (bg) e.style.backgroundColor = bg;
1644                                 }
1645
1646                                 new Ajax.Request("backend.php", { parameters: query });
1647
1648                                 updateFilterList();
1649                         },
1650                         execute: function() {
1651                                 if (this.validate()) {
1652                                         var caption = this.attr('value').caption;
1653                                         var fg_color = this.attr('value').fg_color;
1654                                         var bg_color = this.attr('value').bg_color;
1655                                         var query = dojo.objectToQuery(this.attr('value'));
1656
1657                                         dijit.byId('labelTree').setNameById(id, caption);
1658                                         this.setLabelColor(id, fg_color, bg_color);
1659                                         this.hide();
1660
1661                                         new Ajax.Request("backend.php", {
1662                                                 parameters: query,
1663                                                 onComplete: function(transport) {
1664                                                         updateFilterList();
1665                                         } });
1666                                 }
1667                         },
1668                         href: query});
1669
1670                 dialog.show();
1671
1672         } catch (e) {
1673                 exception_error("editLabel", e);
1674         }
1675 }
1676
1677
1678 function customizeCSS() {
1679         try {
1680                 var query = "backend.php?op=pref-prefs&method=customizeCSS";
1681
1682                 if (dijit.byId("cssEditDlg"))
1683                         dijit.byId("cssEditDlg").destroyRecursive();
1684
1685                 dialog = new dijit.Dialog({
1686                         id: "cssEditDlg",
1687                         title: __("Customize stylesheet"),
1688                         style: "width: 600px",
1689                         execute: function() {
1690                                 notify_progress('Saving data...', true);
1691                                 new Ajax.Request("backend.php", {
1692                                         parameters: dojo.objectToQuery(this.attr('value')),
1693                                         onComplete: function(transport) {
1694                                                 notify('');
1695                                                 window.location.reload();
1696                                 } });
1697
1698                         },
1699                         href: query});
1700
1701                 dialog.show();
1702
1703         } catch (e) {
1704                 exception_error("customizeCSS", e);
1705         }
1706 }
1707
1708 function insertSSLserial(value) {
1709         try {
1710                 dijit.byId("SSL_CERT_SERIAL").attr('value', value);
1711         } catch (e) {
1712                 exception_error("insertSSLcerial", e);
1713         }
1714 }
1715
1716 function gotoExportOpml(filename, settings) {
1717         tmp = settings ? 1 : 0;
1718         document.location.href = "backend.php?op=opml&method=export&filename=" + filename + "&settings=" + tmp;
1719 }
1720
1721
1722 function batchSubscribe() {
1723         try {
1724                 var query = "backend.php?op=pref-feeds&method=batchSubscribe";
1725
1726                 // overlapping widgets
1727                 if (dijit.byId("batchSubDlg")) dijit.byId("batchSubDlg").destroyRecursive();
1728                 if (dijit.byId("feedAddDlg"))   dijit.byId("feedAddDlg").destroyRecursive();
1729
1730                 var dialog = new dijit.Dialog({
1731                         id: "batchSubDlg",
1732                         title: __("Batch subscribe"),
1733                         style: "width: 600px",
1734                         execute: function() {
1735                                 if (this.validate()) {
1736                                         console.log(dojo.objectToQuery(this.attr('value')));
1737
1738                                         notify_progress(__("Subscribing to feeds..."), true);
1739
1740                                         new Ajax.Request("backend.php", {
1741                                                 parameters: dojo.objectToQuery(this.attr('value')),
1742                                                 onComplete: function(transport) {
1743                                                         notify("");
1744                                                         updateFeedList();
1745                                                         dialog.hide();
1746                                                 } });
1747                                         }
1748                         },
1749                         href: query});
1750
1751                 dialog.show();
1752         } catch (e) {
1753                 exception_error("batchSubscribe", e);
1754         }
1755 }
1756
1757
1758 function toggleAdvancedPrefs() {
1759         try {
1760                 notify_progress("Loading, please wait...");
1761
1762                 new Ajax.Request("backend.php", {
1763                         parameters: "?op=pref-prefs&method=toggleadvanced",
1764                         onComplete: function(transport) {
1765                                 updatePrefsList();
1766                         } });
1767
1768         } catch (e) {
1769                 exception_error("toggleAdvancedPrefs", e);
1770         }
1771 }
1772
1773 function clearPluginData(name) {
1774         try {
1775                 if (confirm(__("Clear stored data for this plugin?"))) {
1776                         notify_progress("Loading, please wait...");
1777
1778                         new Ajax.Request("backend.php", {
1779                                 parameters: "?op=pref-prefs&method=clearplugindata&name=" + param_escape(name),
1780                                 onComplete: function(transport) {
1781                                         notify('');
1782                                         updatePrefsList();
1783                                 } });
1784                 }
1785         } catch (e) {
1786                 exception_error("clearPluginData", e);
1787         }
1788 }
1789
1790 function clearSqlLog() {
1791
1792         if (confirm(__("Clear all messages in the error log?"))) {
1793
1794                 notify_progress("Loading, please wait...");
1795                 var query = "?op=pref-system&method=clearLog";
1796
1797                 new Ajax.Request("backend.php", {
1798                         parameters: query,
1799                         onComplete: function(transport) {
1800                                 updateSystemList();
1801                         } });
1802
1803         }
1804 }
1805
1806