summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorHugues Hiegel <hugues@hiegel.fr>2013-09-12 11:35:26 +0200
committerHugues Hiegel <root@paranoid>2013-11-08 17:40:16 +0100
commit31de4bc5ebf9556817554ae9630ca06e92fd7218 (patch)
treef98afd42b6f4f818b3f4c489b2e6a7b3912dbb93 /plugins
parentef14bd0d8d58ae0f57aa1969e31a5373aa441dba (diff)
Updates / Plugins
Diffstat (limited to 'plugins')
-rw-r--r--plugins/archive/localization/nb_NB.inc21
-rw-r--r--plugins/compose_addressbook/compose_addressbook.js224
-rw-r--r--plugins/compose_addressbook/compose_addressbook.php180
-rw-r--r--plugins/compose_addressbook/config.inc.php.dist21
-rw-r--r--plugins/compose_addressbook/localization/de_DE.inc11
-rw-r--r--plugins/compose_addressbook/localization/en_GB.inc10
-rw-r--r--plugins/compose_addressbook/localization/en_US.inc10
-rw-r--r--plugins/compose_addressbook/localization/es_ES.inc10
-rw-r--r--plugins/compose_addressbook/localization/fr_FR.inc10
-rw-r--r--plugins/compose_addressbook/localization/it_IT.inc10
-rw-r--r--plugins/compose_addressbook/localization/nl_NL.inc10
-rw-r--r--plugins/compose_addressbook/localization/pl_PL.inc10
-rw-r--r--plugins/compose_addressbook/localization/sv_SE.inc10
-rw-r--r--plugins/compose_addressbook/localization/zh_TW.inc10
-rw-r--r--plugins/compose_addressbook/package.xml18
-rw-r--r--plugins/compose_addressbook/skins/classic/compose_addressbook.css83
-rw-r--r--plugins/compose_addressbook/skins/classic/compose_addressbook.pngbin0 -> 4142 bytes
-rw-r--r--plugins/compose_addressbook/skins/classic/searchfield.gifbin0 -> 397 bytes
-rw-r--r--plugins/compose_addressbook/skins/classic/smoothness/images/ui-anim_basic_16x16.gifbin0 -> 1553 bytes
-rw-r--r--plugins/compose_addressbook/skins/classic/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.pngbin0 -> 180 bytes
-rw-r--r--plugins/compose_addressbook/skins/classic/smoothness/images/ui-bg_flat_75_ffffff_40x100.pngbin0 -> 178 bytes
-rw-r--r--plugins/compose_addressbook/skins/classic/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.pngbin0 -> 120 bytes
-rw-r--r--plugins/compose_addressbook/skins/classic/smoothness/images/ui-bg_glass_65_ffffff_1x400.pngbin0 -> 105 bytes
-rw-r--r--plugins/compose_addressbook/skins/classic/smoothness/images/ui-bg_glass_75_dadada_1x400.pngbin0 -> 111 bytes
-rw-r--r--plugins/compose_addressbook/skins/classic/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.pngbin0 -> 110 bytes
-rw-r--r--plugins/compose_addressbook/skins/classic/smoothness/images/ui-bg_glass_95_fef1ec_1x400.pngbin0 -> 119 bytes
-rw-r--r--plugins/compose_addressbook/skins/classic/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.pngbin0 -> 101 bytes
-rw-r--r--plugins/compose_addressbook/skins/classic/smoothness/images/ui-icons_222222_256x240.pngbin0 -> 4369 bytes
-rw-r--r--plugins/compose_addressbook/skins/classic/smoothness/images/ui-icons_2e83ff_256x240.pngbin0 -> 4369 bytes
-rw-r--r--plugins/compose_addressbook/skins/classic/smoothness/images/ui-icons_454545_256x240.pngbin0 -> 4369 bytes
-rw-r--r--plugins/compose_addressbook/skins/classic/smoothness/images/ui-icons_888888_256x240.pngbin0 -> 4369 bytes
-rw-r--r--plugins/compose_addressbook/skins/classic/smoothness/images/ui-icons_cd0a0a_256x240.pngbin0 -> 4369 bytes
-rw-r--r--plugins/compose_addressbook/skins/classic/smoothness/jquery-ui-1.8.2.custom.css345
-rw-r--r--plugins/contextmenu/contextmenu.js595
-rw-r--r--plugins/contextmenu/contextmenu.php315
-rw-r--r--plugins/contextmenu/jquery.contextMenu.js21
l---------plugins/contextmenu/jquery.mousewheel.js1
-rw-r--r--plugins/contextmenu/localization/ca_ES.inc12
-rw-r--r--plugins/contextmenu/localization/cs_CZ.inc12
-rw-r--r--plugins/contextmenu/localization/da_DK.inc12
-rw-r--r--plugins/contextmenu/localization/de_CH.inc12
-rw-r--r--plugins/contextmenu/localization/de_DE.inc12
-rw-r--r--plugins/contextmenu/localization/en_GB.inc12
-rw-r--r--plugins/contextmenu/localization/en_US.inc12
-rw-r--r--plugins/contextmenu/localization/es_ES.inc12
-rw-r--r--plugins/contextmenu/localization/fr_FR.inc12
-rw-r--r--plugins/contextmenu/localization/gl_ES.inc12
-rw-r--r--plugins/contextmenu/localization/hu_HU.inc12
-rw-r--r--plugins/contextmenu/localization/it_IT.inc12
-rw-r--r--plugins/contextmenu/localization/nl_NL.inc12
-rw-r--r--plugins/contextmenu/localization/pl_PL.inc12
-rw-r--r--plugins/contextmenu/localization/pt_BR.inc12
-rw-r--r--plugins/contextmenu/localization/ro_RO.inc12
-rw-r--r--plugins/contextmenu/localization/ru_RU.inc12
-rw-r--r--plugins/contextmenu/localization/sv_SE.inc12
-rw-r--r--plugins/contextmenu/localization/tr_TR.inc12
-rw-r--r--plugins/contextmenu/localization/uk_UA.inc12
-rw-r--r--plugins/contextmenu/localization/zh_TW.inc12
-rw-r--r--plugins/contextmenu/package.xml90
-rw-r--r--plugins/contextmenu/skins/classic/contexticons.gifbin0 -> 2238 bytes
-rw-r--r--plugins/contextmenu/skins/classic/contexticons.pngbin0 -> 4261 bytes
-rw-r--r--plugins/contextmenu/skins/classic/contextmenu.css357
-rw-r--r--plugins/contextmenu/skins/classic/folders.gifbin0 -> 2430 bytes
-rw-r--r--plugins/contextmenu/skins/classic/folders.pngbin0 -> 4771 bytes
-rw-r--r--plugins/contextmenu/skins/classic/ie6hacks.css54
-rw-r--r--plugins/contextmenu/skins/classic/messageactions.gifbin0 -> 1567 bytes
-rw-r--r--plugins/contextmenu/skins/classic/messageactions.pngbin0 -> 2578 bytes
-rw-r--r--plugins/contextmenu/skins/larry/contexticons.pngbin0 -> 5728 bytes
-rw-r--r--plugins/contextmenu/skins/larry/contextmenu.css425
-rw-r--r--plugins/contextmenu/skins/larry/folders.pngbin0 -> 3901 bytes
-rw-r--r--plugins/contextmenu/skins/larry/ie6hacks.css3
-rw-r--r--plugins/contextmenu/skins/larry/messageactions.pngbin0 -> 1698 bytes
-rw-r--r--plugins/copymessage/copymessage.js40
-rw-r--r--plugins/copymessage/copymessage.php114
-rw-r--r--plugins/copymessage/localization/ca_ES.inc9
-rw-r--r--plugins/copymessage/localization/cs_CZ.inc9
-rw-r--r--plugins/copymessage/localization/da_DK.inc9
-rw-r--r--plugins/copymessage/localization/de_CH.inc9
-rw-r--r--plugins/copymessage/localization/de_DE.inc9
-rw-r--r--plugins/copymessage/localization/en_GB.inc9
-rw-r--r--plugins/copymessage/localization/en_US.inc9
-rw-r--r--plugins/copymessage/localization/es_ES.inc9
-rw-r--r--plugins/copymessage/localization/fr_FR.inc9
-rw-r--r--plugins/copymessage/localization/gl_ES.inc9
-rw-r--r--plugins/copymessage/localization/hu_HU.inc9
-rw-r--r--plugins/copymessage/localization/it_IT.inc9
-rw-r--r--plugins/copymessage/localization/nl_NL.inc9
-rw-r--r--plugins/copymessage/localization/pl_PL.inc9
-rw-r--r--plugins/copymessage/localization/pt_BR.inc9
-rw-r--r--plugins/copymessage/localization/ro_RO.inc9
-rw-r--r--plugins/copymessage/localization/ru_RU.inc9
-rw-r--r--plugins/copymessage/localization/sv_SE.inc9
-rw-r--r--plugins/copymessage/localization/tr_TR.inc9
-rw-r--r--plugins/copymessage/package.xml78
-rw-r--r--plugins/dkimstatus/dkimstatus.php155
-rw-r--r--plugins/dkimstatus/images/authorsign.pngbin0 -> 699 bytes
-rw-r--r--plugins/dkimstatus/images/invalidsig.pngbin0 -> 618 bytes
-rw-r--r--plugins/dkimstatus/images/nosiginfo.pngbin0 -> 707 bytes
-rw-r--r--plugins/dkimstatus/images/thirdpty.pngbin0 -> 722 bytes
-rw-r--r--plugins/dkimstatus/localization/cs_CZ.inc16
-rw-r--r--plugins/dkimstatus/localization/de_DE.inc8
-rw-r--r--plugins/dkimstatus/localization/en_US.inc9
-rw-r--r--plugins/dkimstatus/localization/es_ES.inc9
-rw-r--r--plugins/dkimstatus/localization/fr_FR.inc10
-rw-r--r--plugins/dkimstatus/localization/it_IT.inc7
-rw-r--r--plugins/dkimstatus/localization/ja_JP.inc9
-rw-r--r--plugins/dkimstatus/localization/pl_PL.inc9
-rw-r--r--plugins/dkimstatus/localization/ro_RO.inc9
-rw-r--r--plugins/dovecot_impersonate/config.inc.php.dist10
-rw-r--r--plugins/dovecot_impersonate/dovecot_impersonate.php52
-rw-r--r--plugins/dovecot_impersonate/package.xml18
-rw-r--r--plugins/enigma/home/aldric/pubring.gpg0
-rw-r--r--plugins/enigma/home/aldric/secring.gpg0
-rw-r--r--plugins/enigma/home/aldric/trustdb.gpgbin0 -> 40 bytes
-rw-r--r--plugins/enigma/home/hugues/pubring.gpgbin0 -> 133165 bytes
-rw-r--r--plugins/enigma/home/hugues/secring.gpgbin0 -> 1350 bytes
-rw-r--r--plugins/enigma/home/hugues/trustdb.gpgbin0 -> 1200 bytes
-rw-r--r--plugins/fail2ban/fail2ban.php33
l---------plugins/jqueryui/css1
l---------plugins/jqueryui/js/jquery-ui.min.js1
-rw-r--r--plugins/keyboard_shortcuts/keyboard_shortcuts.css23
-rw-r--r--plugins/keyboard_shortcuts/keyboard_shortcuts.js139
-rw-r--r--plugins/keyboard_shortcuts/keyboard_shortcuts.php130
-rw-r--r--plugins/keyboard_shortcuts/localization/cs_CZ.inc24
-rw-r--r--plugins/keyboard_shortcuts/localization/de_DE.inc10
-rw-r--r--plugins/keyboard_shortcuts/localization/en_US.inc11
-rw-r--r--plugins/keyboard_shortcuts/localization/fr_FR.inc11
-rw-r--r--plugins/keyboard_shortcuts/localization/nl_NL.inc11
-rw-r--r--plugins/keyboard_shortcuts/localization/pl_PL.inc11
-rw-r--r--plugins/keyboard_shortcuts/localization/ru_RU.inc11
-rw-r--r--plugins/keyboard_shortcuts/localization/sv_SE.inc10
-rw-r--r--plugins/keyboard_shortcuts/localization/zh_TW.inc11
-rw-r--r--plugins/keyboard_shortcuts/package.xml18
-rw-r--r--plugins/keyboard_shortcuts/skins/classic/images/keyboard.pngbin0 -> 4157 bytes
-rw-r--r--plugins/keyboard_shortcuts/skins/larry/images/keyboard.pngbin0 -> 4157 bytes
-rw-r--r--plugins/listcommands/listcommands.php106
-rw-r--r--plugins/listcommands/localization/en_US.inc12
-rw-r--r--plugins/listcommands/localization/es_ES.inc12
-rw-r--r--plugins/listcommands/localization/fr_FR.inc13
-rw-r--r--plugins/listcommands/localization/nl_NL.inc12
-rw-r--r--plugins/listcommands/localization/pl_PL.inc12
-rw-r--r--plugins/listcommands/localization/ru_RU.inc12
-rw-r--r--plugins/listcommands/package.xml18
-rw-r--r--plugins/markasjunk2/config.inc.php.dist152
-rw-r--r--plugins/markasjunk2/drivers/cmd_learn.php74
-rw-r--r--plugins/markasjunk2/drivers/dir_learn.php49
-rw-r--r--plugins/markasjunk2/drivers/edit_headers.php53
-rw-r--r--plugins/markasjunk2/drivers/email_learn.php191
-rw-r--r--plugins/markasjunk2/drivers/sa_blacklist.php103
-rw-r--r--plugins/markasjunk2/drivers/sa_detach.php47
-rw-r--r--plugins/markasjunk2/localization/ca_ES.inc14
-rw-r--r--plugins/markasjunk2/localization/cs_CZ.inc14
-rw-r--r--plugins/markasjunk2/localization/de_CH.inc15
-rw-r--r--plugins/markasjunk2/localization/de_DE.inc15
-rw-r--r--plugins/markasjunk2/localization/en_GB.inc15
-rw-r--r--plugins/markasjunk2/localization/en_US.inc15
-rw-r--r--plugins/markasjunk2/localization/es_AR.inc14
-rw-r--r--plugins/markasjunk2/localization/es_ES.inc14
-rw-r--r--plugins/markasjunk2/localization/fa_IR.inc14
-rw-r--r--plugins/markasjunk2/localization/fr_FR.inc14
-rw-r--r--plugins/markasjunk2/localization/gl_ES.inc14
-rw-r--r--plugins/markasjunk2/localization/hu_HU.inc14
-rw-r--r--plugins/markasjunk2/localization/it_IT.inc15
-rw-r--r--plugins/markasjunk2/localization/lv_LV.inc15
-rw-r--r--plugins/markasjunk2/localization/nl_NL.inc14
-rw-r--r--plugins/markasjunk2/localization/pl_PL.inc15
-rw-r--r--plugins/markasjunk2/localization/pt_BR.inc14
-rw-r--r--plugins/markasjunk2/localization/ro_RO.inc14
-rw-r--r--plugins/markasjunk2/localization/ru_RU.inc15
-rw-r--r--plugins/markasjunk2/localization/tr_TR.inc14
-rw-r--r--plugins/markasjunk2/localization/zh_TW.inc14
-rw-r--r--plugins/markasjunk2/markasjunk2.js199
-rw-r--r--plugins/markasjunk2/markasjunk2.php211
-rw-r--r--plugins/markasjunk2/package.xml92
-rw-r--r--plugins/markasjunk2/skins/classic/ie6hacks.css19
-rw-r--r--plugins/markasjunk2/skins/classic/mail_toolbar.gifbin0 -> 3434 bytes
-rw-r--r--plugins/markasjunk2/skins/classic/mail_toolbar.pngbin0 -> 7565 bytes
-rw-r--r--plugins/markasjunk2/skins/classic/markasjunk2.css52
-rw-r--r--plugins/markasjunk2/skins/classic/messageactions.gifbin0 -> 1307 bytes
-rw-r--r--plugins/markasjunk2/skins/classic/messageactions.pngbin0 -> 1798 bytes
-rw-r--r--plugins/markasjunk2/skins/larry/ie6hacks.css3
-rw-r--r--plugins/markasjunk2/skins/larry/mail_toolbar.pngbin0 -> 1924 bytes
-rw-r--r--plugins/markasjunk2/skins/larry/markasjunk2.css51
-rw-r--r--plugins/markasjunk2/skins/larry/messageactions.pngbin0 -> 1050 bytes
-rw-r--r--plugins/message_highlight/colorpicker/images/color.pngbin0 -> 892 bytes
-rw-r--r--plugins/message_highlight/colorpicker/images/colorpicker.pngbin0 -> 4739 bytes
-rw-r--r--plugins/message_highlight/colorpicker/images/graybar.jpgbin0 -> 5225 bytes
-rw-r--r--plugins/message_highlight/colorpicker/images/grid.gifbin0 -> 87 bytes
-rw-r--r--plugins/message_highlight/colorpicker/images/meta100.pngbin0 -> 828 bytes
-rw-r--r--plugins/message_highlight/colorpicker/images/transparentpixel.gifbin0 -> 43 bytes
-rw-r--r--plugins/message_highlight/colorpicker/mColorPicker.js564
-rw-r--r--plugins/message_highlight/localization/de_DE.inc15
-rw-r--r--plugins/message_highlight/localization/en_US.inc16
-rw-r--r--plugins/message_highlight/localization/fr_FR.inc16
-rw-r--r--plugins/message_highlight/localization/nl_NL.inc15
-rw-r--r--plugins/message_highlight/localization/ru_RU.inc14
-rw-r--r--plugins/message_highlight/message_highlight.css74
-rw-r--r--plugins/message_highlight/message_highlight.js58
-rw-r--r--plugins/message_highlight/message_highlight.php176
-rw-r--r--plugins/message_highlight/package.xml18
-rw-r--r--plugins/quickrules/localization/cs_CZ.inc9
-rw-r--r--plugins/quickrules/localization/de_CH.inc10
-rw-r--r--plugins/quickrules/localization/de_DE.inc10
-rw-r--r--plugins/quickrules/localization/en_GB.inc10
-rw-r--r--plugins/quickrules/localization/en_US.inc10
-rw-r--r--plugins/quickrules/localization/hu_HU.inc9
-rw-r--r--plugins/quickrules/localization/it_IT.inc10
-rw-r--r--plugins/quickrules/localization/pl_PL.inc9
-rw-r--r--plugins/quickrules/localization/pt_BR.inc9
-rw-r--r--plugins/quickrules/localization/pt_PT.inc9
-rw-r--r--plugins/quickrules/package.xml79
-rw-r--r--plugins/quickrules/quickrules.js169
-rw-r--r--plugins/quickrules/quickrules.php137
-rw-r--r--plugins/quickrules/skins/classic/ie6hacks.css14
-rw-r--r--plugins/quickrules/skins/classic/mail_toolbar.gifbin0 -> 1722 bytes
-rw-r--r--plugins/quickrules/skins/classic/mail_toolbar.pngbin0 -> 3310 bytes
-rw-r--r--plugins/quickrules/skins/classic/messageactions.gifbin0 -> 571 bytes
-rw-r--r--plugins/quickrules/skins/classic/messageactions.pngbin0 -> 842 bytes
-rw-r--r--plugins/quickrules/skins/classic/quickrules.css26
-rw-r--r--plugins/quickrules/skins/larry/ie6hacks.css3
-rw-r--r--plugins/quickrules/skins/larry/mail_toolbar.pngbin0 -> 1350 bytes
-rw-r--r--plugins/quickrules/skins/larry/messageactions.pngbin0 -> 672 bytes
-rw-r--r--plugins/quickrules/skins/larry/quickrules.css21
-rw-r--r--plugins/sauserprefs/config.inc.php.dist160
-rw-r--r--plugins/sauserprefs/include/rcube_sauserprefs_storage.php268
-rw-r--r--plugins/sauserprefs/localization/cs_CZ.inc86
-rw-r--r--plugins/sauserprefs/localization/de_CH.inc86
-rw-r--r--plugins/sauserprefs/localization/de_DE.inc86
-rw-r--r--plugins/sauserprefs/localization/en_GB.inc86
-rw-r--r--plugins/sauserprefs/localization/en_US.inc86
-rw-r--r--plugins/sauserprefs/localization/es_ES.inc85
-rw-r--r--plugins/sauserprefs/localization/fr_FR.inc86
-rw-r--r--plugins/sauserprefs/localization/gl_ES.inc85
-rw-r--r--plugins/sauserprefs/localization/hu_HU.inc61
-rw-r--r--plugins/sauserprefs/localization/it_IT.inc86
-rw-r--r--plugins/sauserprefs/localization/pl_PL.inc86
-rw-r--r--plugins/sauserprefs/localization/pt_BR.inc85
-rw-r--r--plugins/sauserprefs/localization/ro_RO.inc85
-rw-r--r--plugins/sauserprefs/localization/ru_RU.inc87
-rw-r--r--plugins/sauserprefs/localization/sk_SK.inc86
-rw-r--r--plugins/sauserprefs/localization/sv_SE.inc84
-rw-r--r--plugins/sauserprefs/package.xml91
-rw-r--r--plugins/sauserprefs/sauserprefs.js459
-rw-r--r--plugins/sauserprefs/sauserprefs.php909
-rw-r--r--plugins/sauserprefs/skins/classic/help.gifbin0 -> 1024 bytes
-rw-r--r--plugins/sauserprefs/skins/classic/icons.gifbin0 -> 1345 bytes
-rw-r--r--plugins/sauserprefs/skins/classic/icons.pngbin0 -> 2045 bytes
-rw-r--r--plugins/sauserprefs/skins/classic/ie6hacks.css9
-rw-r--r--plugins/sauserprefs/skins/classic/iehacks.css9
-rw-r--r--plugins/sauserprefs/skins/classic/safari.css6
-rw-r--r--plugins/sauserprefs/skins/classic/sauserprefs.css185
-rw-r--r--plugins/sauserprefs/skins/classic/tabstyles.css3
-rw-r--r--plugins/sauserprefs/skins/classic/templates/sauserprefs.html47
-rw-r--r--plugins/sauserprefs/skins/classic/templates/settingsedit.html33
-rw-r--r--plugins/sauserprefs/skins/larry/help.pngbin0 -> 475 bytes
-rw-r--r--plugins/sauserprefs/skins/larry/icons.pngbin0 -> 962 bytes
-rw-r--r--plugins/sauserprefs/skins/larry/iehacks.css9
-rw-r--r--plugins/sauserprefs/skins/larry/listicons.pngbin0 -> 4891 bytes
-rw-r--r--plugins/sauserprefs/skins/larry/safari.css6
-rw-r--r--plugins/sauserprefs/skins/larry/sauserprefs.css253
-rw-r--r--plugins/sauserprefs/skins/larry/tabstyles.css15
-rw-r--r--plugins/sauserprefs/skins/larry/templates/sauserprefs.html54
-rw-r--r--plugins/sauserprefs/skins/larry/templates/settingsedit.html30
-rw-r--r--plugins/sieverules/config.inc.php.dist147
-rw-r--r--plugins/sieverules/importFilters/avelsieve.php54
-rw-r--r--plugins/sieverules/importFilters/ingo.php52
-rw-r--r--plugins/sieverules/include/rcube_sieve.php249
-rw-r--r--plugins/sieverules/include/rcube_sieve_script.php969
-rw-r--r--plugins/sieverules/jquery.maskedinput.js7
l---------plugins/sieverules/lib/Net/Sieve.php1
-rw-r--r--plugins/sieverules/localization/ca_ES.inc168
-rw-r--r--plugins/sieverules/localization/cs_CZ.inc195
-rw-r--r--plugins/sieverules/localization/de_CH.inc192
-rw-r--r--plugins/sieverules/localization/de_DE.inc192
-rw-r--r--plugins/sieverules/localization/en_GB.inc205
-rw-r--r--plugins/sieverules/localization/en_US.inc205
-rw-r--r--plugins/sieverules/localization/es_AR.inc140
-rw-r--r--plugins/sieverules/localization/es_ES.inc185
-rw-r--r--plugins/sieverules/localization/et_EE.inc79
-rw-r--r--plugins/sieverules/localization/fi_FI.inc186
-rw-r--r--plugins/sieverules/localization/fr_FR.inc185
-rw-r--r--plugins/sieverules/localization/hu_HU.inc171
-rw-r--r--plugins/sieverules/localization/it_IT.inc202
-rw-r--r--plugins/sieverules/localization/nl_NL.inc205
-rw-r--r--plugins/sieverules/localization/pl_PL.inc205
-rw-r--r--plugins/sieverules/localization/pt_BR.inc183
-rw-r--r--plugins/sieverules/localization/pt_PT.inc183
-rw-r--r--plugins/sieverules/localization/ro_RO.inc175
-rw-r--r--plugins/sieverules/localization/ru_RU.inc182
-rw-r--r--plugins/sieverules/localization/sk_SK.inc159
-rw-r--r--plugins/sieverules/localization/sl_SI.inc185
-rw-r--r--plugins/sieverules/localization/sv_SE.inc159
-rw-r--r--plugins/sieverules/localization/zh_TW.inc192
-rw-r--r--plugins/sieverules/package.xml116
-rw-r--r--plugins/sieverules/sieverules.js1480
-rw-r--r--plugins/sieverules/sieverules.php2331
-rw-r--r--plugins/sieverules/skins/classic/cross.gifbin0 -> 577 bytes
-rw-r--r--plugins/sieverules/skins/classic/help.gifbin0 -> 1024 bytes
-rw-r--r--plugins/sieverules/skins/classic/icons.gifbin0 -> 2017 bytes
-rw-r--r--plugins/sieverules/skins/classic/icons.pngbin0 -> 2748 bytes
-rw-r--r--plugins/sieverules/skins/classic/ie6hacks.css10
-rw-r--r--plugins/sieverules/skins/classic/iehacks.css53
-rw-r--r--plugins/sieverules/skins/classic/safari.css8
-rw-r--r--plugins/sieverules/skins/classic/sieverules.css406
-rw-r--r--plugins/sieverules/skins/classic/tabstyles.css3
-rw-r--r--plugins/sieverules/skins/classic/templates/advancededitor.html55
-rw-r--r--plugins/sieverules/skins/classic/templates/editsieverule.html29
-rw-r--r--plugins/sieverules/skins/classic/templates/setupsieverules.html18
-rw-r--r--plugins/sieverules/skins/classic/templates/sieverules.html93
-rw-r--r--plugins/sieverules/skins/classic/tick.gifbin0 -> 545 bytes
-rw-r--r--plugins/sieverules/skins/larry/cross.pngbin0 -> 342 bytes
-rw-r--r--plugins/sieverules/skins/larry/help.pngbin0 -> 475 bytes
-rw-r--r--plugins/sieverules/skins/larry/icons.pngbin0 -> 1773 bytes
-rw-r--r--plugins/sieverules/skins/larry/iehacks.css53
-rw-r--r--plugins/sieverules/skins/larry/listicons.pngbin0 -> 1345 bytes
-rw-r--r--plugins/sieverules/skins/larry/safari.css8
-rw-r--r--plugins/sieverules/skins/larry/sieverules.css435
-rw-r--r--plugins/sieverules/skins/larry/tabstyles.css15
-rw-r--r--plugins/sieverules/skins/larry/templates/advancededitor.html60
-rw-r--r--plugins/sieverules/skins/larry/templates/editsieverule.html30
-rw-r--r--plugins/sieverules/skins/larry/templates/setupsieverules.html27
-rw-r--r--plugins/sieverules/skins/larry/templates/sieverules.html78
-rw-r--r--plugins/sieverules/skins/larry/tick.pngbin0 -> 284 bytes
-rw-r--r--plugins/thunderbird_labels/localization/bg_BG.inc17
-rw-r--r--plugins/thunderbird_labels/localization/ca_ES.inc17
-rw-r--r--plugins/thunderbird_labels/localization/cs_CZ.inc18
-rw-r--r--plugins/thunderbird_labels/localization/de_DE.inc18
-rw-r--r--plugins/thunderbird_labels/localization/en_US.inc18
-rw-r--r--plugins/thunderbird_labels/localization/fr_FR.inc17
-rw-r--r--plugins/thunderbird_labels/localization/hu_HU.inc18
-rw-r--r--plugins/thunderbird_labels/localization/lv_LV.inc17
-rw-r--r--plugins/thunderbird_labels/localization/pl_PL.inc18
-rw-r--r--plugins/thunderbird_labels/localization/ru_RU.inc18
-rw-r--r--plugins/thunderbird_labels/skins/classic/tb_label.css183
-rw-r--r--plugins/thunderbird_labels/skins/classic/thunderbird_32.pngbin0 -> 3232 bytes
-rw-r--r--plugins/thunderbird_labels/skins/default/tb_label.css183
-rw-r--r--plugins/thunderbird_labels/skins/default/thunderbird_32.pngbin0 -> 3232 bytes
-rw-r--r--plugins/thunderbird_labels/skins/larry/tb_label.css170
-rw-r--r--plugins/thunderbird_labels/skins/larry/thunderbird_32.pngbin0 -> 2662 bytes
-rw-r--r--plugins/thunderbird_labels/tb_label.js369
-rw-r--r--plugins/thunderbird_labels/thunderbird_labels.php210
341 files changed, 23693 insertions, 0 deletions
diff --git a/plugins/archive/localization/nb_NB.inc b/plugins/archive/localization/nb_NB.inc
new file mode 100644
index 000000000..46e49aba0
--- /dev/null
+++ b/plugins/archive/localization/nb_NB.inc
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | localization/nb_NB/labels.inc |
+ | |
+ | Language file of the Roundcube Webmail client |
+ | Copyright (C) 2012, The Roundcube Dev Team |
+ | Licensed under the GNU General Public License |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Tobias V. Langhoff <spug@thespug.net> |
+ +-----------------------------------------------------------------------+
+*/
+
+$labels = array();
+$labels['buttontext'] = 'Arkiv';
+$labels['archivefolder'] = 'Arkiv';
+$labels['buttontitle'] = 'Arkiver meldingen';
+$labels['archived'] = 'Arkivert';
+
diff --git a/plugins/compose_addressbook/compose_addressbook.js b/plugins/compose_addressbook/compose_addressbook.js
new file mode 100644
index 000000000..de5d95276
--- /dev/null
+++ b/plugins/compose_addressbook/compose_addressbook.js
@@ -0,0 +1,224 @@
+var compose_addressbook_fetched = false;
+
+if(window.rcmail) {
+ rcmail.addEventListener('init', function(evt) {
+
+ // mode of operation. configure this in config.php
+ var mode = rcmail.env.compose_addressbook_mode;
+
+ // to be able to have translated buttons, we need to predefine the buttons array
+ var cab_to = rcmail.gettext('to');
+ var cab_cc = rcmail.gettext('cc');
+ var cab_bcc = rcmail.gettext('bcc');
+
+ var buttons = {};
+ buttons[cab_bcc] = function() {
+ compose_addressbook_add_recipients('_bcc');
+ $('.ui-dialog-buttonpane button').removeClass('ui-state-focus');
+ }
+ buttons[cab_cc] = function() {
+ compose_addressbook_add_recipients('_cc');
+ $('.ui-dialog-buttonpane button').removeClass('ui-state-focus');
+ }
+ buttons[cab_to] = function() {
+ compose_addressbook_add_recipients('_to');
+ $('.ui-dialog-buttonpane button').removeClass('ui-state-focus');
+ }
+
+ // bind the dialog functionality to the dialog div
+ $("#compose_addressbook_dialog").dialog({
+ autoOpen: false,
+ modal: false,
+ resizable: false,
+ width: 285,
+ height: 500,
+ minHeight: 400,
+ buttons: buttons,
+ position: [$(window).width()-400,50]
+ });
+
+ // register the command associated with the toolbar button
+ rcmail.register_command('plugin.compose_addressbook', compose_addressbook_start , true);
+
+ // add the command to the list of compose commands
+ rcmail.env.compose_commands.push('plugin.compose_addressbook');
+
+ // register the callback function
+ rcmail.addEventListener('plugin.compose_addressbook_receive', compose_addressbook_receive);
+
+ // register the callback function for the group expander
+ rcmail.addEventListener('plugin.compose_addressbook_receive_expand', compose_addressbook_receive_expand);
+
+ // create an rc list object
+ if(rcmail.gui_objects.compose_addressbook_list) {
+ rcmail.compose_addressbook_list = new rcube_list_widget(rcmail.gui_objects.compose_addressbook_list, {multiselect:true, draggable:false, keyboard:false});
+
+ // add a listener for double click
+ rcmail.compose_addressbook_list.addEventListener('dblclick', function(o){ compose_address_dblclick(o); });
+
+ // initialize the list
+ rcmail.compose_addressbook_list.init();
+ }
+
+ // each mode of operation has a different key handler
+ if(mode == 'full') {
+ // bind keyevent handler to the search box
+ $('#compose_addressbook_filter').bind('keyup', function(evt) {
+ var search = $('#compose_addressbook_filter').val();
+ var regexp = new RegExp(search, 'i');
+ $('#compose_addressbook_table').find('td').each(function() {
+ var content = $(this).attr('title');
+ if(regexp.test(content)) {
+ $(this).parent().show();
+ } else {
+ $(this).parent().hide();
+ }
+ });
+ });
+ } else {
+ $('#compose_addressbook_filter').bind((bw.safari || bw.ie ? 'keydown' : 'keypress'), function(evt) {
+ var key = rcube_event.get_keycode(evt);
+ if(key == 13) {
+ var search = $('#compose_addressbook_filter').val();
+ $('#compose_addressbook_filter').val('');
+ compose_addressbook_search(search);
+ return false;
+ }
+ });
+ }
+
+ // bind click event to clear function
+ $("#compose_addressbook_searchreset").bind('click', function(e) {
+ $('#compose_addressbook_filter').val('');
+ $('#compose_addressbook_filter').focus();
+ $('#compose_addressbook_table').find('tr').each(function() {
+ $(this).show();
+ });
+ });
+ });
+}
+
+function compose_addressbook_start()
+{
+ compose_addressbook_fetch();
+ $('#compose_addressbook_dialog').dialog('open');
+}
+
+function compose_addressbook_fetch()
+{
+ if(!compose_addressbook_fetched) {
+ lock = rcmail.set_busy(true, 'loading');
+ rcmail.http_post('plugin.get_addressbook', '', lock);
+ compose_addressbook_fetched = true;
+ }
+}
+
+function compose_addressbook_search(search)
+{
+ rcmail.compose_addressbook_list.clear();
+ lock = rcmail.set_busy(true, 'loading');
+ rcmail.http_post('plugin.get_addressbook', '_search='+urlencode(search), lock);
+}
+
+function compose_addressbook_receive(data)
+{
+ var addresses = data.addresses;
+ var name;
+ var email;
+
+ // save the addresses for later use
+ rcmail.compose_addressbook_addresses = addresses;
+
+ for(var j=0; j<addresses.length; j++) {
+ var name = addresses[j].name;
+
+ if(addresses[j].id) {
+ email = 'address group';
+ } else {
+ email = addresses[j].email;
+ }
+ // add address to the row
+ compose_addressbook_add(name,email,j);
+ }
+}
+
+function compose_addressbook_add(address,email,id) {
+ var row = document.createElement('tr');
+ row.id = 'rcmrow'+id;
+ td = document.createElement('td');
+ td.innerHTML = address;
+ td.setAttribute('title', email);
+ td.style.cursor='pointer';
+ row.appendChild(td);
+
+ // add element to the list
+ rcmail.compose_addressbook_list.insert_row(row,0);
+}
+
+function compose_address_dblclick(list) {
+ var group_ids = [];
+ var group_sources = [];
+
+ var id = list.get_single_selection();
+ if(id == null) return;
+
+ var uid = list.rows[id].uid;
+ if(rcmail.compose_addressbook_addresses[uid].id) {
+ group_ids[0] = rcmail.compose_addressbook_addresses[uid].id;
+ group_sources[0] = rcmail.compose_addressbook_addresses[uid].source;
+ compose_addressbook_expand(group_ids, group_sources, '_to');
+ } else {
+ $("[name='_to']").attr('value', $("[name='_to']").val() + rcmail.compose_addressbook_addresses[uid].email+", ");
+ }
+ rcmail.compose_addressbook_list.clear_selection();
+}
+
+function compose_addressbook_add_recipients(target) {
+ var group_ids = [];
+ var group_sources = [];
+
+ if(rcmail.compose_addressbook_list.selection.length == 0) {
+ rcmail.display_message(rcmail.gettext('compose_addressbook_noselect', 'compose_addressbook'), 'error');
+ return;
+ }
+ rcmail.compose_addressbook_list.focused = false;
+ switch(target) {
+ case '_cc':
+ rcmail_ui.show_header_form('cc');
+ break;
+ case '_bcc':
+ rcmail_ui.show_header_form('bcc');
+ break;
+ }
+
+ for (var n=0; n<rcmail.compose_addressbook_list.selection.length; n++) {
+ var id = rcmail.compose_addressbook_list.selection[n];
+ var uid = rcmail.compose_addressbook_list.rows[id].uid;
+ var form = '[name="'+target+'"]';
+
+ if(rcmail.compose_addressbook_addresses[uid].id) {
+ group_ids[group_ids.length] = rcmail.compose_addressbook_addresses[uid].id;
+ group_sources[group_sources.length] = rcmail.compose_addressbook_addresses[uid].source;
+ } else {
+ $('#'+target).attr('value', $('#'+target).val() + rcmail.compose_addressbook_addresses[uid].email+", ");
+ }
+ }
+ compose_addressbook_expand(group_ids, group_sources,target);
+ rcmail.compose_addressbook_list.clear_selection();
+ rcmail.display_message(rcmail.gettext('compose_addressbook_added', 'compose_addressbook'), 'confirmation');
+}
+
+function compose_addressbook_expand(group_ids, group_sources,target) {
+ if(group_ids.length > 0) {
+ lock = rcmail.set_busy(true, 'loading');
+ rcmail.http_request('plugin.expand_groups', '_groupids='+urlencode(group_ids.join(','))+'&_groupsources='+urlencode(group_sources.join(','))+'&_target='+target, lock);
+ }
+}
+
+function compose_addressbook_receive_expand(data) {
+ var form = '[name="'+data.target+'"]';
+
+ for(var j in data.members) {
+ $(form).attr('value', $(form).val() + data.members[j]+", ");
+ }
+}
diff --git a/plugins/compose_addressbook/compose_addressbook.php b/plugins/compose_addressbook/compose_addressbook.php
new file mode 100644
index 000000000..b97be7b75
--- /dev/null
+++ b/plugins/compose_addressbook/compose_addressbook.php
@@ -0,0 +1,180 @@
+<?php
+
+/**
+ * This plugin lets you add addressbook entries from the compose window using the mouse
+ *
+ * @author Cor Bosman (roundcube@wa.ter.net)
+ */
+
+class compose_addressbook extends rcube_plugin
+{
+ public $task = 'mail';
+
+ public function init()
+ {
+ $rcmail = rcmail::get_instance();
+
+ // only run this plugin if the skin is set to classic
+ $skin = $rcmail->config->get('skin');
+ if($skin != 'classic') return;
+
+ $this->require_plugin('jqueryui');
+
+ $this->register_action('plugin.get_addressbook', array($this, 'get_address'));
+ $this->register_action('plugin.expand_groups', array($this, 'expand_groups'));
+
+ if($rcmail->action == 'compose') {
+ $this->compose_addressbook_init();
+ }
+ }
+
+ public function compose_addressbook_init()
+ {
+ $this->add_texts('localization', true);
+
+ $rcmail = rcmail::get_instance();
+
+ $skin_path = $this->local_skin_path();
+
+ // add javascript and stylesheets
+ $this->include_script('compose_addressbook.js?v=2');
+ $this->include_stylesheet("$skin_path/compose_addressbook.css");
+
+ // html for dialog window
+ $table = new html_table(array('id' => 'compose_addressbook_table', 'class' => 'records-table', 'cols' => 1, 'cellspacing' => 0));
+
+ // create div for dialog window
+ $rcmail->output->add_footer(html::div(array('id' => "compose_addressbook_dialog", 'title' => Q($this->gettext('compose_addressbook_title'))),
+ html::div(array('id' => "compose_addressbook_quicksearchbar"),
+ html::img(array('id'=>'compose_addressbook_searchmod','src'=>'/images/icons/glass.png')) .
+ html::tag('input', array('type' => "text", 'class' => 'compose_addressbook_filter','id'=>'compose_addressbook_filter')).
+ html::a(array('id' => 'compose_addressbook_searchreset', 'href'=>'#'),
+ html::img(array('src'=>'/images/icons/reset.gif')))
+ ) .
+ html::div(array('id' => "compose_addressbook_container"),
+ $table->show()
+ )
+ ));
+
+ // add the addressbook button
+ $this->add_button(array(
+ 'command' => 'plugin.compose_addressbook',
+ 'imagepas' => $skin_path.'/compose_addressbook.png',
+ 'imageact' => $skin_path.'/compose_addressbook.png',
+ 'title' => 'compose_addressbook.compose_addressbook_buttontitle',
+ 'id' => 'rcmbtn_compose_addressbook'), 'toolbar');
+
+ $this->load_config();
+ $rcmail->output->set_env('compose_addressbook_mode', $rcmail->config->get('compose_addressbook_mode', 'full'));
+ $rcmail->output->add_gui_object('compose_addressbook_list', 'compose_addressbook_table');
+
+ // add some labels
+ $rcmail->output->add_label('cc', 'bcc', 'to');
+
+ // add list functions
+ $rcmail->output->include_script('list.js');
+
+ }
+
+ // get the addressbook entries and return them to the UI.
+ function get_address() {
+ $contacts = array();
+ $this->load_config();
+ $rcmail = rcmail::get_instance();
+
+ $mode = $rcmail->config->get('compose_addressbook_mode', 'full');
+ $search_mode = $rcmail->config->get('addressbook_search_mode');
+
+ // get the addressbooks, or default to all address sources
+ $book_types = (array) $rcmail->config->get('compose_addressbooks', $rcmail->config->get('autocomplete_addressbooks', array_keys($rcmail->get_address_sources())));
+
+ foreach ($book_types as $id) {
+ $abook = $rcmail->get_address_book($id);
+ $abook->set_pagesize(50000);
+
+ if($mode == 'full') {
+ $result = $abook->list_records();
+ while ($sql_arr = $result->iterate()) {
+ foreach ((array)$abook->get_col_values('email', $sql_arr, true) as $email) {
+ $contact = format_email_recipient($email, $sql_arr['name']);
+ $contacts[] = array('name' => $sql_arr['name'] , 'email' => format_email_recipient($email, $sql_arr['name']));
+ }
+ }
+ $search = null;
+ if($abook->groups) {
+ foreach($abook->list_groups($search) as $group) {
+ $abook->reset();
+ $abook->set_group($group['ID']);
+ $result = $abook->count();
+ if ($result->count) {
+ $contacts[] = array('name' => $group['name'] . ' (' . intval($result->count) . ')', 'id' => $group['ID'], 'source' => $id);
+ }
+ }
+ }
+ } else {
+ $search=trim(get_input_value('_search', RCUBE_INPUT_POST));
+
+ if(!empty($search)) {
+ $result = $abook->search(array('name','email'),$search, $search_mode, true, true, 'email');
+ while ($sql_arr = $result->iterate()) {
+ foreach ((array)$abook->get_col_values('email', $sql_arr, true) as $email) {
+ $contact = format_email_recipient($email, $sql_arr['name']);
+ $contacts[] = array('name' => $sql_arr['name'] , 'email' => format_email_recipient($email, $sql_arr['name']));
+ }
+ }
+ if($abook->groups) {
+ foreach($abook->list_groups($search) as $group) {
+ $abook->reset();
+ $abook->set_group($group['ID']);
+ $result = $abook->count();
+ if ($result->count) {
+ $contacts[] = array('name' => $group['name'] . ' (' . intval($result->count) . ')', 'id' => $group['ID'], 'source' => $id);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ sort($contacts);
+
+ // send the addressbook back to javascript
+ $rcmail->output->command('plugin.compose_addressbook_receive', array('addresses' => $contacts));
+ }
+
+ // expand all the groups that we added
+ function expand_groups() {
+ $rcmail = rcmail::get_instance();
+
+ $group_ids_input=trim(get_input_value('_groupids', RCUBE_INPUT_GET));
+ $group_sources_input=trim(get_input_value('_groupsources', RCUBE_INPUT_GET));
+ $target = trim(get_input_value('_target', RCUBE_INPUT_GET));
+
+ if($group_ids_input == '' || $group_sources_input == '') exit;
+
+ $group_ids = explode(',', $group_ids_input);
+ $group_sources = explode(',', $group_sources_input);
+
+ // create a list of ids per address source
+ for($i=0; $i<count($group_sources);$i++) {
+ $address_sources[$group_sources[$i]][] = $group_ids[$i];
+ }
+
+ // iterate over each address source and get the expanded groups
+ $members = array();
+ foreach($address_sources as $source => $groups) {
+ $abook = $rcmail->get_address_book($source);
+ foreach($groups as $group) {
+ $abook->set_group($group);
+ $abook->set_pagesize(1000);
+ $result = $abook->list_records(array('email','name'));
+ while ($result && ($sql_arr = $result->iterate())) {
+ $email = (array)$sql_arr['email'];
+ $members[] = format_email_recipient($email[0], $sql_arr['name']);
+ }
+ }
+ }
+ $rcmail->output->command('plugin.compose_addressbook_receive_expand', array('members' => array_unique($members), 'target' => $target));
+ }
+}
+?>
diff --git a/plugins/compose_addressbook/config.inc.php.dist b/plugins/compose_addressbook/config.inc.php.dist
new file mode 100644
index 000000000..b2ba8f9c8
--- /dev/null
+++ b/plugins/compose_addressbook/config.inc.php.dist
@@ -0,0 +1,21 @@
+<?php
+
+// which addressbook do we show. this can contain any addressbooks you use, including those set by plugins.
+// by default it's the same as the autocomplete_addressbooks setting.
+
+// $rcmail_config['compose_addressbooks'] = array('ldap');
+// $rcmail_config['compose_addressbooks'] = array('sql', 'static');
+// $rcmail_config['compose_addressbooks'] = array('sql');
+
+// which mode of operation do we use.
+//
+// full - show the full addressbook in the popup window. this should work
+// with most users, and is the default
+//
+// search - popup window starts up empty, and you can search for specific
+// addresses. This is recommended for extremely large addressbooks
+// containing thousands of addresses, and in most LDAP environments.
+
+$rcmail_config['compose_addressbook_mode'] = 'full';
+
+?>
diff --git a/plugins/compose_addressbook/localization/de_DE.inc b/plugins/compose_addressbook/localization/de_DE.inc
new file mode 100644
index 000000000..929a6493d
--- /dev/null
+++ b/plugins/compose_addressbook/localization/de_DE.inc
@@ -0,0 +1,11 @@
+<?php
+
+$labels = array();
+$labels['compose_addressbook_buttontitle'] = 'Adressbuch anzeigen';
+$labels['compose_addressbook_title'] = 'Adressbuch';
+$labels['compose_addressbook_close'] = 'Schließen';
+$labels['compose_addressbook_noselect'] = 'Sie haben keine Adresse ausgewählt';
+$labels['compose_addressbook_added'] = 'Adresse wurde hinzugefügt';
+
+
+?> \ No newline at end of file
diff --git a/plugins/compose_addressbook/localization/en_GB.inc b/plugins/compose_addressbook/localization/en_GB.inc
new file mode 100644
index 000000000..a8078f469
--- /dev/null
+++ b/plugins/compose_addressbook/localization/en_GB.inc
@@ -0,0 +1,10 @@
+<?php
+
+$labels = array();
+$labels['compose_addressbook_buttontitle'] = 'Show Address Book';
+$labels['compose_addressbook_title'] = 'Address Book';
+$labels['compose_addressbook_close'] = 'Close';
+$labels['compose_addressbook_noselect'] = 'You did not select an address';
+$labels['compose_addressbook_added'] = 'Addresses added';
+
+?>
diff --git a/plugins/compose_addressbook/localization/en_US.inc b/plugins/compose_addressbook/localization/en_US.inc
new file mode 100644
index 000000000..a8078f469
--- /dev/null
+++ b/plugins/compose_addressbook/localization/en_US.inc
@@ -0,0 +1,10 @@
+<?php
+
+$labels = array();
+$labels['compose_addressbook_buttontitle'] = 'Show Address Book';
+$labels['compose_addressbook_title'] = 'Address Book';
+$labels['compose_addressbook_close'] = 'Close';
+$labels['compose_addressbook_noselect'] = 'You did not select an address';
+$labels['compose_addressbook_added'] = 'Addresses added';
+
+?>
diff --git a/plugins/compose_addressbook/localization/es_ES.inc b/plugins/compose_addressbook/localization/es_ES.inc
new file mode 100644
index 000000000..2a000f2fa
--- /dev/null
+++ b/plugins/compose_addressbook/localization/es_ES.inc
@@ -0,0 +1,10 @@
+<?php
+
+$labels = array();
+$labels['compose_addressbook_buttontitle'] = 'Mostrar Direcciones';
+$labels['compose_addressbook_title'] = 'Libreta de Direcciones';
+$labels['compose_addressbook_close'] = 'Cerrar';
+$labels['compose_addressbook_noselect'] = 'No has seleccionado ninguna dirección!';
+$labels['compose_addressbook_added'] = 'Dirección añadida';
+
+?>
diff --git a/plugins/compose_addressbook/localization/fr_FR.inc b/plugins/compose_addressbook/localization/fr_FR.inc
new file mode 100644
index 000000000..1f52ffeae
--- /dev/null
+++ b/plugins/compose_addressbook/localization/fr_FR.inc
@@ -0,0 +1,10 @@
+<?php
+
+$labels = array();
+$labels['compose_addressbook_buttontitle'] = 'Afficher le carnet d\'adresse';
+$labels['compose_addressbook_title'] = 'Carnet d\'adresse';
+$labels['compose_addressbook_close'] = 'Fermer';
+$labels['compose_addressbook_noselect'] = 'Vous n\'avez pas sélectionné d\'adresse';
+$labels['compose_addressbook_added'] = 'Adresses ajoutées';
+
+?>
diff --git a/plugins/compose_addressbook/localization/it_IT.inc b/plugins/compose_addressbook/localization/it_IT.inc
new file mode 100644
index 000000000..d1b0c46af
--- /dev/null
+++ b/plugins/compose_addressbook/localization/it_IT.inc
@@ -0,0 +1,10 @@
+<?php
+
+$labels = array();
+$labels['compose_addressbook_buttontitle'] = 'Mostra la rubrica';
+$labels['compose_addressbook_title'] = 'Rubrica';
+$labels['compose_addressbook_close'] = 'Chiudi';
+$labels['compose_addressbook_noselect'] = 'Non hai selezionato nessun indirizzo';
+$labels['compose_addressbook_added'] = 'L\'indirizzo è stato aggiunto';
+
+?>
diff --git a/plugins/compose_addressbook/localization/nl_NL.inc b/plugins/compose_addressbook/localization/nl_NL.inc
new file mode 100644
index 000000000..f5de52ac9
--- /dev/null
+++ b/plugins/compose_addressbook/localization/nl_NL.inc
@@ -0,0 +1,10 @@
+<?php
+
+$labels = array();
+$labels['compose_addressbook_buttontitle'] = 'Voeg adres uit adresboek toe';
+$labels['compose_addressbook_title'] = 'Adres boek';
+$labels['compose_addressbook_close'] = 'Sluiten';
+$labels['compose_addressbook_noselect'] = 'Er is geen contact adres geselecteerd';
+$labels['compose_addressbook_added'] = 'Adressen zijn toegevoegd';
+
+?>
diff --git a/plugins/compose_addressbook/localization/pl_PL.inc b/plugins/compose_addressbook/localization/pl_PL.inc
new file mode 100644
index 000000000..eb95e4225
--- /dev/null
+++ b/plugins/compose_addressbook/localization/pl_PL.inc
@@ -0,0 +1,10 @@
+<?php
+
+$labels = array();
+$labels['compose_addressbook_buttontitle'] = 'Zobacz książkę adresową';
+$labels['compose_addressbook_title'] = 'Książka adresowa';
+$labels['compose_addressbook_close'] = 'Zamknij';
+$labels['compose_addressbook_noselect'] = 'Zaznacz jakiś adres';
+$labels['compose_addressbook_added'] = 'Adres został dodany';
+
+?>
diff --git a/plugins/compose_addressbook/localization/sv_SE.inc b/plugins/compose_addressbook/localization/sv_SE.inc
new file mode 100644
index 000000000..6e6d49f36
--- /dev/null
+++ b/plugins/compose_addressbook/localization/sv_SE.inc
@@ -0,0 +1,10 @@
+<?php
+
+$labels = array();
+$labels['compose_addressbook_buttontitle'] = 'Visa adressbok';
+$labels['compose_addressbook_title'] = 'Adressbok';
+$labels['compose_addressbook_close'] = 'Stäng';
+$labels['compose_addressbook_noselect'] = 'Ingen adress valdes';
+$labels['compose_addressbook_added'] = 'Adress tillagd';
+
+?>
diff --git a/plugins/compose_addressbook/localization/zh_TW.inc b/plugins/compose_addressbook/localization/zh_TW.inc
new file mode 100644
index 000000000..1be7b614d
--- /dev/null
+++ b/plugins/compose_addressbook/localization/zh_TW.inc
@@ -0,0 +1,10 @@
+<?php
+
+$labels = array();
+$labels['compose_addressbook_buttontitle'] = '顯示地址簿';
+$labels['compose_addressbook_title'] = '地址簿';
+$labels['compose_addressbook_close'] = '關閉';
+$labels['compose_addressbook_noselect'] = '沒有選擇電郵地址';
+$labels['compose_addressbook_added'] = '已加入電郵地址';
+
+?> \ No newline at end of file
diff --git a/plugins/compose_addressbook/package.xml b/plugins/compose_addressbook/package.xml
new file mode 100644
index 000000000..cc22b4c9b
--- /dev/null
+++ b/plugins/compose_addressbook/package.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<package xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" packagerversion="1.9.0" version="2.0" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0
+ http://pear.php.net/dtd/tasks-1.0.xsd
+ http://pear.php.net/dtd/package-2.0
+ http://pear.php.net/dtd/package-2.0.xsd">
+ <name>compose_addressbook</name>
+ <lead>
+ <name>Cor Bosman</name>
+ <user>cor</user>
+ <email>cor@roundcu.be</email>
+ <active>yes</active>
+ </lead>
+ <uri>https://github.com/corbosman/compose_addressbook</uri>
+ <version>
+ <release>8.0</release>
+ </version>
+ <license uri="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPLv2</license>
+</package>
diff --git a/plugins/compose_addressbook/skins/classic/compose_addressbook.css b/plugins/compose_addressbook/skins/classic/compose_addressbook.css
new file mode 100644
index 000000000..f8ec665d1
--- /dev/null
+++ b/plugins/compose_addressbook/skins/classic/compose_addressbook.css
@@ -0,0 +1,83 @@
+#compose_addressbook_dialog {
+ display: none;
+ background-color: #FAFAFA;
+ color: #333;
+ padding: 5px 0 0 0;
+ overflow: hidden;
+}
+
+#compose_addressbook_dialog .ui-dialog {
+ padding: 0;
+}
+
+#compose_addressbook_container {
+ height: 376px;
+ overflow: auto;
+ overflow-x: hidden;
+ border-top: 1px solid #AAAAAA;
+ position: relative;
+ top: 30px;
+}
+
+#compose_addressbook_dialog table {
+ width: 100%;
+ overflow: hidden;
+}
+
+#compose_addressbook_quicksearchbar
+{
+ position: absolute;
+ left: 60px;
+ width: 182px;
+ height: 20px;
+ text-align: right;
+ background: url('searchfield.gif') top left no-repeat;
+}
+
+#compose_addressbook_searchreset
+{
+ position: absolute;
+ top: 3px;
+ right: 4px;
+ text-decoration: none;
+}
+
+#compose_addressbook_searchmod
+{
+ position: absolute;
+ top: 3px;
+ right: 160px;
+}
+
+#compose_addressbook_quicksearchbar img
+{
+ vertical-align: middle;
+}
+
+#compose_addressbook_filter
+{
+ margin-right: 4px;
+ margin-bottom: 5px;
+ position: absolute;
+ top: 2px;
+ left: 24px;
+ width: 140px;
+ height: 15px;
+ font-size: 11px;
+ padding: 0px;
+ border: none;
+}
+
+#compose_addressbook_dialog input {
+ outline: none;
+ border: none !important;
+}
+
+#compose_addressbook_filter[type=text]:focus {
+ outline: 0 none;
+}
+
+.ui-dialog-buttonpane button {
+ font-size: 10px !important;
+ width: 85px !important;
+} \ No newline at end of file
diff --git a/plugins/compose_addressbook/skins/classic/compose_addressbook.png b/plugins/compose_addressbook/skins/classic/compose_addressbook.png
new file mode 100644
index 000000000..e58e4dddc
--- /dev/null
+++ b/plugins/compose_addressbook/skins/classic/compose_addressbook.png
Binary files differ
diff --git a/plugins/compose_addressbook/skins/classic/searchfield.gif b/plugins/compose_addressbook/skins/classic/searchfield.gif
new file mode 100644
index 000000000..756a17e47
--- /dev/null
+++ b/plugins/compose_addressbook/skins/classic/searchfield.gif
Binary files differ
diff --git a/plugins/compose_addressbook/skins/classic/smoothness/images/ui-anim_basic_16x16.gif b/plugins/compose_addressbook/skins/classic/smoothness/images/ui-anim_basic_16x16.gif
new file mode 100644
index 000000000..085ccaeca
--- /dev/null
+++ b/plugins/compose_addressbook/skins/classic/smoothness/images/ui-anim_basic_16x16.gif
Binary files differ
diff --git a/plugins/compose_addressbook/skins/classic/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png b/plugins/compose_addressbook/skins/classic/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png
new file mode 100644
index 000000000..5b5dab2ab
--- /dev/null
+++ b/plugins/compose_addressbook/skins/classic/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png
Binary files differ
diff --git a/plugins/compose_addressbook/skins/classic/smoothness/images/ui-bg_flat_75_ffffff_40x100.png b/plugins/compose_addressbook/skins/classic/smoothness/images/ui-bg_flat_75_ffffff_40x100.png
new file mode 100644
index 000000000..ac8b229af
--- /dev/null
+++ b/plugins/compose_addressbook/skins/classic/smoothness/images/ui-bg_flat_75_ffffff_40x100.png
Binary files differ
diff --git a/plugins/compose_addressbook/skins/classic/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png b/plugins/compose_addressbook/skins/classic/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png
new file mode 100644
index 000000000..ad3d6346e
--- /dev/null
+++ b/plugins/compose_addressbook/skins/classic/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png
Binary files differ
diff --git a/plugins/compose_addressbook/skins/classic/smoothness/images/ui-bg_glass_65_ffffff_1x400.png b/plugins/compose_addressbook/skins/classic/smoothness/images/ui-bg_glass_65_ffffff_1x400.png
new file mode 100644
index 000000000..42ccba269
--- /dev/null
+++ b/plugins/compose_addressbook/skins/classic/smoothness/images/ui-bg_glass_65_ffffff_1x400.png
Binary files differ
diff --git a/plugins/compose_addressbook/skins/classic/smoothness/images/ui-bg_glass_75_dadada_1x400.png b/plugins/compose_addressbook/skins/classic/smoothness/images/ui-bg_glass_75_dadada_1x400.png
new file mode 100644
index 000000000..5a46b47cb
--- /dev/null
+++ b/plugins/compose_addressbook/skins/classic/smoothness/images/ui-bg_glass_75_dadada_1x400.png
Binary files differ
diff --git a/plugins/compose_addressbook/skins/classic/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png b/plugins/compose_addressbook/skins/classic/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png
new file mode 100644
index 000000000..86c2baa65
--- /dev/null
+++ b/plugins/compose_addressbook/skins/classic/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png
Binary files differ
diff --git a/plugins/compose_addressbook/skins/classic/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png b/plugins/compose_addressbook/skins/classic/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png
new file mode 100644
index 000000000..4443fdc1a
--- /dev/null
+++ b/plugins/compose_addressbook/skins/classic/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png
Binary files differ
diff --git a/plugins/compose_addressbook/skins/classic/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png b/plugins/compose_addressbook/skins/classic/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png
new file mode 100644
index 000000000..7c9fa6c6e
--- /dev/null
+++ b/plugins/compose_addressbook/skins/classic/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png
Binary files differ
diff --git a/plugins/compose_addressbook/skins/classic/smoothness/images/ui-icons_222222_256x240.png b/plugins/compose_addressbook/skins/classic/smoothness/images/ui-icons_222222_256x240.png
new file mode 100644
index 000000000..b273ff111
--- /dev/null
+++ b/plugins/compose_addressbook/skins/classic/smoothness/images/ui-icons_222222_256x240.png
Binary files differ
diff --git a/plugins/compose_addressbook/skins/classic/smoothness/images/ui-icons_2e83ff_256x240.png b/plugins/compose_addressbook/skins/classic/smoothness/images/ui-icons_2e83ff_256x240.png
new file mode 100644
index 000000000..09d1cdc85
--- /dev/null
+++ b/plugins/compose_addressbook/skins/classic/smoothness/images/ui-icons_2e83ff_256x240.png
Binary files differ
diff --git a/plugins/compose_addressbook/skins/classic/smoothness/images/ui-icons_454545_256x240.png b/plugins/compose_addressbook/skins/classic/smoothness/images/ui-icons_454545_256x240.png
new file mode 100644
index 000000000..59bd45b90
--- /dev/null
+++ b/plugins/compose_addressbook/skins/classic/smoothness/images/ui-icons_454545_256x240.png
Binary files differ
diff --git a/plugins/compose_addressbook/skins/classic/smoothness/images/ui-icons_888888_256x240.png b/plugins/compose_addressbook/skins/classic/smoothness/images/ui-icons_888888_256x240.png
new file mode 100644
index 000000000..6d02426c1
--- /dev/null
+++ b/plugins/compose_addressbook/skins/classic/smoothness/images/ui-icons_888888_256x240.png
Binary files differ
diff --git a/plugins/compose_addressbook/skins/classic/smoothness/images/ui-icons_cd0a0a_256x240.png b/plugins/compose_addressbook/skins/classic/smoothness/images/ui-icons_cd0a0a_256x240.png
new file mode 100644
index 000000000..2ab019b73
--- /dev/null
+++ b/plugins/compose_addressbook/skins/classic/smoothness/images/ui-icons_cd0a0a_256x240.png
Binary files differ
diff --git a/plugins/compose_addressbook/skins/classic/smoothness/jquery-ui-1.8.2.custom.css b/plugins/compose_addressbook/skins/classic/smoothness/jquery-ui-1.8.2.custom.css
new file mode 100644
index 000000000..401eb1d15
--- /dev/null
+++ b/plugins/compose_addressbook/skins/classic/smoothness/jquery-ui-1.8.2.custom.css
@@ -0,0 +1,345 @@
+/*
+* jQuery UI CSS Framework
+* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
+* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
+*/
+
+/* Layout helpers
+----------------------------------*/
+.ui-helper-hidden { display: none; }
+.ui-helper-hidden-accessible { position: absolute; left: -99999999px; }
+.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
+.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
+.ui-helper-clearfix { display: inline-block; }
+/* required comment for clearfix to work in Opera \*/
+* html .ui-helper-clearfix { height:1%; }
+.ui-helper-clearfix { display:block; }
+/* end clearfix */
+.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
+
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-disabled { cursor: default !important; }
+
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Overlays */
+.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
+
+
+/*
+* jQuery UI CSS Framework
+* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
+* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
+* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana,Arial,sans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=03_highlight_soft.png&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=01_flat.png&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=02_glass.png&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px
+*/
+
+
+/* Component containers
+----------------------------------*/
+.ui-widget { font-family: Verdana,Arial,sans-serif; font-size: 1.1em; }
+.ui-widget .ui-widget { font-size: 1em; }
+.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif; font-size: 1em; }
+.ui-widget-content { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; color: #222222; }
+.ui-widget-content a { color: #222222; }
+.ui-widget-header { border: 1px solid #aaaaaa; background: #cccccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x; color: #222222; font-weight: bold; }
+.ui-widget-header a { color: #222222; }
+
+/* Interaction states
+----------------------------------*/
+.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #d3d3d3; background: #e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #555555; }
+.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555; text-decoration: none; }
+.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #999999; background: #dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; }
+.ui-state-hover a, .ui-state-hover a:hover { color: #212121; text-decoration: none; }
+.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; }
+.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121; text-decoration: none; }
+.ui-widget :active { outline: none; }
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fcefa1; background: #fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x; color: #363636; }
+.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; }
+.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; }
+.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; }
+.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; }
+.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
+.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
+.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); }
+.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
+.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
+.ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png); }
+.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); }
+.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); }
+.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); }
+.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); }
+
+/* positioning */
+.ui-icon-carat-1-n { background-position: 0 0; }
+.ui-icon-carat-1-ne { background-position: -16px 0; }
+.ui-icon-carat-1-e { background-position: -32px 0; }
+.ui-icon-carat-1-se { background-position: -48px 0; }
+.ui-icon-carat-1-s { background-position: -64px 0; }
+.ui-icon-carat-1-sw { background-position: -80px 0; }
+.ui-icon-carat-1-w { background-position: -96px 0; }
+.ui-icon-carat-1-nw { background-position: -112px 0; }
+.ui-icon-carat-2-n-s { background-position: -128px 0; }
+.ui-icon-carat-2-e-w { background-position: -144px 0; }
+.ui-icon-triangle-1-n { background-position: 0 -16px; }
+.ui-icon-triangle-1-ne { background-position: -16px -16px; }
+.ui-icon-triangle-1-e { background-position: -32px -16px; }
+.ui-icon-triangle-1-se { background-position: -48px -16px; }
+.ui-icon-triangle-1-s { background-position: -64px -16px; }
+.ui-icon-triangle-1-sw { background-position: -80px -16px; }
+.ui-icon-triangle-1-w { background-position: -96px -16px; }
+.ui-icon-triangle-1-nw { background-position: -112px -16px; }
+.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
+.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
+.ui-icon-arrow-1-n { background-position: 0 -32px; }
+.ui-icon-arrow-1-ne { background-position: -16px -32px; }
+.ui-icon-arrow-1-e { background-position: -32px -32px; }
+.ui-icon-arrow-1-se { background-position: -48px -32px; }
+.ui-icon-arrow-1-s { background-position: -64px -32px; }
+.ui-icon-arrow-1-sw { background-position: -80px -32px; }
+.ui-icon-arrow-1-w { background-position: -96px -32px; }
+.ui-icon-arrow-1-nw { background-position: -112px -32px; }
+.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
+.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
+.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
+.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
+.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
+.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
+.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
+.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
+.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
+.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
+.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
+.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
+.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
+.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
+.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
+.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
+.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
+.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
+.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
+.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
+.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
+.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
+.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
+.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
+.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
+.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
+.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
+.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
+.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
+.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
+.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
+.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
+.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
+.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
+.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
+.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
+.ui-icon-arrow-4 { background-position: 0 -80px; }
+.ui-icon-arrow-4-diag { background-position: -16px -80px; }
+.ui-icon-extlink { background-position: -32px -80px; }
+.ui-icon-newwin { background-position: -48px -80px; }
+.ui-icon-refresh { background-position: -64px -80px; }
+.ui-icon-shuffle { background-position: -80px -80px; }
+.ui-icon-transfer-e-w { background-position: -96px -80px; }
+.ui-icon-transferthick-e-w { background-position: -112px -80px; }
+.ui-icon-folder-collapsed { background-position: 0 -96px; }
+.ui-icon-folder-open { background-position: -16px -96px; }
+.ui-icon-document { background-position: -32px -96px; }
+.ui-icon-document-b { background-position: -48px -96px; }
+.ui-icon-note { background-position: -64px -96px; }
+.ui-icon-mail-closed { background-position: -80px -96px; }
+.ui-icon-mail-open { background-position: -96px -96px; }
+.ui-icon-suitcase { background-position: -112px -96px; }
+.ui-icon-comment { background-position: -128px -96px; }
+.ui-icon-person { background-position: -144px -96px; }
+.ui-icon-print { background-position: -160px -96px; }
+.ui-icon-trash { background-position: -176px -96px; }
+.ui-icon-locked { background-position: -192px -96px; }
+.ui-icon-unlocked { background-position: -208px -96px; }
+.ui-icon-bookmark { background-position: -224px -96px; }
+.ui-icon-tag { background-position: -240px -96px; }
+.ui-icon-home { background-position: 0 -112px; }
+.ui-icon-flag { background-position: -16px -112px; }
+.ui-icon-calendar { background-position: -32px -112px; }
+.ui-icon-cart { background-position: -48px -112px; }
+.ui-icon-pencil { background-position: -64px -112px; }
+.ui-icon-clock { background-position: -80px -112px; }
+.ui-icon-disk { background-position: -96px -112px; }
+.ui-icon-calculator { background-position: -112px -112px; }
+.ui-icon-zoomin { background-position: -128px -112px; }
+.ui-icon-zoomout { background-position: -144px -112px; }
+.ui-icon-search { background-position: -160px -112px; }
+.ui-icon-wrench { background-position: -176px -112px; }
+.ui-icon-gear { background-position: -192px -112px; }
+.ui-icon-heart { background-position: -208px -112px; }
+.ui-icon-star { background-position: -224px -112px; }
+.ui-icon-link { background-position: -240px -112px; }
+.ui-icon-cancel { background-position: 0 -128px; }
+.ui-icon-plus { background-position: -16px -128px; }
+.ui-icon-plusthick { background-position: -32px -128px; }
+.ui-icon-minus { background-position: -48px -128px; }
+.ui-icon-minusthick { background-position: -64px -128px; }
+.ui-icon-close { background-position: -80px -128px; }
+.ui-icon-closethick { background-position: -96px -128px; }
+.ui-icon-key { background-position: -112px -128px; }
+.ui-icon-lightbulb { background-position: -128px -128px; }
+.ui-icon-scissors { background-position: -144px -128px; }
+.ui-icon-clipboard { background-position: -160px -128px; }
+.ui-icon-copy { background-position: -176px -128px; }
+.ui-icon-contact { background-position: -192px -128px; }
+.ui-icon-image { background-position: -208px -128px; }
+.ui-icon-video { background-position: -224px -128px; }
+.ui-icon-script { background-position: -240px -128px; }
+.ui-icon-alert { background-position: 0 -144px; }
+.ui-icon-info { background-position: -16px -144px; }
+.ui-icon-notice { background-position: -32px -144px; }
+.ui-icon-help { background-position: -48px -144px; }
+.ui-icon-check { background-position: -64px -144px; }
+.ui-icon-bullet { background-position: -80px -144px; }
+.ui-icon-radio-off { background-position: -96px -144px; }
+.ui-icon-radio-on { background-position: -112px -144px; }
+.ui-icon-pin-w { background-position: -128px -144px; }
+.ui-icon-pin-s { background-position: -144px -144px; }
+.ui-icon-play { background-position: 0 -160px; }
+.ui-icon-pause { background-position: -16px -160px; }
+.ui-icon-seek-next { background-position: -32px -160px; }
+.ui-icon-seek-prev { background-position: -48px -160px; }
+.ui-icon-seek-end { background-position: -64px -160px; }
+.ui-icon-seek-start { background-position: -80px -160px; }
+/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
+.ui-icon-seek-first { background-position: -80px -160px; }
+.ui-icon-stop { background-position: -96px -160px; }
+.ui-icon-eject { background-position: -112px -160px; }
+.ui-icon-volume-off { background-position: -128px -160px; }
+.ui-icon-volume-on { background-position: -144px -160px; }
+.ui-icon-power { background-position: 0 -176px; }
+.ui-icon-signal-diag { background-position: -16px -176px; }
+.ui-icon-signal { background-position: -32px -176px; }
+.ui-icon-battery-0 { background-position: -48px -176px; }
+.ui-icon-battery-1 { background-position: -64px -176px; }
+.ui-icon-battery-2 { background-position: -80px -176px; }
+.ui-icon-battery-3 { background-position: -96px -176px; }
+.ui-icon-circle-plus { background-position: 0 -192px; }
+.ui-icon-circle-minus { background-position: -16px -192px; }
+.ui-icon-circle-close { background-position: -32px -192px; }
+.ui-icon-circle-triangle-e { background-position: -48px -192px; }
+.ui-icon-circle-triangle-s { background-position: -64px -192px; }
+.ui-icon-circle-triangle-w { background-position: -80px -192px; }
+.ui-icon-circle-triangle-n { background-position: -96px -192px; }
+.ui-icon-circle-arrow-e { background-position: -112px -192px; }
+.ui-icon-circle-arrow-s { background-position: -128px -192px; }
+.ui-icon-circle-arrow-w { background-position: -144px -192px; }
+.ui-icon-circle-arrow-n { background-position: -160px -192px; }
+.ui-icon-circle-zoomin { background-position: -176px -192px; }
+.ui-icon-circle-zoomout { background-position: -192px -192px; }
+.ui-icon-circle-check { background-position: -208px -192px; }
+.ui-icon-circlesmall-plus { background-position: 0 -208px; }
+.ui-icon-circlesmall-minus { background-position: -16px -208px; }
+.ui-icon-circlesmall-close { background-position: -32px -208px; }
+.ui-icon-squaresmall-plus { background-position: -48px -208px; }
+.ui-icon-squaresmall-minus { background-position: -64px -208px; }
+.ui-icon-squaresmall-close { background-position: -80px -208px; }
+.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
+.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
+.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
+.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
+.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
+.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Corner radius */
+.ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; }
+.ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; }
+.ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; }
+.ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
+.ui-corner-top { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; }
+.ui-corner-bottom { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
+.ui-corner-right { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
+.ui-corner-left { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; }
+.ui-corner-all { -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; }
+
+/* Overlays */
+.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); }
+.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/* Resizable
+----------------------------------*/
+.ui-resizable { position: relative;}
+.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;}
+.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
+.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }
+.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }
+.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; }
+.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; }
+.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
+.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
+.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
+.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* Button
+----------------------------------*/
+
+.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */
+.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */
+button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */
+.ui-button-icons-only { width: 3.4em; }
+button.ui-button-icons-only { width: 3.7em; }
+
+/*button text element */
+.ui-button .ui-button-text { display: block; line-height: 1.4; }
+.ui-button-text-only .ui-button-text { padding: .4em 1em; }
+.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; }
+.ui-button-text-icon .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; }
+.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; }
+/* no icon support for input elements, provide padding by default */
+input.ui-button { padding: .4em 1em; }
+
+/*button icon element(s) */
+.ui-button-icon-only .ui-icon, .ui-button-text-icon .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; }
+.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; }
+.ui-button-text-icon .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; }
+.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
+
+/*button sets*/
+.ui-buttonset { margin-right: 7px; }
+.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; }
+
+/* workarounds */
+button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */
+
+
+
+
+
+/* Dialog
+----------------------------------*/
+.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; }
+.ui-dialog .ui-dialog-titlebar { padding: .5em 1em .3em; position: relative; }
+.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .2em 0; }
+.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
+.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
+.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
+.ui-dialog .ui-dialog-content { border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
+.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
+.ui-dialog .ui-dialog-buttonpane button { float: right; margin: .5em .4em .5em 0; cursor: pointer; padding: .2em .6em .3em .6em; line-height: 1.4em; width:auto; overflow:visible; }
+.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
+.ui-draggable .ui-dialog-titlebar { cursor: move; }
diff --git a/plugins/contextmenu/contextmenu.js b/plugins/contextmenu/contextmenu.js
new file mode 100644
index 000000000..6d83f1fbe
--- /dev/null
+++ b/plugins/contextmenu/contextmenu.js
@@ -0,0 +1,595 @@
+/**
+ * ContextMenu plugin script
+ */
+
+rcube_webmail.prototype.contextmenu_command_handlers = new Object();
+rcube_webmail.prototype.contextmenu_disable_multi = new Array('#reply','#reply-all','#reply-list','#forward-inline','#print','#edit','#viewsource','#download','#open','#edit');
+
+function rcm_contextmenu_update() {
+ //if (!rcmail.env.flag_for_deletion && rcmail.env.trash_mailbox && rcmail.env.mailbox != rcmail.env.trash_mailbox)
+ // $("#rcm_delete").html('<span>' + rcmail.gettext('movemessagetotrash') + '</span>');
+ //else
+ // $("#rcm_delete").html('<span>' + rcmail.gettext('deletemessage') + '</span>');
+}
+
+function rcm_contextmenu_init(row) {
+ $("#" + row).contextMenu({
+ menu: 'rcmContextMenu',
+ submenu_delay: 400
+ },
+ function(command, el, pos) {
+ var matches = String($(el).attr('id')).match(/rcmrow([a-z0-9\-_=]+)/i);
+ if ($(el) && matches) {
+ var prev_uid = rcmail.env.uid;
+ if (rcmail.message_list.selection.length <= 1 || !rcmail.message_list.in_selection(matches[1]))
+ rcmail.env.uid = matches[1];
+
+ // fix command string in IE
+ if (command.indexOf("#") > 0)
+ command = command.substr(command.indexOf("#") + 1);
+
+ // enable the required command
+ cmd = (command == 'read' || command == 'unread' || command == 'flagged' || command == 'unflagged') ? 'mark' : command;
+ var prev_command = rcmail.commands[cmd];
+ rcmail.enable_command(cmd, true);
+
+ // process external commands
+ if (typeof rcmail.contextmenu_command_handlers[command] == 'function') {
+ rcmail.contextmenu_command_handlers[command](command, el, pos);
+ }
+ else if (typeof rcmail.contextmenu_command_handlers[command] == 'string') {
+ window[rcmail.contextmenu_command_handlers[command]](command, el, pos);
+ }
+ else {
+ switch (command) {
+ case 'read':
+ case 'unread':
+ case 'flagged':
+ case 'unflagged':
+ rcmail.command('mark', command, $(el));
+ break;
+ case 'reply':
+ case 'reply-all':
+ case 'reply-list':
+ case 'forward-inline':
+ case 'forward-attachment':
+ case 'print':
+ case 'download':
+ case 'viewsource':
+ rcmail.command(command, '', $(el));
+ break;
+ case 'edit':
+ rcmail.command(command, 'new', $(el));
+ break;
+ case 'open':
+ rcmail.command(command, '', rcube_find_object('rcm_open'));
+ rcmail.sourcewin = window.open(rcube_find_object('rcm_open').href);
+ if (rcmail.sourcewin)
+ window.setTimeout(function() { rcmail.sourcewin.focus(); }, 20);
+
+ rcube_find_object('rcm_open').href = '#open';
+ break;
+ case 'delete':
+ case 'moveto':
+ if (command == 'moveto' && rcmail.env.rcm_destfolder == rcmail.env.mailbox)
+ return;
+
+ var prev_sel = null;
+
+ // also select childs of (collapsed) threads
+ if (rcmail.env.uid) {
+ if (!rcmail.message_list.in_selection(rcmail.env.uid)) {
+ prev_sel = rcmail.message_list.get_selection();
+ rcmail.message_list.select_row(rcmail.env.uid);
+ }
+
+ if (rcmail.message_list.rows[rcmail.env.uid].has_children && !rcmail.message_list.rows[rcmail.env.uid].expanded)
+ rcmail.message_list.select_childs(rcmail.env.uid);
+
+ rcmail.env.uid = null;
+ }
+
+ rcmail.command(command, rcmail.env.rcm_destfolder, $(el));
+
+ if (prev_sel) {
+ rcmail.message_list.clear_selection();
+
+ for (var i in prev_sel)
+ rcmail.message_list.select_row(prev_sel[i], CONTROL_KEY);
+ }
+
+ delete rcmail.env.rcm_destfolder;
+ break;
+ }
+ }
+
+ rcmail.enable_command(cmd, prev_command);
+ rcmail.env.uid = prev_uid;
+ }
+ });
+}
+
+function rcm_set_dest_folder(folder) {
+ rcmail.env.rcm_destfolder = folder;
+}
+
+function rcm_contextmenu_register_command(command, callback, label, pos, sep, multi, newSub, menu, liclass) {
+ if (!menu)
+ menu = $('#rcmContextMenu');
+
+ if (!liclass)
+ liclass = command;
+
+ if (typeof label != 'string') {
+ var menuItem = label.children('li');
+ }
+ else {
+ var menuItem = $('<li>').addClass(liclass);
+ $('<a>').attr('href', '#' + command).addClass('active').html('<span>' + rcmail.gettext(label) + '</span>').appendTo(menuItem);
+ }
+
+ rcmail.contextmenu_command_handlers[command] = callback;
+
+ if (pos && menu.children('li.' + pos) && newSub) {
+ subMenu = menu.children('li.' + pos);
+ subMenu.addClass('submenu');
+
+ var mainLink = null;
+ if (subMenu.children('a') && !subMenu.hasClass('sublink')) {
+ subMenu.addClass('sublink');
+
+ var mainLink = $('<li>').addClass(pos);
+ subMenu.children('a').clone().appendTo(mainLink)
+ subMenu.children('a').addClass('mainlink');
+ }
+
+ var newMenu = $('<ul>').addClass('toolbarmenu').appendTo(subMenu);
+
+ if (mainLink)
+ newMenu.append(mainLink);
+
+ newMenu.append(menuItem);
+ }
+ else if (pos && menu.children('li.' + pos)) {
+ menu.children('li.' + pos).before(menuItem);
+ }
+ else {
+ menu.append(menuItem);
+ }
+
+ if (sep == 'before')
+ menuItem.addClass('separator_above');
+ else if (sep == 'after')
+ menuItem.addClass('separator_below');
+
+ if (!multi)
+ rcmail.contextmenu_disable_multi[rcmail.contextmenu_disable_multi.length] = '#' + command;
+}
+
+function rcm_foldermenu_init() {
+ $("#mailboxlist li").contextMenu({
+ menu: 'rcmFolderMenu'
+ },
+ function(command, el, pos) {
+ var matches = String($(el).children('a').attr('onclick')).match(/.*rcmail.command\(["']list["'],\s*["']([^"']*)["'],\s*this\).*/i);
+ if ($(el) && matches) {
+ var mailbox = matches[1];
+ var messagecount = 0;
+
+ if (command == 'readfolder' || command == 'expunge' || command == 'purge') {
+ if (mailbox == rcmail.env.mailbox) {
+ messagecount = rcmail.env.messagecount;
+ }
+ else if (rcmail.env.unread_counts[mailbox] == 0) {
+ var lock = rcmail.set_busy(true, 'loading');
+
+ querystring = '_mbox=' + urlencode(mailbox);
+ querystring += (querystring ? '&' : '') + '_remote=1';
+ var url = rcmail.env.comm_path + '&_action=' + 'plugin.contextmenu.messagecount' + '&' + querystring
+
+ // send request
+ console.log('HTTP POST: ' + url);
+
+ jQuery.ajax({
+ url: url,
+ dataType: "json",
+ success: function(response) { messagecount = response.env.messagecount; },
+ async: false
+ });
+
+ rcmail.set_busy(false, null, lock);
+ }
+
+ if (rcmail.env.unread_counts[mailbox] == 0 && messagecount == 0) {
+ rcmail.display_message(rcmail.get_label('nomessagesfound'), 'notice');
+ return false;
+ }
+ }
+
+ // fix command string in IE
+ if (command.indexOf("#") > 0)
+ command = command.substr(command.indexOf("#") + 1);
+
+ // enable the required command
+ var prev_command = rcmail.commands[command];
+ rcmail.enable_command(command, true);
+
+ // process external commands
+ if (typeof rcmail.contextmenu_command_handlers[command] == 'function') {
+ rcmail.contextmenu_command_handlers[command](command, el, pos);
+ }
+ else if (typeof rcmail.contextmenu_command_handlers[command] == 'string') {
+ window[rcmail.contextmenu_command_handlers[command]](command, el, pos);
+ }
+ else {
+ switch (command) {
+ case 'readfolder':
+ var lock = rcmail.set_busy(true, 'loading');
+ rcmail.http_request('plugin.contextmenu.readfolder', '_mbox=' + urlencode(mailbox) + '&_cur=' + rcmail.env.mailbox + '&_oact=' + rcmail.env.action, lock);
+ break;
+ case 'expunge':
+ rcmail.expunge_mailbox(mailbox);
+ break;
+ case 'purge':
+ rcmail.purge_mailbox(mailbox);
+ break;
+ case 'collapseall':
+ case 'expandall':
+ targetdiv = (command == 'collapseall') ? 'expanded' : 'collapsed';
+ $("#mailboxlist div." + targetdiv).each( function() {
+ var el = $(this);
+ var matches = String($(el).attr('onclick')).match(/.*rcmail.command\(["']collapse-folder["'],\s*["']([^"']*)["']\).*/i);
+ rcmail.collapse_folder(matches[1]);
+ });
+ break;
+ case 'openfolder':
+ rcube_find_object('rcm_openfolder').href = '?_task=mail&_mbox='+urlencode(mailbox);
+ rcmail.sourcewin = window.open(rcube_find_object('rcm_openfolder').href);
+ if (rcmail.sourcewin)
+ window.setTimeout(function() { rcmail.sourcewin.focus(); }, 20);
+
+ rcube_find_object('rcm_openfolder').href = '#openfolder';
+ break;
+ }
+ }
+
+ rcmail.enable_command(command, prev_command);
+ }
+ });
+}
+
+function rcm_update_options(el) {
+ if (el.hasClass('message')) {
+ $('#rcmContextMenu').disableContextMenuItems('#reply-list');
+ var matches = String($(el).attr('id')).match(/rcmrow([a-z0-9\-_=]+)/i);
+ if ($(el) && matches) {
+ if (rcmail.message_list.selection.length > 1 && rcmail.message_list.in_selection(matches[1])) {
+ $('#rcmContextMenu').disableContextMenuItems(rcmail.contextmenu_disable_multi.join(','));
+ }
+ else {
+ $('#rcmContextMenu').enableContextMenuItems(rcmail.contextmenu_disable_multi.join(','));
+
+ var msg = rcmail.env.messages[matches[1]];
+ if (!msg.ml)
+ $('#rcmContextMenu').disableContextMenuItems('#reply-list');
+ }
+ }
+ }
+ else if (el.hasClass('mailbox')) {
+ $('#rcmFolderMenu').disableContextMenuItems('#readfolder,#purge,#collapseall,#expandall');
+ var matches = String($(el).children('a').attr('onclick')).match(/.*rcmail.command\(["']list["'],\s*["']([^"']*)["'],\s*this\).*/i);
+ if ($(el) && matches) {
+ var mailbox = matches[1];
+
+ if (rcmail.env.unread_counts[mailbox] > 0)
+ $('#rcmFolderMenu').enableContextMenuItems('#readfolder');
+
+ if (mailbox == rcmail.env.trash_mailbox || mailbox == rcmail.env.junk_mailbox
+ || mailbox.match('^' + RegExp.escape(rcmail.env.trash_mailbox) + RegExp.escape(rcmail.env.delimiter))
+ || mailbox.match('^' + RegExp.escape(rcmail.env.junk_mailbox) + RegExp.escape(rcmail.env.delimiter)))
+ $('#rcmFolderMenu').enableContextMenuItems('#purge');
+
+ if ($("#mailboxlist div.expanded").length > 0)
+ $('#rcmFolderMenu').enableContextMenuItems('#collapseall');
+
+ if ($("#mailboxlist div.collapsed").length > 0)
+ $('#rcmFolderMenu').enableContextMenuItems('#expandall');
+ }
+ }
+ else if (el.hasClass('addressbook') || el.hasClass('contactgroup')) {
+ $('#rcmGroupMenu').disableContextMenuItems('#group-create,#group-rename,#group-delete');
+
+ if ($(el).hasClass('contactgroup') && $(el).children('a').attr('rel')) {
+ var matches = $(el).children('a').attr('rel').match(/([A-Z0-9\-_]+):?([A-Z0-9\-_]+)?/i);
+
+ if (!rcmail.env.address_sources[matches[1]].readonly) {
+ if (!rcmail.name_input)
+ $('#rcmGroupMenu').enableContextMenuItems('#group-rename');
+
+ $('#rcmGroupMenu').enableContextMenuItems('#group-delete');
+ }
+ }
+ else if ($(el).hasClass('addressbook')) {
+ var source = $(el).children('a').attr('rel');
+
+ if (!rcmail.env.address_sources[source].readonly)
+ $('#rcmGroupMenu').enableContextMenuItems('#group-create')
+ }
+ }
+ else if (rcmail.env.task == 'addressbook') {
+ var matches = String($(el).attr('id')).match(/rcmrow([a-z0-9\-_=]+)/i);
+ if ($(el) && matches) {
+ if (rcmail.contact_list.selection.length > 1 && rcmail.contact_list.in_selection(matches[1]))
+ $('#rcmAddressMenu').disableContextMenuItems(rcmail.contextmenu_disable_multi.join(','));
+ else
+ $('#rcmAddressMenu').enableContextMenuItems(rcmail.contextmenu_disable_multi.join(','));
+
+ if (rcmail.env.group && rcmail.contact_list.in_selection(matches[1]))
+ $('#rcmAddressMenu').enableContextMenuItems('#group-remove-selected');
+ else
+ $('#rcmAddressMenu').disableContextMenuItems('#group-remove-selected');
+
+ var ab_src = rcmail.env.source ? rcmail.env.source : matches[1].split('-', 2)[1];
+
+ if (rcmail.env.address_sources[ab_src].readonly)
+ $('#rcmAddressMenu').disableContextMenuItems('#edit,#delete,#group-remove-selected');
+ }
+ }
+}
+
+function rcm_addressmenu_init(row) {
+ $("tr[id=" + row + "]").contextMenu({
+ menu: 'rcmAddressMenu'
+ },
+ function(command, el, pos) {
+ var matches = String($(el).attr('id')).match(/rcmrow([a-z0-9\-_=]+)/i);
+ if ($(el) && matches) {
+ var prev_cid = rcmail.env.cid;
+ if (rcmail.contact_list.selection.length <= 1 || !rcmail.contact_list.in_selection(matches[1]))
+ rcmail.env.cid = matches[1];
+
+ // fix command string in IE
+ if (command.indexOf("#") > 0)
+ command = command.substr(command.indexOf("#") + 1);
+
+ // enable the required command
+ cmd = command;
+ var prev_command = rcmail.commands[cmd];
+ rcmail.enable_command(cmd, true);
+
+ // process external commands
+ if (typeof rcmail.contextmenu_command_handlers[command] == 'function') {
+ rcmail.contextmenu_command_handlers[command](command, el, pos);
+ }
+ else if (typeof rcmail.contextmenu_command_handlers[command] == 'string') {
+ window[rcmail.contextmenu_command_handlers[command]](command, el, pos);
+ }
+ else {
+ switch (command) {
+ case 'edit':
+ rcmail.contact_list.select(rcmail.env.cid);
+ clearTimeout(rcmail.preview_timer)
+ rcmail.command(command, '', $(el));
+ break;
+ case 'compose':
+ case 'delete':
+ case 'moveto':
+ case 'group-remove-selected':
+ var ab_src = rcmail.env.source ? rcmail.env.source : matches[1].split('-', 2)[1];
+
+ if (command == 'moveto') {
+ // check for valid taget
+ if (rcmail.env.rcm_destbook == ab_src || (rcmail.env.rcm_destgroup && rcmail.env.contactfolders['G' + rcmail.env.rcm_destsource + rcmail.env.rcm_destgroup].id == rcmail.env.group))
+ return;
+ }
+
+ var prev_sel = null;
+
+ if (rcmail.env.cid) {
+ if (!rcmail.contact_list.in_selection(rcmail.env.cid)) {
+ prev_sel = rcmail.contact_list.get_selection();
+ rcmail.contact_list.select(rcmail.env.cid);
+ }
+ else if (rcmail.contact_list.get_single_selection() == rcmail.env.cid) {
+ rcmail.env.cid = null;
+ }
+ else {
+ prev_sel = rcmail.contact_list.get_selection();
+ rcmail.contact_list.select(rcmail.env.cid);
+ }
+ }
+
+ if (command == 'delete')
+ rcmail.env.cid = null;
+
+ rcmail.drag_active = true;
+ if (rcmail.env.rcm_destgroup)
+ rcmail.command(command, rcmail.env.contactfolders['G' + rcmail.env.rcm_destsource + rcmail.env.rcm_destgroup], $(el));
+ else
+ rcmail.command(command, rcmail.env.contactfolders[rcmail.env.rcm_destsource], $(el));
+ rcmail.drag_active = false;
+
+ if (prev_sel) {
+ rcmail.contact_list.clear_selection();
+
+ for (var i in prev_sel)
+ rcmail.contact_list.select_row(prev_sel[i], CONTROL_KEY);
+ }
+
+ rcmail.env.rcm_destbook = null;
+ rcmail.env.rcm_destsource = null;
+ rcmail.env.rcm_destgroup = null;
+ break;
+ }
+ }
+
+ rcmail.enable_command(cmd, prev_command);
+ rcmail.env.cid = prev_cid;
+ }
+ });
+}
+
+function rcm_set_dest_book(obj, source, group) {
+ rcmail.env.rcm_destbook = obj;
+ rcmail.env.rcm_destsource = source;
+ rcmail.env.rcm_destgroup = group;
+}
+
+function rcm_groupmenu_init(li) {
+ $(li).contextMenu({
+ menu: 'rcmGroupMenu'
+ },
+ function(command, el, pos) {
+ var matches = $(el).children('a').attr('rel').match(/([A-Z0-9\-_]+):?([A-Z0-9\-_]+)?/i);
+ if ($(el) && matches) {
+ prev_group = rcmail.env.group;
+ prev_source = rcmail.env.source;
+
+ cur_source = matches[1];
+ if (matches[2])
+ cur_id = matches[2];
+ else
+ cur_id = rcmail.env.group;
+
+ rcmail.env.group = cur_id
+ rcmail.env.source = cur_source;
+
+ // fix command string in IE
+ if (command.indexOf("#") > 0)
+ command = command.substr(command.indexOf("#") + 1);
+
+ // enable the required command
+ var prev_command = rcmail.commands[command];
+ rcmail.enable_command(command, true);
+
+ // process external commands
+ if (typeof rcmail.contextmenu_command_handlers[command] == 'function') {
+ rcmail.contextmenu_command_handlers[command](command, el, pos);
+ }
+ else if (typeof rcmail.contextmenu_command_handlers[command] == 'string') {
+ window[rcmail.contextmenu_command_handlers[command]](command, el, pos);
+ }
+ else {
+ switch (command) {
+ case 'group-create':
+ rcmail.command(command, '', $(el).children('a'));
+ break;
+ case 'group-rename':
+ rcmail.command(command, '', $(el).children('a'));
+
+ // callback requires target is selected
+ rcmail.enable_command('listgroup', true);
+ rcmail.env.group = prev_group;
+ rcmail.env.source = prev_source
+ prev_group = cur_id;
+ prev_source = cur_source;
+ rcmail.command('listgroup', {'source': prev_source,'id': prev_group}, $(el).children('a'));
+ rcmail.enable_command('listgroup', false);
+ break;
+ case 'group-delete':
+ rcmail.command(command, '', $(el).children('a'));
+ break;
+ }
+ }
+
+ rcmail.enable_command(command, prev_command);
+ rcmail.env.group = prev_group;
+ rcmail.env.source = prev_source;
+ }
+ });
+}
+
+function rcm_groupmenu_update(action, props) {
+ var gid = props.source + props.id;
+ gid = gid.replace(rcmail.identifier_expr, '_');
+
+ switch (action) {
+ case 'insert':
+ var link = $('<a>')
+ .attr('id', 'rcm_contextgrps_G' + gid)
+ .attr('href', '#moveto')
+ .addClass('active')
+ .attr('onclick', "rcm_set_dest_book('G" + gid + "', '" + props.source + "','" + props.id + "')")
+ .html('<span>' + props.name + '</span>');
+
+ var li = $('<li>').addClass('contactgroup').append(link);
+
+ var sibling = $('#rcm_contextaddr_' + props.source);
+ $('a[id^="rcm_contextgrps_G"]').each(function(i, elem) {
+ if (props.name.toUpperCase().trim() >= $(this).text().toUpperCase().trim())
+ sibling = $(elem).parent();
+ else
+ return false;
+ });
+
+ $(li).insertAfter($(sibling));
+
+ rcm_groupmenu_init(props.li);
+ break;
+ case 'update':
+ if ($('#rcm_contextgrps_G' + gid).length) {
+ if (props.newid) {
+ var new_gid = props.source + props.newid;
+ new_gid = new_gid.replace(rcmail.identifier_expr, '_');
+
+ var link = $('<a>')
+ .attr('id', 'rcm_contextgrps_G' + new_gid)
+ .attr('href', '#moveto')
+ .addClass('active')
+ .attr('onclick', "rcm_set_dest_book('G" + new_gid + "', '" + props.source + "','" + props.newid + "')")
+ .html('<span>' + props.name + '</span>');
+
+ $('#rcm_contextgrps_G' + gid).replaceWith(link);
+ }
+ else {
+ $('#rcm_contextgrps_G' + gid).html('<span>' + props.name + '</span>');
+ }
+
+ row = $('#rcm_contextgrps_G' + gid).parent().clone(true);
+ $('#rcm_contextgrps_G' + gid).parent().remove();
+
+ var sibling = $('#rcm_contextaddr_' + props.source);
+ $('a[id^="rcm_contextgrps_G"]').each(function(i, elem) {
+ if (props.name.toUpperCase().trim() >= $(this).text().toUpperCase().trim())
+ sibling = $(elem).parent();
+ else
+ return false;
+ });
+
+ $(row).insertAfter($(sibling));
+ }
+
+ break;
+ case 'remove':
+ if ($('#rcm_contextgrps_G' + gid).length)
+ $('#rcm_contextgrps_G' + gid).remove();
+
+ break;
+ }
+}
+
+$(document).ready(function() {
+ if (window.rcmail) {
+ // init message list menu
+ if ($('#rcmContextMenu').length > 0) {
+ rcmail.addEventListener('listupdate', function(props) { rcm_contextmenu_update(); } );
+ rcmail.addEventListener('insertrow', function(props) { rcm_contextmenu_init(props.row.id); } );
+ }
+
+ // init folder list menu
+ if ($('#rcmFolderMenu').length > 0)
+ rcmail.add_onload('rcm_foldermenu_init();');
+
+ // init contact list menu
+ if ($('#rcmAddressMenu').length > 0)
+ rcmail.addEventListener('insertrow', function(props) { rcm_addressmenu_init(props.row.id); } );
+
+ // init group list menu
+ if ($('#rcmGroupMenu').length > 0) {
+ rcmail.add_onload('rcm_groupmenu_init("#directorylist li");');
+ rcmail.addEventListener('group_insert', function(props) { rcm_groupmenu_update('insert', props); } );
+ rcmail.addEventListener('group_update', function(props) { rcm_groupmenu_update('update', props); } );
+ rcmail.addEventListener('group_delete', function(props) { rcm_groupmenu_update('remove', props); } );
+ }
+ }
+}); \ No newline at end of file
diff --git a/plugins/contextmenu/contextmenu.php b/plugins/contextmenu/contextmenu.php
new file mode 100644
index 000000000..aa29aa8d5
--- /dev/null
+++ b/plugins/contextmenu/contextmenu.php
@@ -0,0 +1,315 @@
+<?php
+
+/**
+ * ContextMenu
+ *
+ * Plugin to add a context menu to the message list
+ *
+ * @version @package_version@
+ * @author Philip Weir
+ */
+class contextmenu extends rcube_plugin
+{
+ public $task = 'mail|addressbook';
+
+ function init()
+ {
+ $rcmail = rcube::get_instance();
+ if ($rcmail->task == 'mail' && ($rcmail->action == '' || $rcmail->action == 'show'))
+ $this->add_hook('render_mailboxlist', array($this, 'show_mailbox_menu'));
+ elseif ($rcmail->task == 'addressbook' && $rcmail->action == '')
+ $this->add_hook('addressbooks_list', array($this, 'show_addressbook_menu'));
+
+ $this->register_action('plugin.contextmenu.messagecount', array($this, 'messagecount'));
+ $this->register_action('plugin.contextmenu.readfolder', array($this, 'readfolder'));
+ }
+
+ public function messagecount()
+ {
+ $mbox = rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_GET);
+ $this->api->output->set_env('messagecount', rcube::get_instance()->storage->count($mbox));
+ $this->api->output->send();
+ }
+
+ public function readfolder()
+ {
+ $storage = rcube::get_instance()->storage;
+ $cbox = rcube_utils::get_input_value('_cur', rcube_utils::INPUT_GET);
+ $mbox = rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_GET);
+ $oact = rcube_utils::get_input_value('_oact', rcube_utils::INPUT_GET);
+
+ $uids = $storage->search_once($mbox, 'ALL UNSEEN', true);
+
+ if ($uids->is_empty())
+ return false;
+
+ $storage->set_flag($uids->get(), 'SEEN', $mbox);
+
+ if ($cbox == $mbox && $oact == '')
+ $this->api->output->command('toggle_read_status', 'read', $uids->get());
+
+ rcmail_send_unread_count($mbox, true);
+ $this->api->output->send();
+ }
+
+ public function show_mailbox_menu($args)
+ {
+ $rcmail = rcube::get_instance();
+ $this->add_texts('localization/');
+ $rcmail->output->add_label('nomessagesfound');
+ $this->include_script('jquery.contextMenu.js');
+ $this->include_script('jquery.mousewheel.js');
+ $this->include_script('contextmenu.js');
+
+ $this->include_stylesheet($this->local_skin_path() . '/contextmenu.css');
+ if ($rcmail->output->browser->ie && $rcmail->output->browser->ver == 6)
+ $this->include_stylesheet($this->local_skin_path() . '/ie6hacks.css');
+
+ $out = '';
+
+ // message list menu
+ if ($rcmail->action == '') {
+ $li = '';
+
+ $li .= html::tag('li', array('class' => 'conmentitle'), html::span(null, rcmail::Q($this->gettext('markmessages'))));
+ $li .= html::tag('li', array('class' => 'markmessage read'), html::a(array('href' => "#read", 'class' => 'active'), html::span(null, rcmail::Q($this->gettext('markread')))));
+ $li .= html::tag('li', array('class' => 'markmessage unread'), html::a(array('href' => "#unread", 'class' => 'active'), html::span(null, rcmail::Q($this->gettext('markunread')))));
+ $li .= html::tag('li', array('class' => 'markmessage flagged'), html::a(array('href' => "#flagged", 'class' => 'active'), html::span(null, rcmail::Q($this->gettext('markflagged')))));
+ $li .= html::tag('li', array('class' => 'markmessage unflagged separator_below'), html::a(array('href' => "#unflagged", 'class' => 'active'), html::span(null, rcmail::Q($this->gettext('markunflagged')))));
+ $li .= html::tag('li', array('class' => 'reply'), html::a(array('href' => "#reply", 'class' => 'active'), html::span(null, rcmail::Q($this->gettext('replytomessage')))));
+
+ $lis = '';
+ $lis .= html::tag('li', array('class' => 'replyall'), html::a(array('href' => "#reply-all", 'class' => 'active'), html::span(null, rcmail::Q($this->gettext('replytoallmessage')))));
+ $lis .= html::tag('li', array('class' => 'replylist'), html::a(array('href' => "#reply-list", 'class' => 'active'), html::span(null, rcmail::Q($this->gettext('replylist')))));
+ $li .= html::tag('li', array('class' => 'submenu replyacts'), html::a(array('href' => "#reply-all", 'class' => 'active'), html::span(null, rcmail::Q($this->gettext('replyall')))) . html::tag('ul', array('class' => 'popupmenu toolbarmenu replyacts'), $lis));
+
+ $lis = '';
+ $lis .= html::tag('li', array('class' => 'forwardinline'), html::a(array('href' => "#forward-inline", 'class' => 'active'), html::span(null, rcmail::Q($this->gettext('forwardinline')))));
+ $lis .= html::tag('li', array('class' => 'forwardattachment'), html::a(array('href' => "#forward-attachment", 'class' => 'active'), html::span(null, rcmail::Q($this->gettext('forwardattachment')))));
+ $li .= html::tag('li', array('class' => 'submenu forwardacts'), html::a(array('href' => "#forward-inline", 'class' => 'active'), html::span(null, rcmail::Q($this->gettext('forward')))) . html::tag('ul', array('class' => 'popupmenu toolbarmenu forwardacts'), $lis));
+
+ //$rcmail = rcmail::get_instance();
+ //if (!$rcmail->config->get('flag_for_deletion', false) && $rcmail->config->get('trash_mbox') && $_SESSION['mbox'] != $rcmail->config->get('trash_mbox'))
+ // $li .= html::tag('li', array('class' => 'delete separator_below'), html::a(array('href' => "#delete", 'id' => 'rcm_delete', 'class' => 'active'), html::span(null, rcmail::Q($this->gettext('movemessagetotrash')))));
+ //else
+ $li .= html::tag('li', array('class' => 'delete separator_below'), html::a(array('href' => "#delete", 'id' => 'rcm_delete', 'class' => 'active'), html::span(null, rcmail::Q($this->gettext('deletemessage')))));
+
+ $li .= html::tag('li', array('class' => 'submenu moveto'), html::span(null, rcmail::Q($this->gettext('moveto'))) . $this->_gen_folder_list($args['list'], '#moveto'));
+
+ $lis = '';
+ $lis .= html::tag('li', array('class' => 'print'), html::a(array('href' => "#print", 'class' => 'active'), html::span(null, rcmail::Q($this->gettext('printmessage')))));
+ $lis .= html::tag('li', array('class' => 'save'), html::a(array('href' => "#download", 'class' => 'active'), html::span(null, rcmail::Q($this->gettext('emlsave')))));
+ $lis .= html::tag('li', array('class' => 'edit'), html::a(array('href' => "#edit", 'class' => 'active'), html::span(null, rcmail::Q($this->gettext('editasnew')))));
+ $lis .= html::tag('li', array('class' => 'source separator_below'), html::a(array('href' => "#viewsource", 'class' => 'active'), html::span(null, rcmail::Q($this->gettext('viewsource')))));
+ $lis .= html::tag('li', array('class' => 'open'), html::a(array('href' => "#open", 'id' => 'rcm_open', 'class' => 'active'), html::span(null, rcmail::Q($this->gettext('openinextwin')))));
+ $li .= html::tag('li', array('class' => 'submenu moreacts'), html::span(null, rcmail::Q($this->gettext('moreactions'))) . html::tag('ul', array('class' => 'popupmenu toolbarmenu moreacts'), $lis));
+
+ $out .= html::tag('ul', array('id' => 'rcmContextMenu', 'class' => 'popupmenu toolbarmenu'), $li);
+ }
+
+ // folder list menu
+ $li = '';
+
+ $li .= html::tag('li', array('class' => 'readfolder separator_below'), html::a(array('href' => "#readfolder", 'class' => 'active'), html::span(null, rcmail::Q($this->gettext('markreadfolder')))));
+
+ $li .= html::tag('li', array('class' => 'expunge'), html::a(array('href' => "#expunge", 'class' => 'active'), html::span(null, rcmail::Q($this->gettext('compact')))));
+ $li .= html::tag('li', array('class' => 'purge separator_below'), html::a(array('href' => "#purge", 'class' => 'active'), html::span(null, rcmail::Q($this->gettext('empty')))));
+
+ $li .= html::tag('li', array('class' => 'collapseall'), html::a(array('href' => "#collapseall", 'class' => 'active'), html::span(null, rcmail::Q($this->gettext('collapseall')))));
+ $li .= html::tag('li', array('class' => 'expandall separator_below'), html::a(array('href' => "#expandall", 'class' => 'active'), html::span(null, rcmail::Q($this->gettext('expandall')))));
+
+ $li .= html::tag('li', array('class' => 'openfolder'), html::a(array('href' => "#openfolder", 'id' => 'rcm_openfolder', 'class' => 'active'), html::span(null, rcmail::Q($this->gettext('openinextwin')))));
+
+ $out .= html::tag('ul', array('id' => 'rcmFolderMenu', 'class' => 'popupmenu toolbarmenu'), $li);
+
+ $this->api->output->add_footer(html::div(null , $out));
+
+ if ($rcmail->action == 'show')
+ $this->api->output->set_env('delimiter', $rcmail->storage->get_hierarchy_delimiter());
+ }
+
+ public function show_addressbook_menu($args)
+ {
+ $rcmail = rcube::get_instance();
+ $this->add_texts('localization/');
+ $this->include_script('jquery.contextMenu.js');
+ $this->include_script('jquery.mousewheel.js');
+ $this->include_stylesheet($this->local_skin_path() . '/contextmenu.css');
+ $this->include_script('contextmenu.js');
+ $out = '';
+
+ // contact list menu
+ $li = '';
+
+ $li .= html::tag('li', array('class' => 'composeto separator_below'), html::a(array('href' => "#compose", 'class' => 'active'), html::span(null, rcmail::Q($this->gettext('composeto')))));
+
+ $li .= html::tag('li', array('class' => 'editcontact'), html::a(array('href' => "#edit", 'class' => 'active'), html::span(null, rcmail::Q($this->gettext('editcontact')))));
+ $li .= html::tag('li', array('class' => 'deletecontact'), html::a(array('href' => "#delete", 'class' => 'active'), html::span(null, rcmail::Q($this->gettext('deletecontact')))));
+ $li .= html::tag('li', array('class' => 'removefromgroup'), html::a(array('href' => "#group-remove-selected", 'class' => 'active'), html::span(null, rcmail::Q($this->gettext('groupremoveselected')))));
+
+ if ($lis = $this->_gen_addressbooks_list($args['sources'], '#moveto'))
+ $li .= html::tag('li', array('class' => 'submenu separator_above'), html::span(null, rcmail::Q($this->gettext('copyto'))) . $lis);
+
+ $out .= html::tag('ul', array('id' => 'rcmAddressMenu', 'class' => 'popupmenu toolbarmenu'), $li);
+
+ // contact group menu
+ $li = '';
+
+ $li .= html::tag('li', array('class' => 'groupcreate'), html::a(array('href' => "#group-create", 'class' => 'active'), html::span(null, rcmail::Q($this->gettext('newcontactgroup')))));
+ $li .= html::tag('li', array('class' => 'grouprename'), html::a(array('href' => "#group-rename", 'class' => 'active'), html::span(null, rcmail::Q($this->gettext('grouprename')))));
+ $li .= html::tag('li', array('class' => 'groupdelete'), html::a(array('href' => "#group-delete", 'class' => 'active'), html::span(null, rcmail::Q($this->gettext('groupdelete')))));
+
+ $out .= html::tag('ul', array('id' => 'rcmGroupMenu', 'class' => 'popupmenu toolbarmenu'), $li);
+
+ $this->api->output->add_footer(html::div(null , $out));
+ }
+
+ // based on rcmail->render_folder_tree_html()
+ private function _gen_folder_list($arrFolders, $command, $nestLevel = 0, &$folderTotal = 0)
+ {
+ $rcmail = rcube::get_instance();
+
+ $maxlength = 35;
+ $realnames = false;
+
+ $out = '';
+ foreach ($arrFolders as $key => $folder) {
+ $title = null;
+
+ if (($folder_class = $rcmail->folder_classname($folder['id'])) && !$realnames) {
+ $foldername = $rcmail->gettext($folder_class);
+ }
+ else {
+ $foldername = $folder['name'];
+
+ // shorten the folder name to a given length
+ if ($maxlength && $maxlength > 1) {
+ $fname = abbreviate_string($foldername, $maxlength);
+
+ if ($fname != $foldername)
+ $title = $foldername;
+
+ $foldername = $fname;
+ }
+ }
+
+ // make folder name safe for ids and class names
+ $folder_id = asciiwords($folder['id'], true, '_');
+ $classes = array();
+
+ // set special class for Sent, Drafts, Trash and Junk
+ if ($folder['id'] == $rcmail->config->get('sent_mbox'))
+ $classes[] = 'sent';
+ else if ($folder['id'] == $rcmail->config->get('drafts_mbox'))
+ $classes[] = 'drafts';
+ else if ($folder['id'] == $rcmail->config->get('trash_mbox'))
+ $classes[] = 'trash';
+ else if ($folder['id'] == $rcmail->config->get('junk_mbox'))
+ $classes[] = 'junk';
+ else if ($folder['id'] == 'INBOX')
+ $classes[] = 'inbox';
+ else
+ $classes[] = '_'.asciiwords($folder_class ? $folder_class : strtolower($folder['id']), true);
+
+ if ($folder['virtual'])
+ $classes[] = 'virtual';
+
+ if ($nestLevel > 0)
+ $classes[] = 'subfolder';
+
+ $out .= html::tag('li', array('class' => join(' ', $classes)), html::a(array('href' => $command, 'onclick' => "rcm_set_dest_folder('". rcmail::JQ($folder['id']) ."')", 'class' => 'active', 'title' => $title), html::span(null, str_repeat('&nbsp;&nbsp;', $nestLevel) . rcmail::Q($foldername))));
+
+ if (!empty($folder['folders']))
+ $out .= $this->_gen_folder_list($folder['folders'], $command, $nestLevel+1, $folderTotal);
+
+ $folderTotal++;
+ }
+
+ if ($nestLevel == 0) {
+ if ($folderTotal > 5) {
+ $out = html::tag('ul', array('class' => 'toolbarmenu folders scrollable'), $out);
+ $out = html::tag('div', array('class' => 'scroll_up_pas'), '') . $out . html::tag('div', array('class' => 'scroll_down_act'), '');
+ $out = html::tag('div', array('class' => 'popupmenu'), $out);
+ }
+ else {
+ $out = html::tag('ul', array('class' => 'popupmenu toolbarmenu folders'), $out);
+ }
+ }
+
+ return $out;
+ }
+
+ // based on rcmail_directory_list()
+ private function _gen_addressbooks_list($arrBooks, $command)
+ {
+ $rcmail = rcube::get_instance();
+ $groupTotal = 0;
+ $maxlength = 35;
+ $maxlength_grp = 33;
+ $out = '';
+
+ // address books
+ foreach ($arrBooks as $j => $source) {
+ $title = null;
+ $id = $source['id'] ? $source['id'] : $j;
+ $bookname = !empty($source['name']) ? rcmail::Q($source['name']) : rcmail::Q($id);
+
+ // shorten the address book name to a given length
+ if ($maxlength && $maxlength > 1) {
+ $bname = abbreviate_string($bookname, $maxlength);
+
+ if ($bname != $bookname)
+ $title = $bookname;
+
+ $bookname = $bname;
+ }
+
+ if ($source['readonly'])
+ $out .= html::tag('li', array('id' => 'rcm_contextaddr_' . $id, 'class' => 'addressbook disabled'), html::a(array('href' => $command, 'id' => 'rcm_contextgrps_'. rcmail::JQ($id), 'onclick' => "rcm_set_dest_book('" . rcmail::JQ($id) ."', '" . rcmail::JQ($id) ."', null)", 'class' => 'active', 'title' => $title), html::span(null, rcmail::Q($bookname))));
+ else
+ $out .= html::tag('li', array('id' => 'rcm_contextaddr_' . $id, 'class' => 'addressbook'), html::a(array('href' => $command, 'id' => 'rcm_contextgrps_'. rcmail::JQ($id), 'onclick' => "rcm_set_dest_book('" . rcmail::JQ($id) ."', '" . rcmail::JQ($id) ."', null)", 'class' => 'active', 'title' => $title), html::span(null, rcmail::Q($bookname))));
+
+ // contact groups
+ if ($source['groups']) {
+ $groups = $rcmail->get_address_book($source['id'])->list_groups();
+ foreach ($groups as $group) {
+ $title = null;
+ $gid = 'G' . rcube_utils::html_identifier($id . $group['ID']);
+ $groupname = !empty($group['name']) ? rcmail::Q($group['name']) : rcmail::Q($gid);
+
+ // shorten the address book name to a given length
+ if ($maxlength_grp && $maxlength_grp > 1) {
+ $gname = abbreviate_string($groupname, $maxlength_grp);
+
+ if ($gname != $groupname)
+ $title = $groupname;
+
+ $groupname = $gname;
+ }
+
+ if ($source['readonly'])
+ $out .= html::tag('li', array('class' => 'contactgroup disabled'), html::a(array('href' => $command, 'id' => 'rcm_contextgrps_'. rcmail::JQ($gid), 'onclick' => "rcm_set_dest_book('" . rcmail::JQ($gid) . "', '" . rcmail::JQ($id) . "', '" . rcmail::JQ($group['ID']) ."')", 'class' => 'active', 'title' => $title), html::span(null, rcmail::Q($groupname))));
+ else
+ $out .= html::tag('li', array('class' => 'contactgroup'), html::a(array('href' => $command, 'id' => 'rcm_contextgrps_'. rcmail::JQ($gid), 'onclick' => "rcm_set_dest_book('" . rcmail::JQ($gid) . "', '" . rcmail::JQ($id) . "', '" . rcmail::JQ($group['ID']) ."')", 'class' => 'active', 'title' => $title), html::span(null, rcmail::Q($groupname))));
+
+ $groupTotal++;
+ }
+ }
+
+ $groupTotal++;
+ }
+
+ if ($groupTotal > 5) {
+ $out = html::tag('ul', array('id' => 'rcm_contextgrps', 'class' => 'toolbarmenu folders scrollable'), $out);
+ $out = html::tag('div', array('class' => 'scroll_up_pas'), '') . $out . html::tag('div', array('class' => 'scroll_down_act'), '');
+ $out = html::tag('div', array('class' => 'popupmenu'), $out);
+ }
+ else {
+ $out = html::tag('ul', array('id' => 'rcm_contextgrps', 'class' => 'popupmenu toolbarmenu folders'), $out);
+ }
+
+ return $out;
+ }
+}
+
+?> \ No newline at end of file
diff --git a/plugins/contextmenu/jquery.contextMenu.js b/plugins/contextmenu/jquery.contextMenu.js
new file mode 100644
index 000000000..eaf33e5af
--- /dev/null
+++ b/plugins/contextmenu/jquery.contextMenu.js
@@ -0,0 +1,21 @@
+// jQuery Context Menu Plugin
+//
+// Version 1.01
+//
+// Cory S.N. LaViska
+// A Beautiful Site (http://abeautifulsite.net/)
+//
+// More info: http://abeautifulsite.net/2008/09/jquery-context-menu-plugin/
+//
+// Terms of Use
+//
+// This plugin is dual-licensed under the GNU General Public License
+// and the MIT License and is copyright A Beautiful Site, LLC.
+//
+// Modified by Philip Weir:
+// Added highlighting of selected row and submenu support
+// Added sub menu functions
+// Added bind to contextmenu event
+// Adjust menu position for screen boundaries
+// Shrunk with Google Closure Compiler (Simple Optimizations)
+jQuery&&function(){$.extend($.fn,{contextMenu:function(a,e){if(void 0==a.menu)return!1;void 0==a.inSpeed&&(a.inSpeed=150);void 0==a.outSpeed&&(a.outSpeed=75);0==a.inSpeed&&(a.inSpeed=-1);0==a.outSpeed&&(a.outSpeed=-1);$(this).each(function(){var b=$(this),l=$(b).offset();$("#"+a.menu).addClass("contextMenu");$(this).mousedown(function(m){$(this).mouseup(function(g){var d=$(this);$(this).unbind("mouseup");if(2==m.button){$(".contextRow").removeClass("contextRow");$(".contextMenu").hide();d.addClass("contextRow"); rcm_update_options(d);var f=$("#"+a.menu);$(this).submenu_render(f);if($(b).hasClass("disabled"))return!1;var c={},h,j;self.innerHeight?(c.pageYOffset=self.pageYOffset,c.pageXOffset=self.pageXOffset,c.innerHeight=self.innerHeight,c.innerWidth=self.innerWidth):document.documentElement&&document.documentElement.clientHeight?(c.pageYOffset=document.documentElement.scrollTop,c.pageXOffset=document.documentElement.scrollLeft,c.innerHeight=document.documentElement.clientHeight,c.innerWidth=document.documentElement.clientWidth): document.body&&(c.pageYOffset=document.body.scrollTop,c.pageXOffset=document.body.scrollLeft,c.innerHeight=document.body.clientHeight,c.innerWidth=document.body.clientWidth);g.pageX?h=g.pageX:h=g.clientX+c.scrollLeft;g.pageY?j=g.pageY:j=g.clientY+c.scrollTop;h+$(f).width()+10>$(document).width()&&0<$(document).width()-$(f).width()-10&&(h=$(document).width()-$(f).width()-10);j+$(f).height()+10>$(document).height()&&0<$(document).height()-$(f).height()-10&&(j=$(document).height()-$(f).height()-10); $(document).unbind("click",$(this).document_click);$("#"+a.menu+" li ul").hide();$("#"+a.menu+" li div").hide();$(f).css({top:j,left:h}).fadeIn(a.inSpeed);$(document).bind("keypress",{menu:f},$(this).menu_keypress);$("#"+a.menu).find("a").unbind("click");$("#"+a.menu).find("li a:not(.disabled)").click(function(){$(document).unbind("click",$(this).document_click).unbind("keypress",$(this).menu_keypress);$(".contextMenu").hide();d.removeClass("contextRow");e&&e($(this).attr("href").substr(1),$(d),{x:h- l.left,y:j-l.top,docX:h,docY:j});return!1});setTimeout(function(){$(document).bind("click",{menu:f,o:a},$(this).document_click);$("iframe").load(function(){(this.contentDocument?this.contentDocument:this.contentWindow?this.contentWindow.document:null).onclick=function(){$(document).click()}});$("iframe").contents().mouseup(function(){$(document).click()})},0)}rcmail.drag_active||(g.cancelBubble=!0,g.stopPropagation&&g.stopPropagation())})});var d,k;$("#"+a.menu).children("li").mouseenter(function(){if($(this).hasClass("submenu")){if($(this).hasClass("submenu")&& !d&&!$(this).children("*:not(a, span)").is(":visible")){window.clearTimeout(k);k=null;var b=this;d=window.setTimeout(function(){$("#"+a.menu).children("li.submenu").children("div.popupmenu").children("ul.scrollable").scrollTop(0);$("#"+a.menu).children("li.submenu").children("div.popupmenu").children("div.scroll_up_act").addClass("scroll_up_pas").removeClass("scroll_up_act");$("#"+a.menu).children("li.submenu").children("div.popupmenu").children("div.scroll_down_pas").addClass("scroll_down_act").removeClass("scroll_down_pas"); $("#"+a.menu).children("li.submenu").children("*:not(a, span)").hide();doc_height=$(document).height();$(b).children("*:not(a, span)").css({left:$("#"+a.menu).width()-2,top:0});$(b).children("*:not(a, span)").show();$(b).children("*:not(a, span)").offset().left+$(b).children("*:not(a, span)").width()+10>$(document).width()&&0<$(document).width()-$(b).children("*:not(a, span)").width()-$("#"+a.menu).width()&&$(b).children("*:not(a, span)").css({left:-1*$(b).children("*:not(a, span)").width()});y=-1* ($(b).children("*:not(a, span)").offset().top+$(b).children("*:not(a, span)").height()+10-doc_height);0>y&&0<$(b).children("*:not(a, span)").offset().top+y&&$(b).children("*:not(a, span)").css({top:y});$(b).children("div.popupmenu").length&&$(b).children("div.popupmenu").children().show();d=null},a.submenu_delay)}}else k=window.setTimeout(function(){$("#"+a.menu).children("li.submenu").children("*:not(a, span)").hide();k=null},a.submenu_delay)});$("#"+a.menu).children("li.submenu").mouseleave(function(){window.clearTimeout(d); d=null});$(this).mouseleave(function(){window.clearTimeout(d);d=null});$("#"+a.menu).each(function(){$(this).attr("unselectable","on");$(this).css("user-select","none");$(this).on("selectstart",!1)});$(b).add($("ul.contextMenu")).bind("contextmenu",function(){return!1})});return $(this)},disableContextMenuItems:function(a){if(void 0==a)return $(this).find("a").addClass("disabled"),$(this);$(this).each(function(){if(void 0!=a)for(var e=a.split(","),b=0;b<e.length;b++)$(this).find('a[href="'+e[b]+'"]').addClass("disabled")}); return $(this)},enableContextMenuItems:function(a){if(void 0==a)return $(this).find("a.disabled").removeClass("disabled"),$(this);$(this).each(function(){if(void 0!=a)for(var e=a.split(","),b=0;b<e.length;b++)$(this).find('a[href="'+e[b]+'"]').removeClass("disabled")});return $(this)},disableContextMenu:function(){$(this).each(function(){$(this).addClass("disabled")});return $(this)},enableContextMenu:function(){$(this).each(function(){$(this).removeClass("disabled")});return $(this)},destroyContextMenu:function(){$(this).each(function(){$(this).unbind("mousedown").unbind("mouseup")}); return $(this)},submenu_render:function(a){$(a).show();$(a).children("li.submenu").children().show();$(a).children("li.submenu").children("div.popupmenu").each(function(){ul_overflow=$(this).children("ul").css("overflow");$(this).children("ul").css({overflow:"visible"});$(this).children("div").css({width:$(this).children("ul").width()+"px"});$(this).css({width:$(this).children("ul").width()+"px"});$(this).children("ul").css({overflow:ul_overflow});$(this).children("div").click(function(a){var b=$(this).parent().children("ul"); $(this).hasClass("scroll_up_act")?($(b).scrollTop($(b).scrollTop()-18),$(this).parent().children("div.scroll_down_pas").addClass("scroll_down_act"),$(this).parent().children("div.scroll_down_pas").removeClass("scroll_down_pas"),0==$(b).scrollTop()&&($(this).removeClass("scroll_up_act"),$(this).addClass("scroll_up_pas"))):$(this).hasClass("scroll_down_act")&&($(b).scrollTop($(b).scrollTop()+18),$(this).parent().children("div.scroll_up_pas").addClass("scroll_up_act"),$(this).parent().children("div.scroll_up_pas").removeClass("scroll_up_pas"), $(b).prop("scrollHeight")-$(b).scrollTop()==$(b).outerHeight()&&($(this).removeClass("scroll_down_act"),$(this).addClass("scroll_down_pas")));a.cancelBubble=!0;a.stopPropagation&&a.stopPropagation()});$(this).children("ul").mousewheel($(this).submenu_mousewheel)});$(a).children("li.submenu").children("*:not(a, span)").hide();$(a).hide()},submenu_mousewheel:function(a,e){0<e?$(this).parent().children("div.scroll_up_act").click():0>e&&$(this).parent().children("div.scroll_down_act").click()},menu_keypress:function(a){switch(a.keyCode){case 13:$(a.data.menu).find("li a.hover").trigger("click"); break;case 27:$(document).trigger("click")}},document_click:function(a){$(document).unbind("click",$(this).document_click).unbind("keypress",$(this).menu_keypress);$(".contextRow").removeClass("contextRow");$(a.data.menu).fadeOut(a.data.o.outSpeed);return!1}})}(jQuery); \ No newline at end of file
diff --git a/plugins/contextmenu/jquery.mousewheel.js b/plugins/contextmenu/jquery.mousewheel.js
new file mode 120000
index 000000000..d86864a6a
--- /dev/null
+++ b/plugins/contextmenu/jquery.mousewheel.js
@@ -0,0 +1 @@
+../../../javascript/jquery-mousewheel/jquery.mousewheel.min.js \ No newline at end of file
diff --git a/plugins/contextmenu/localization/ca_ES.inc b/plugins/contextmenu/localization/ca_ES.inc
new file mode 100644
index 000000000..61081b6c8
--- /dev/null
+++ b/plugins/contextmenu/localization/ca_ES.inc
@@ -0,0 +1,12 @@
+<?php
+/* Author: Daniel López */
+
+$labels = array();
+$labels['markreadfolder'] = 'Marca tot com a llegit';
+$labels['collapseall'] = 'Compacta totes les carpetes';
+$labels['expandall'] = 'Expandeix totes les carpetes';
+$labels['copyto'] = 'Copia a ...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/contextmenu/localization/cs_CZ.inc b/plugins/contextmenu/localization/cs_CZ.inc
new file mode 100644
index 000000000..1dc4400db
--- /dev/null
+++ b/plugins/contextmenu/localization/cs_CZ.inc
@@ -0,0 +1,12 @@
+<?php
+/* Author: Martin Frajdl */
+
+$labels = array();
+$labels['markreadfolder'] = 'Oznacit vše jako přečtené';
+$labels['collapseall'] = 'Sbalit všechny složky';
+$labels['expandall'] = 'Rozbalit všechny složky';
+$labels['copyto'] = 'Kopírovat do...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/contextmenu/localization/da_DK.inc b/plugins/contextmenu/localization/da_DK.inc
new file mode 100644
index 000000000..5b9c04f39
--- /dev/null
+++ b/plugins/contextmenu/localization/da_DK.inc
@@ -0,0 +1,12 @@
+<?php
+/* Author: Johannes Hessellund */
+
+$labels = array();
+$labels['markreadfolder'] = 'Markér alle som læst';
+$labels['collapseall'] = 'Fold alle mapper sammen';
+$labels['expandall'] = 'Udfold alle mapper';
+$labels['copyto'] = 'Kopier til...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/contextmenu/localization/de_CH.inc b/plugins/contextmenu/localization/de_CH.inc
new file mode 100644
index 000000000..fbfa57078
--- /dev/null
+++ b/plugins/contextmenu/localization/de_CH.inc
@@ -0,0 +1,12 @@
+<?php
+/* Author: Mike Constabel */
+
+$labels = array();
+$labels['markreadfolder'] = 'Alle als gelesen markieren';
+$labels['collapseall'] = 'Alle Unterordner einklappen';
+$labels['expandall'] = 'Alle Unterordner ausklappen';
+$labels['copyto'] = 'Kopieren nach ...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/contextmenu/localization/de_DE.inc b/plugins/contextmenu/localization/de_DE.inc
new file mode 100644
index 000000000..fbfa57078
--- /dev/null
+++ b/plugins/contextmenu/localization/de_DE.inc
@@ -0,0 +1,12 @@
+<?php
+/* Author: Mike Constabel */
+
+$labels = array();
+$labels['markreadfolder'] = 'Alle als gelesen markieren';
+$labels['collapseall'] = 'Alle Unterordner einklappen';
+$labels['expandall'] = 'Alle Unterordner ausklappen';
+$labels['copyto'] = 'Kopieren nach ...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/contextmenu/localization/en_GB.inc b/plugins/contextmenu/localization/en_GB.inc
new file mode 100644
index 000000000..d9cc7f9d7
--- /dev/null
+++ b/plugins/contextmenu/localization/en_GB.inc
@@ -0,0 +1,12 @@
+<?php
+/* Author: Philip Weir */
+
+$labels = array();
+$labels['markreadfolder'] = 'Mark all as read';
+$labels['collapseall'] = 'Collapse all folders';
+$labels['expandall'] = 'Expand all folders';
+$labels['copyto'] = 'Copy to...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/contextmenu/localization/en_US.inc b/plugins/contextmenu/localization/en_US.inc
new file mode 100644
index 000000000..d9cc7f9d7
--- /dev/null
+++ b/plugins/contextmenu/localization/en_US.inc
@@ -0,0 +1,12 @@
+<?php
+/* Author: Philip Weir */
+
+$labels = array();
+$labels['markreadfolder'] = 'Mark all as read';
+$labels['collapseall'] = 'Collapse all folders';
+$labels['expandall'] = 'Expand all folders';
+$labels['copyto'] = 'Copy to...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/contextmenu/localization/es_ES.inc b/plugins/contextmenu/localization/es_ES.inc
new file mode 100644
index 000000000..253106be6
--- /dev/null
+++ b/plugins/contextmenu/localization/es_ES.inc
@@ -0,0 +1,12 @@
+<?php
+/* Author: Daniel López */
+
+$labels = array();
+$labels['markreadfolder'] = 'Marcar todo como leído';
+$labels['collapseall'] = 'Compactar todas las carpetas';
+$labels['expandall'] = 'Expandir todas las carpetas';
+$labels['copyto'] = 'Copiar a...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/contextmenu/localization/fr_FR.inc b/plugins/contextmenu/localization/fr_FR.inc
new file mode 100644
index 000000000..6da00f498
--- /dev/null
+++ b/plugins/contextmenu/localization/fr_FR.inc
@@ -0,0 +1,12 @@
+<?php
+/* Author: */
+
+$labels = array();
+$labels['markreadfolder'] = 'Marquer tout comme lu';
+$labels['collapseall'] = 'Reduire les dossiers';
+$labels['expandall'] = 'Developper les dossiers';
+$labels['copyto'] = 'Copier vers...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/contextmenu/localization/gl_ES.inc b/plugins/contextmenu/localization/gl_ES.inc
new file mode 100644
index 000000000..33f2de1d6
--- /dev/null
+++ b/plugins/contextmenu/localization/gl_ES.inc
@@ -0,0 +1,12 @@
+<?php
+/* Author: David Garabana Barro */
+
+$labels = array();
+$labels['markreadfolder'] = 'Marcar todas coma lidas';
+$labels['collapseall'] = 'Pechar tódolos cartafoles';
+$labels['expandall'] = 'Abrir tódolos cartafoles';
+$labels['copyto'] = 'Copiar a...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/contextmenu/localization/hu_HU.inc b/plugins/contextmenu/localization/hu_HU.inc
new file mode 100644
index 000000000..699aa8df9
--- /dev/null
+++ b/plugins/contextmenu/localization/hu_HU.inc
@@ -0,0 +1,12 @@
+<?php
+/* Author: Németh János */
+
+$labels = array();
+$labels['markreadfolder'] = 'Összes megjelölése olvasottként';
+$labels['collapseall'] = 'Összes összecsukása';
+$labels['expandall'] = 'Összes kibontása';
+$labels['copyto'] = 'Másolás...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/contextmenu/localization/it_IT.inc b/plugins/contextmenu/localization/it_IT.inc
new file mode 100644
index 000000000..7e68214c5
--- /dev/null
+++ b/plugins/contextmenu/localization/it_IT.inc
@@ -0,0 +1,12 @@
+<?php
+/* Author: Massimiliano Adamo */
+
+$labels = array();
+$labels['markreadfolder'] = 'Marca tutto come letto';
+$labels['collapseall'] = 'Compatta tutte le cartelle';
+$labels['expandall'] = 'Espandi tutte le cartelle';
+$labels['copyto'] = 'Copia su...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/contextmenu/localization/nl_NL.inc b/plugins/contextmenu/localization/nl_NL.inc
new file mode 100644
index 000000000..57f3562d0
--- /dev/null
+++ b/plugins/contextmenu/localization/nl_NL.inc
@@ -0,0 +1,12 @@
+<?php
+/* Author: Wouter Kevenaar */
+
+$labels = array();
+$labels['markreadfolder'] = 'Alles markeren als gelezen';
+$labels['collapseall'] = 'Alle mappen inklappen';
+$labels['expandall'] = 'Alle mappen uitklappen';
+$labels['copyto'] = 'Kopiëren naar...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/contextmenu/localization/pl_PL.inc b/plugins/contextmenu/localization/pl_PL.inc
new file mode 100644
index 000000000..7cc2cd4b9
--- /dev/null
+++ b/plugins/contextmenu/localization/pl_PL.inc
@@ -0,0 +1,12 @@
+<?php
+/* Author: Michał Jałocha */
+
+$labels = array();
+$labels['markreadfolder'] = 'Oznacz wszystkie jako przeczytane';
+$labels['collapseall'] = 'Zwiń wszystkie foldery';
+$labels['expandall'] = 'Rozwiń wszystkie foldery';
+$labels['copyto'] = 'Kopiuj do...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/contextmenu/localization/pt_BR.inc b/plugins/contextmenu/localization/pt_BR.inc
new file mode 100644
index 000000000..60b0e7284
--- /dev/null
+++ b/plugins/contextmenu/localization/pt_BR.inc
@@ -0,0 +1,12 @@
+<?php
+/* Author: Alexandre Gorges */
+
+$labels = array();
+$labels['markreadfolder'] = 'Marcar todas como lidas';
+$labels['collapseall'] = 'Recolher todas as pastas';
+$labels['expandall'] = 'Expandir todas as pastas';
+$labels['copyto'] = 'Copiar para...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/contextmenu/localization/ro_RO.inc b/plugins/contextmenu/localization/ro_RO.inc
new file mode 100644
index 000000000..3ac7559ab
--- /dev/null
+++ b/plugins/contextmenu/localization/ro_RO.inc
@@ -0,0 +1,12 @@
+<?php
+/* Author: Ovidiu Bica */
+
+$labels = array();
+$labels['markreadfolder'] = 'Marchează mesajele ca citite';
+$labels['collapseall'] = 'Ascunde toate folderele';
+$labels['expandall'] = 'Afişează toate folderele';
+$labels['copyto'] = 'Copiaza in';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/contextmenu/localization/ru_RU.inc b/plugins/contextmenu/localization/ru_RU.inc
new file mode 100644
index 000000000..3a3d85df6
--- /dev/null
+++ b/plugins/contextmenu/localization/ru_RU.inc
@@ -0,0 +1,12 @@
+<?php
+/* Author: Sergey Basov */
+
+$labels = array();
+$labels['markreadfolder'] = 'Отметить все как прочитанные';
+$labels['collapseall'] = 'Свернуть все папки';
+$labels['expandall'] = 'Развернуть все папки';
+$labels['copyto'] = 'Копировать в...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/contextmenu/localization/sv_SE.inc b/plugins/contextmenu/localization/sv_SE.inc
new file mode 100644
index 000000000..92f3c13a0
--- /dev/null
+++ b/plugins/contextmenu/localization/sv_SE.inc
@@ -0,0 +1,12 @@
+<?php
+/* Author: Jonas Nasholm */
+
+$labels = array();
+$labels['markreadfolder'] = 'Märk allt som läst';
+$labels['collapseall'] = 'Dölj alla kataloger';
+$labels['expandall'] = 'Visa alla kataloger';
+$labels['copyto'] = 'Kopiera till...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/contextmenu/localization/tr_TR.inc b/plugins/contextmenu/localization/tr_TR.inc
new file mode 100644
index 000000000..62f7acf93
--- /dev/null
+++ b/plugins/contextmenu/localization/tr_TR.inc
@@ -0,0 +1,12 @@
+<?php
+/* Author: Mustafa Icer */
+
+$labels = array();
+$labels['markreadfolder'] = 'Tüm mesajları okunumuş olarak işaretle';
+$labels['collapseall'] = 'Tüm alt klasörleri kapat';
+$labels['expandall'] = 'Tüm alt klasörleri aç';
+$labels['copyto'] = '... kopyala';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/contextmenu/localization/uk_UA.inc b/plugins/contextmenu/localization/uk_UA.inc
new file mode 100644
index 000000000..67ddb234c
--- /dev/null
+++ b/plugins/contextmenu/localization/uk_UA.inc
@@ -0,0 +1,12 @@
+<?php
+/* Author: Sergey Basov */
+
+$labels = array();
+$labels['markreadfolder'] = 'Відмітити все як прочитане';
+$labels['collapseall'] = 'Згорнути усі папки';
+$labels['expandall'] = 'Розгорнути усі папки';
+$labels['copyto'] = 'Копіювати до...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/contextmenu/localization/zh_TW.inc b/plugins/contextmenu/localization/zh_TW.inc
new file mode 100644
index 000000000..bd33d27b8
--- /dev/null
+++ b/plugins/contextmenu/localization/zh_TW.inc
@@ -0,0 +1,12 @@
+<?php
+/* Author: thomasysliu */
+
+$labels = array();
+$labels['markreadfolder'] = '標示為已讀取';
+$labels['collapseall'] = '全部收起';
+$labels['expandall'] = '全部展開';
+$labels['copyto'] = '複製到...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/contextmenu/package.xml b/plugins/contextmenu/package.xml
new file mode 100644
index 000000000..c65375ae9
--- /dev/null
+++ b/plugins/contextmenu/package.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<package xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" packagerversion="1.9.0" version="2.0" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0
+ http://pear.php.net/dtd/tasks-1.0.xsd
+ http://pear.php.net/dtd/package-2.0
+ http://pear.php.net/dtd/package-2.0.xsd">
+ <name>contextmenu</name>
+ <uri>http://github.com/JohnDoh/Roundcube-Plugin-Context-Menu/</uri>
+ <summary>Adds context menus with common tasks to various parts of Roundcube</summary>
+ <description>Adds context menus to the message list, folder list and address book. Menu includes the abilities mark messages as read/unread, delete, reply and forward.</description>
+ <lead>
+ <name>Philip Weir</name>
+ <user>JohnDoh</user>
+ <email>roundcube@tehinterweb.co.uk</email>
+ <active>yes</active>
+ </lead>
+ <date>2013-02-24</date>
+ <time>10:50:37</time>
+ <version>
+ <release>1.10</release>
+ <api>1.10</api>
+ </version>
+ <stability>
+ <release>stable</release>
+ <api>stable</api>
+ </stability>
+ <license uri="http://www.gnu.org/licenses/gpl.html">GNU GPLv3+</license>
+ <notes>-</notes>
+ <contents>
+ <dir baseinstalldir="/" name="/">
+ <file name="contextmenu.php" role="php">
+ <tasks:replace from="@name@" to="name" type="package-info"/>
+ <tasks:replace from="@package_version@" to="version" type="package-info"/>
+ </file>
+ <file name="contextmenu.js" role="data">
+ <tasks:replace from="@name@" to="name" type="package-info"/>
+ <tasks:replace from="@package_version@" to="version" type="package-info"/>
+ </file>
+ <file name="CHANGELOG" role="data"/>
+ <file name="README.md" role="data"/>
+ <file name="jquery.contextMenu.js" role="data"/>
+ <file name="jquery.mousewheel.js" role="data"/>
+ <file name="localization/ca_ES.inc" role="data"/>
+ <file name="localization/cs_CZ.inc" role="data"/>
+ <file name="localization/da_DK.inc" role="data"/>
+ <file name="localization/de_CH.inc" role="data"/>
+ <file name="localization/de_DE.inc" role="data"/>
+ <file name="localization/en_GB.inc" role="data"/>
+ <file name="localization/en_US.inc" role="data"/>
+ <file name="localization/es_ES.inc" role="data"/>
+ <file name="localization/fr_FR.inc" role="data"/>
+ <file name="localization/gl_ES.inc" role="data"/>
+ <file name="localization/hu_HU.inc" role="data"/>
+ <file name="localization/it_IT.inc" role="data"/>
+ <file name="localization/nl_NL.inc" role="data"/>
+ <file name="localization/pl_PL.inc" role="data"/>
+ <file name="localization/pt_BR.inc" role="data"/>
+ <file name="localization/ro_RO.inc" role="data"/>
+ <file name="localization/ru_RU.inc" role="data"/>
+ <file name="localization/sv_SE.inc" role="data"/>
+ <file name="localization/tr_TR.inc" role="data"/>
+ <file name="localization/uk_UA.inc" role="data"/>
+ <file name="localization/zh_TW.inc" role="data"/>
+ <file name="skins/classic/contexticons.gif" role="data"/>
+ <file name="skins/classic/contexticons.png" role="data"/>
+ <file name="skins/classic/contextmenu.css" role="data"/>
+ <file name="skins/classic/folders.gif" role="data"/>
+ <file name="skins/classic/folders.png" role="data"/>
+ <file name="skins/classic/ie6hacks.css" role="data"/>
+ <file name="skins/classic/messageactions.gif" role="data"/>
+ <file name="skins/classic/messageactions.png" role="data"/>
+ <file name="skins/larry/contexticons.png" role="data"/>
+ <file name="skins/larry/contextmenu.css" role="data"/>
+ <file name="skins/larry/folders.png" role="data"/>
+ <file name="skins/larry/ie6hacks.css" role="data"/>
+ <file name="skins/larry/messageactions.png" role="data"/>
+ </dir>
+ <!-- / -->
+ </contents>
+ <dependencies>
+ <required>
+ <php>
+ <min>5.2.1</min>
+ </php>
+ <pearinstaller>
+ <min>1.7.0</min>
+ </pearinstaller>
+ </required>
+ </dependencies>
+ <phprelease/>
+</package>
diff --git a/plugins/contextmenu/skins/classic/contexticons.gif b/plugins/contextmenu/skins/classic/contexticons.gif
new file mode 100644
index 000000000..e1a77ea28
--- /dev/null
+++ b/plugins/contextmenu/skins/classic/contexticons.gif
Binary files differ
diff --git a/plugins/contextmenu/skins/classic/contexticons.png b/plugins/contextmenu/skins/classic/contexticons.png
new file mode 100644
index 000000000..fb0a7299c
--- /dev/null
+++ b/plugins/contextmenu/skins/classic/contexticons.png
Binary files differ
diff --git a/plugins/contextmenu/skins/classic/contextmenu.css b/plugins/contextmenu/skins/classic/contextmenu.css
new file mode 100644
index 000000000..704878818
--- /dev/null
+++ b/plugins/contextmenu/skins/classic/contextmenu.css
@@ -0,0 +1,357 @@
+/**
+ * ContextMenu plugin styles
+ */
+
+.contextRow td,
+#mailboxlist li.contextRow,
+#directorylistbox li.contextRow
+{
+ background-color: #EEEEEE;
+}
+
+#mailboxlist li.selected,
+#directorylistbox li.selected
+{
+ background-color: #929292;
+}
+
+#rcmContextMenu,
+#rcmFolderMenu,
+#rcmAddressMenu,
+#rcmGroupMenu
+{
+ padding-top: 3px;
+ min-width: 220px;
+}
+
+#rcmContextMenu li,
+#rcmFolderMenu li,
+#rcmAddressMenu li,
+#rcmGroupMenu li
+{
+ margin: 0;
+}
+
+#rcmContextMenu li ul,
+#rcmContextMenu li div,
+#rcmFolderMenu li ul,
+#rcmFolderMenu li div,
+#rcmAddressMenu li ul,
+#rcmAddressMenu li div,
+#rcmGroupMenu li ul,
+#rcmGroupMenu li div
+{
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ width: auto;
+ display: none;
+ background-color: #F9F9F9;
+ border: 1px solid #CCC;
+ padding: 1px;
+ z-index: 901;
+}
+
+#rcmContextMenu li.conmentitle,
+#rcmContextMenu li.submenu,
+#rcmFolderMenu li.conmentitle,
+#rcmFolderMenu li.submenu,
+#rcmAddressMenu li.conmentitle,
+#rcmAddressMenu li.submenu,
+#rcmGroupMenu li.conmentitle,
+#rcmGroupMenu li.submenu
+{
+ padding: 2px 8px 3px 27px;
+ cursor: default;
+}
+
+#rcmContextMenu li.sublink,
+#rcmFolderMenu li.sublink,
+#rcmAddressMenu li.sublink,
+#rcmGroupMenu li.sublink
+{
+ padding: 0;
+}
+
+#rcmContextMenu li.submenu,
+#rcmFolderMenu li.submenu,
+#rcmAddressMenu li.submenu,
+#rcmGroupMenu li.submenu
+{
+ position: relative;
+ cursor: pointer;
+ background: url(contexticons.png) no-repeat right 0;
+ padding-right: 15px;
+}
+
+#rcmContextMenu li.replyacts,
+#rcmContextMenu li.forwardacts,
+#rcmAddressMenu li.exportacts
+{
+ padding: 0 8px 0 0;
+}
+
+#rcmContextMenu li.markmessage a,
+#rcmAddressMenu li.contactgroup a
+{
+ text-indent: 8px;
+}
+
+#rcmContextMenu li.submenu:hover,
+#rcmContextMenu li.sublink:hover a.mainlink,
+#rcmFolderMenu li.submenu:hover,
+#rcmFolderMenu li.sublink:hover a.mainlink,
+#rcmAddressMenu li.submenu:hover,
+#rcmAddressMenu li.sublink:hover a.mainlink,
+#rcmGroupMenu li.submenu:hover,
+#rcmGroupMenu li.sublink:hover a.mainlink
+{
+ color: #fff;
+ background-color: #CC0000;
+}
+
+#rcmContextMenu li a,
+#rcmFolderMenu li a,
+#rcmAddressMenu li a,
+#rcmGroupMenu li a
+{
+ background: url(contexticons.png) no-repeat 7px 20px;
+}
+
+#rcmContextMenu li a.active:hover,
+#rcmFolderMenu li a.active:hover,
+#rcmAddressMenu li a.active:hover,
+#rcmGroupMenu li a.active:hover
+{
+ color: #fff;
+ background-color: #CC0000;
+}
+
+#rcmContextMenu a.disabled,
+#rcmFolderMenu a.disabled,
+#rcmAddressMenu a.disabled,
+#rcmGroupMenu a.disabled
+{
+ color: #AAA;
+ cursor: default;
+}
+
+#rcmContextMenu a.disabled:hover,
+#rcmFolderMenu a.disabled:hover,
+#rcmAddressMenu a.disabled:hover,
+#rcmGroupMenu a.disabled:hover
+{
+ color: #AAA;
+ background-color: transparent
+}
+
+#rcmContextMenu .read a
+{
+ background-position: 7px -85px;
+}
+
+#rcmFolderMenu .readfolder a
+{
+ background-position: 7px -85px;
+}
+
+#rcmContextMenu .unread a
+{
+ background-position: 7px -136px;
+}
+#rcmContextMenu .flagged a
+{
+ background-position: 7px -170px;
+}
+
+#rcmContextMenu .unflagged a
+{
+ background-position: 7px -153px;
+}
+
+#rcmContextMenu .reply a, #rcmContextMenu .replyall a, #rcmContextMenu .replylist a
+{
+ background-position: 7px -119px;
+}
+
+#rcmContextMenu .forwardinline a, #rcmContextMenu .forwardattachment a
+{
+ background-position: 7px -102px;
+}
+
+#rcmContextMenu .delete a,
+#rcmAddressMenu .deletecontact a
+{
+ background-position: 7px -187px;
+}
+
+#rcmFolderMenu .expunge a
+{
+ background-position: 7px -255px;
+}
+
+#rcmFolderMenu .purge a
+{
+ background-position: 7px -272px;
+}
+
+#rcmFolderMenu .collapseall a
+{
+ background-position: 7px -204px;
+}
+
+#rcmFolderMenu .expandall a
+{
+ background-position: 7px -220px;
+}
+
+#rcmContextMenu ul.moreacts li a
+{
+ background: url(messageactions.png) no-repeat 5px 20px;
+}
+
+#rcmContextMenu ul.moreacts li.print a
+{
+ background-position: 5px 1px;
+}
+
+#rcmContextMenu ul.moreacts li.source a
+{
+ background-position: 5px -35px;
+}
+
+#rcmContextMenu ul.moreacts li.save a
+{
+ background-position: 5px -17px;
+}
+
+#rcmContextMenu ul.moreacts li.open a
+{
+ background-position: 5px -53px;
+}
+
+#rcmFolderMenu .openfolder a
+{
+ background: url(messageactions.png) no-repeat 6px -53px;
+}
+
+#rcmContextMenu ul.moreacts li.edit a
+{
+ background-position: 5px -71px;
+}
+
+#rcmAddressMenu .editcontact a
+{
+ background: url(messageactions.png) no-repeat 6px -71px;
+}
+
+#rcmAddressMenu .composeto a
+{
+ background-position: 8px -238px;
+}
+
+#rcmContextMenu ul.folders li a,
+#rcmAddressMenu ul.folders li a
+{
+ background: url(folders.png) 5px 1px no-repeat;
+}
+
+#rcmContextMenu ul.folders li.inbox a
+{
+ background-position: 5px -17px;
+}
+
+#rcmContextMenu ul.folders li.drafts a
+{
+ background-position: 5px -36px;
+}
+
+#rcmContextMenu ul.folders li.sent a
+{
+ background-position: 5px -54px;
+}
+
+#rcmContextMenu ul.folders li.junk a
+{
+ background-position: 5px -73px;
+}
+
+#rcmContextMenu ul.folders li.trash a
+{
+ background-position: 5px -90px;
+}
+
+#rcmAddressMenu ul.folders li.addressbook a
+{
+ background-position: 5px -108px;
+}
+
+#rcmAddressMenu ul.folders li.contactgroup a
+{
+ background-position: 5px -144px;
+}
+
+#rcmContextMenu div.popupmenu,
+#rcmFolderMenu div.popupmenu,
+#rcmAddressMenu div.popupmenu
+{
+ height: 129px;
+ padding: 0;
+}
+
+#rcmContextMenu ul.scrollable,
+#rcmFolderMenu ul.scrollable,
+#rcmAddressMenu ul.scrollable
+{
+ top: 15px;
+ height: 100px;
+ overflow: hidden;
+ border-top: 0;
+ border-bottom: 0;
+ margin: 0;
+}
+
+#rcmContextMenu li div,
+#rcmFolderMenu li div,
+#rcmAddressMenu li div
+{
+ height: 12px;
+ overflow: hidden;
+ background: url(contexticons.png) #F9F9F9 no-repeat center 20px;
+}
+
+#rcmContextMenu li div.scroll_up_act,
+#rcmFolderMenu li div.scroll_up_act,
+#rcmAddressMenu li div.scroll_up_act
+{
+ background-position: center -17px;
+ border-bottom: 0;
+}
+
+#rcmContextMenu li div.scroll_up_pas,
+#rcmFolderMenu li div.scroll_up_pas,
+#rcmAddressMenu li div.scroll_up_pas
+{
+ background-position: center -34px;
+ border-bottom: 0;
+ cursor: default;
+}
+
+#rcmContextMenu li div.scroll_down_act,
+#rcmFolderMenu li div.scroll_down_act,
+#rcmAddressMenu li div.scroll_down_act
+{
+ top: 117px;
+ background-position: center -51px;
+ border-top: 0;
+}
+
+#rcmContextMenu li div.scroll_down_pas,
+#rcmFolderMenu li div.scroll_down_pas,
+#rcmAddressMenu li div.scroll_down_pas
+{
+ top: 117px;
+ background-position: center -68px;
+ border-top: 0;
+ cursor: default;
+} \ No newline at end of file
diff --git a/plugins/contextmenu/skins/classic/folders.gif b/plugins/contextmenu/skins/classic/folders.gif
new file mode 100644
index 000000000..0fccb2c18
--- /dev/null
+++ b/plugins/contextmenu/skins/classic/folders.gif
Binary files differ
diff --git a/plugins/contextmenu/skins/classic/folders.png b/plugins/contextmenu/skins/classic/folders.png
new file mode 100644
index 000000000..5013318f8
--- /dev/null
+++ b/plugins/contextmenu/skins/classic/folders.png
Binary files differ
diff --git a/plugins/contextmenu/skins/classic/ie6hacks.css b/plugins/contextmenu/skins/classic/ie6hacks.css
new file mode 100644
index 000000000..909915176
--- /dev/null
+++ b/plugins/contextmenu/skins/classic/ie6hacks.css
@@ -0,0 +1,54 @@
+/**
+ * ContextMenu plugin styles (IE6 hacks)
+ */
+
+#rcmContextMenu,
+#rcmFolderMenu,
+#rcmAddressMenu,
+#rcmGroupMenu
+{
+ width: 220px;
+}
+
+#rcmContextMenu li.submenu,
+#rcmFolderMenu li.submenu,
+#rcmAddressMenu li.submenu,
+#rcmGroupMenu li.submenu
+{
+ background-image: url(contexticons.gif);
+}
+
+#rcmContextMenu li a,
+#rcmFolderMenu li a,
+#rcmAddressMenu li a,
+#rcmGroupMenu li a
+{
+ background-image: url(contexticons.gif);
+}
+
+#rcmContextMenu ul.moreacts li a
+{
+ background-image: url(messageactions.gif);
+}
+
+#rcmFolderMenu .openfolder a
+{
+ background-image: url(messageactions.gif);
+}
+
+#rcmAddressMenu .editcontact a
+{
+ background-image: url(messageactions.gif);
+}
+
+#rcmContextMenu ul.folders li a,
+#rcmAddressMenu ul.folders li a
+{
+ background-image: url(folders.gif);
+}
+
+#rcmContextMenu li div,
+#rcmAddressMenu li div
+{
+ background-image: url(contexticons.gif);
+} \ No newline at end of file
diff --git a/plugins/contextmenu/skins/classic/messageactions.gif b/plugins/contextmenu/skins/classic/messageactions.gif
new file mode 100644
index 000000000..d2d647bed
--- /dev/null
+++ b/plugins/contextmenu/skins/classic/messageactions.gif
Binary files differ
diff --git a/plugins/contextmenu/skins/classic/messageactions.png b/plugins/contextmenu/skins/classic/messageactions.png
new file mode 100644
index 000000000..e9447f211
--- /dev/null
+++ b/plugins/contextmenu/skins/classic/messageactions.png
Binary files differ
diff --git a/plugins/contextmenu/skins/larry/contexticons.png b/plugins/contextmenu/skins/larry/contexticons.png
new file mode 100644
index 000000000..dbbfa4de1
--- /dev/null
+++ b/plugins/contextmenu/skins/larry/contexticons.png
Binary files differ
diff --git a/plugins/contextmenu/skins/larry/contextmenu.css b/plugins/contextmenu/skins/larry/contextmenu.css
new file mode 100644
index 000000000..d0b84ded3
--- /dev/null
+++ b/plugins/contextmenu/skins/larry/contextmenu.css
@@ -0,0 +1,425 @@
+/**
+ * ContextMenu plugin styles
+ */
+
+.records-table tbody tr.contextRow td
+{
+ background-color: #F2F2F2;
+}
+
+#mailboxlist li.contextRow,
+#directorylist li.contextRow,
+#addresslist .contextRow
+{
+ background-color: #C7E3EF;
+}
+
+#rcmContextMenu,
+#rcmFolderMenu,
+#rcmAddressMenu,
+#rcmGroupMenu
+{
+ padding-top: 3px;
+ min-width: 220px;
+}
+
+#rcmContextMenu li,
+#rcmFolderMenu li,
+#rcmAddressMenu li,
+#rcmGroupMenu li
+{
+ margin: 0;
+}
+
+#rcmContextMenu li ul,
+#rcmContextMenu li div,
+#rcmFolderMenu li ul,
+#rcmFolderMenu li div,
+#rcmAddressMenu li ul,
+#rcmAddressMenu li div,
+#rcmGroupMenu li ul,
+#rcmGroupMenu li div
+{
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ width: auto;
+ display: none;
+ background-color: #444;
+ border: 1px solid #999;
+ padding: 1px;
+ z-index: 901;
+ border-radius: 4px;
+ box-shadow: 0 2px 6px 0 #333;
+ -moz-box-shadow: 0 2px 6px 0 #333;
+ -webkit-box-shadow: 0 2px 6px 0 #333;
+ -o-box-shadow: 0 2px 6px 0 #333;
+}
+
+#rcmContextMenu li.conmentitle,
+#rcmContextMenu li.submenu,
+#rcmFolderMenu li.conmentitle,
+#rcmFolderMenu li.submenu,
+#rcmAddressMenu li.conmentitle,
+#rcmAddressMenu li.submenu,
+#rcmGroupMenu li.conmentitle,
+#rcmGroupMenu li.submenu
+{
+ padding: 0;
+ cursor: default;
+}
+
+#rcmContextMenu li.conmentitle span,
+#rcmContextMenu li.submenu span,
+#rcmFolderMenu li.conmentitle span,
+#rcmFolderMenu li.submenu span,
+#rcmAddressMenu li.conmentitle span,
+#rcmAddressMenu li.submenu span,
+#rcmGroupMenu li.conmentitle span,
+#rcmGroupMenu li.submenu span
+{
+ display: block;
+ padding: 6px 10px 6px 29px;
+}
+
+#rcmContextMenu li.sublink,
+#rcmFolderMenu li.sublink,
+#rcmAddressMenu li.sublink,
+#rcmGroupMenu li.sublink
+{
+ padding: 0;
+}
+
+#rcmContextMenu li.submenu,
+#rcmFolderMenu li.submenu,
+#rcmAddressMenu li.submenu,
+#rcmGroupMenu li.submenu
+{
+ position: relative;
+}
+
+#rcmContextMenu li.submenu span,
+#rcmFolderMenu li.submenu span,
+#rcmAddressMenu li.submenu span,
+#rcmGroupMenu li.submenu span
+{
+ cursor: pointer;
+ background: url(contexticons.png) no-repeat right -188px;
+ padding-right: 18px;
+}
+
+#rcmContextMenu li.markmessage a span,
+#rcmAddressMenu li.contactgroup a span
+{
+ text-indent: 15px;
+}
+
+#rcmContextMenu li.submenu:hover,
+#rcmContextMenu li.sublink:hover a.mainlink,
+#rcmFolderMenu li.submenu:hover,
+#rcmFolderMenu li.sublink:hover a.mainlink,
+#rcmAddressMenu li.submenu:hover,
+#rcmAddressMenu li.sublink:hover a.mainlink,
+#rcmGroupMenu li.submenu:hover,
+#rcmGroupMenu li.sublink:hover a.mainlink
+{
+ background-color: #00aad6;
+ background: -moz-linear-gradient(top, #00aad6 0%, #008fc9 100%);
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#00aad6), color-stop(100%,#008fc9));
+ background: -o-linear-gradient(top, #00aad6 0%, #008fc9 100%);
+ background: -ms-linear-gradient(top, #00aad6 0%, #008fc9 100%);
+ background: linear-gradient(top, #00aad6 0%, #008fc9 100%);
+}
+
+#rcmContextMenu li a,
+#rcmFolderMenu li a,
+#rcmAddressMenu li a,
+#rcmGroupMenu li a
+{
+ padding: 0;
+ margin-left: 0;
+}
+
+
+#rcmContextMenu li a span,
+#rcmFolderMenu li a span,
+#rcmAddressMenu li a span,
+#rcmGroupMenu li a span
+{
+ display: block;
+ background: url(contexticons.png) no-repeat 7px 20px;
+ padding: 6px 10px 6px 29px;
+ cursor: pointer;
+}
+
+#rcmContextMenu li a.active:hover,
+#rcmFolderMenu li a.active:hover,
+#rcmAddressMenu li a.active:hover,
+#rcmGroupMenu li a.active:hover
+{
+ background-color: #00aad6;
+ background: -moz-linear-gradient(top, #00aad6 0%, #008fc9 100%);
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#00aad6), color-stop(100%,#008fc9));
+ background: -o-linear-gradient(top, #00aad6 0%, #008fc9 100%);
+ background: -ms-linear-gradient(top, #00aad6 0%, #008fc9 100%);
+ background: linear-gradient(top, #00aad6 0%, #008fc9 100%);
+}
+
+#rcmContextMenu a.disabled,
+#rcmFolderMenu a.disabled,
+#rcmAddressMenu a.disabled,
+#rcmGroupMenu a.disabled
+{
+ opacity: 0.5;
+ filter: alpha(opacity=50);
+}
+
+#rcmContextMenu li a.disabled span,
+#rcmFolderMenu li a.disabled span,
+#rcmAddressMenu li a.disabled span,
+#rcmGroupMenu li a.disabled span
+{
+ cursor: default;
+}
+
+#rcmContextMenu li a.disabled:hover,
+#rcmFolderMenu li a.disabled:hover,
+#rcmAddressMenu li a.disabled:hover,
+#rcmGroupMenu li a.disabled:hover
+{
+ background-color: #444444;
+ background: -moz-linear-gradient(top, #444444 0%, #444444 100%);
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#444444), color-stop(100%,#444444));
+ background: -o-linear-gradient(top, #444444 0%, #444444 100%);
+ background: -ms-linear-gradient(top, #444444 0%, #444444 100%);
+ background: linear-gradient(top, #444444 0%, #444444 100%);
+}
+
+#rcmContextMenu .read a span
+{
+ background-position: 5px -24px;
+}
+
+#rcmFolderMenu .readfolder a span
+{
+ background-position: 5px -24px;
+}
+
+#rcmContextMenu .unread a span
+{
+ background-position: 5px 0px;
+}
+#rcmContextMenu .flagged a span
+{
+ background-position: 5px -46px;
+}
+
+#rcmContextMenu .unflagged a span
+{
+ background-position: 5px -72px;
+}
+
+#rcmContextMenu .reply a span
+{
+ background-position: 5px -120px;
+}
+
+#rcmContextMenu .replyall a span, #rcmContextMenu .replylist a span
+{
+ background-position: 5px -144px;
+}
+
+#rcmContextMenu .forwardinline a span, #rcmContextMenu .forwardattachment a span
+{
+ background-position: 5px -167px;
+}
+
+#rcmContextMenu .delete a span,
+#rcmAddressMenu .deletecontact a span
+{
+ background-position: 5px -94px;
+}
+
+#rcmFolderMenu .expunge a span
+{
+ background-position: 5px 66px;
+}
+
+#rcmFolderMenu .purge a span
+{
+ background-position: 5px 66px;
+}
+
+#rcmFolderMenu .collapseall a span
+{
+ background-position: 5px -323px;
+}
+
+#rcmFolderMenu .expandall a span
+{
+ background-position: 5px -302px;
+}
+
+#rcmContextMenu ul.moreacts li a span
+{
+ background: url(messageactions.png) no-repeat 5px 30px;
+}
+
+#rcmContextMenu ul.moreacts li.print a span
+{
+ background-position: 5px -48px;
+}
+
+#rcmContextMenu ul.moreacts li.source a span
+{
+ background-position: 5px -72px;
+}
+
+#rcmContextMenu ul.moreacts li.save a span
+{
+ background-position: 5px -24px;
+}
+
+#rcmContextMenu ul.moreacts li.open a span
+{
+ background-position: 5px -96px;
+}
+
+#rcmFolderMenu .openfolder a span
+{
+ background: url(messageactions.png) no-repeat 5px -96px;
+}
+
+#rcmContextMenu ul.moreacts li.edit a span
+{
+ background-position: 5px 0px;
+}
+
+#rcmAddressMenu .editcontact a span
+{
+ background: url(messageactions.png) no-repeat 5px 0px;
+}
+
+#rcmAddressMenu .composeto a span
+{
+ background-position: 5px -279px;
+}
+
+#rcmAddressMenu .removefromgroup a span
+{
+ background-position: 5px -344px;
+}
+
+#rcmContextMenu ul.folders li a span,
+#rcmAddressMenu ul.folders li a span
+{
+ background: url(folders.png) 5px 3px no-repeat;
+}
+
+#rcmContextMenu ul.folders li.subfolder a span
+{
+ background-position: 5px -39px;
+}
+
+
+#rcmContextMenu ul.folders li.inbox a span
+{
+ background-position: 5px -61px;
+}
+
+#rcmContextMenu ul.folders li.drafts a span
+{
+ background-position: 5px -84px;
+}
+
+#rcmContextMenu ul.folders li.sent a span
+{
+ background-position: 5px -106px;
+}
+
+#rcmContextMenu ul.folders li.junk a span
+{
+ background-position: 5px -132px;
+}
+
+#rcmContextMenu ul.folders li.trash a span
+{
+ background-position: 5px -159px;
+}
+
+#rcmAddressMenu ul.folders li.addressbook a span
+{
+ background-position: 5px -183px;
+}
+
+#rcmAddressMenu ul.folders li.contactgroup a span
+{
+ background-position: 5px -209px;
+}
+
+#rcmContextMenu div.popupmenu,
+#rcmFolderMenu div.popupmenu,
+#rcmAddressMenu div.popupmenu
+{
+ height: 129px;
+ padding: 0;
+}
+
+#rcmContextMenu ul.scrollable,
+#rcmFolderMenu ul.scrollable,
+#rcmAddressMenu ul.scrollable
+{
+ top: 15px;
+ height: 100px;
+ overflow: hidden;
+ border-top: 0;
+ border-bottom: 0;
+ margin: 0;
+}
+
+#rcmContextMenu li div,
+#rcmFolderMenu li div,
+#rcmAddressMenu li div
+{
+ height: 12px;
+ overflow: hidden;
+ background: url(contexticons.png) #444 no-repeat center 20px;
+}
+
+#rcmContextMenu li div.scroll_up_act,
+#rcmFolderMenu li div.scroll_up_act,
+#rcmAddressMenu li div.scroll_up_act
+{
+ background-position: center -216px;
+ border-bottom: 0;
+ cursor: pointer;
+}
+
+#rcmContextMenu li div.scroll_up_pas,
+#rcmFolderMenu li div.scroll_up_pas,
+#rcmAddressMenu li div.scroll_up_pas
+{
+ background-position: center -233px;
+ border-bottom: 0;
+ cursor: default;
+}
+
+#rcmContextMenu li div.scroll_down_act,
+#rcmFolderMenu li div.scroll_down_act,
+#rcmAddressMenu li div.scroll_down_act
+{
+ top: 117px;
+ background-position: center -251px;
+ border-top: 0;
+ cursor: pointer;
+}
+
+#rcmContextMenu li div.scroll_down_pas,
+#rcmFolderMenu li div.scroll_down_pas,
+#rcmAddressMenu li div.scroll_down_pas
+{
+ top: 117px;
+ background-position: center -270px;
+ border-top: 0;
+ cursor: default;
+} \ No newline at end of file
diff --git a/plugins/contextmenu/skins/larry/folders.png b/plugins/contextmenu/skins/larry/folders.png
new file mode 100644
index 000000000..ce6f3e3db
--- /dev/null
+++ b/plugins/contextmenu/skins/larry/folders.png
Binary files differ
diff --git a/plugins/contextmenu/skins/larry/ie6hacks.css b/plugins/contextmenu/skins/larry/ie6hacks.css
new file mode 100644
index 000000000..effc427f9
--- /dev/null
+++ b/plugins/contextmenu/skins/larry/ie6hacks.css
@@ -0,0 +1,3 @@
+/**
+ * ContextMenu plugin styles (IE6 hacks)
+ */
diff --git a/plugins/contextmenu/skins/larry/messageactions.png b/plugins/contextmenu/skins/larry/messageactions.png
new file mode 100644
index 000000000..156c23970
--- /dev/null
+++ b/plugins/contextmenu/skins/larry/messageactions.png
Binary files differ
diff --git a/plugins/copymessage/copymessage.js b/plugins/copymessage/copymessage.js
new file mode 100644
index 000000000..046edc073
--- /dev/null
+++ b/plugins/copymessage/copymessage.js
@@ -0,0 +1,40 @@
+/**
+ * CopyMessage plugin script
+ */
+
+function rcmail_copyto(command, el, pos) {
+ if (rcmail.env.rcm_destfolder == rcmail.env.mailbox)
+ return;
+
+ var prev_sel = null;
+
+ // also select childs of (collapsed) threads
+ if (rcmail.env.uid) {
+ if (!rcmail.message_list.in_selection(rcmail.env.uid)) {
+ prev_sel = rcmail.message_list.get_selection();
+ rcmail.message_list.select_row(rcmail.env.uid);
+ }
+
+ if (rcmail.message_list.rows[rcmail.env.uid].has_children && !rcmail.message_list.rows[rcmail.env.uid].expanded)
+ rcmail.message_list.select_childs(rcmail.env.uid);
+
+ rcmail.env.uid = null;
+ }
+
+ rcmail.command('copy', rcmail.env.rcm_destfolder, $(el));
+
+ if (prev_sel) {
+ rcmail.message_list.clear_selection();
+
+ for (var i in prev_sel)
+ rcmail.message_list.select_row(prev_sel[i], CONTROL_KEY);
+ }
+
+ delete rcmail.env.rcm_destfolder;
+}
+
+$(document).ready(function(){
+ if (window.rcm_contextmenu_register_command) {
+ rcm_contextmenu_register_command('copy', 'rcmail_copyto', $('#rcmContextCopy'), 'moreacts', 'after', true);
+ }
+}); \ No newline at end of file
diff --git a/plugins/copymessage/copymessage.php b/plugins/copymessage/copymessage.php
new file mode 100644
index 000000000..a8658734c
--- /dev/null
+++ b/plugins/copymessage/copymessage.php
@@ -0,0 +1,114 @@
+<?php
+
+/**
+ * CopyMessage
+ *
+ * Plugin to allow message to be copied to different folders
+ *
+ * @version @package_version@
+ * @requires ContextMenu plugin
+ * @author Philip Weir
+ */
+class copymessage extends rcube_plugin
+{
+ public $task = 'mail';
+
+ function init()
+ {
+ // load required plugin
+ $this->require_plugin('contextmenu');
+
+ $rcmail = rcube::get_instance();
+ if ($rcmail->action == '')
+ $this->add_hook('render_mailboxlist', array($this, 'show_copy_contextmenu'));
+ }
+
+ public function show_copy_contextmenu($args)
+ {
+ $rcmail = rcube::get_instance();
+ $this->add_texts('localization/');
+ $this->api->output->add_label('copymessage.copyingmessage');
+ $this->include_script('copymessage.js');
+
+ $li = html::tag('li', array('class' => 'submenu copyto'), html::span(null, rcmail::Q($this->gettext('copyto'))) . $this->_gen_folder_list($args['list'], '#copy'));
+ $out .= html::tag('ul', array('id' => 'rcmContextCopy'), $li);
+ $this->api->output->add_footer(html::div(array('style' => 'display: none;'), $out));
+ }
+
+ // based on rcmail->render_folder_tree_html()
+ private function _gen_folder_list($arrFolders, $command, $nestLevel = 0, &$folderTotal = 0)
+ {
+ $rcmail = rcube::get_instance();
+
+ $maxlength = 35;
+ $realnames = false;
+
+ $out = '';
+ foreach ($arrFolders as $key => $folder) {
+ $title = null;
+
+ if (($folder_class = $rcmail->folder_classname($folder['id'])) && !$realnames) {
+ $foldername = $rcmail->gettext($folder_class);
+ }
+ else {
+ $foldername = $folder['name'];
+
+ // shorten the folder name to a given length
+ if ($maxlength && $maxlength > 1) {
+ $fname = abbreviate_string($foldername, $maxlength);
+
+ if ($fname != $foldername)
+ $title = $foldername;
+
+ $foldername = $fname;
+ }
+ }
+
+ // make folder name safe for ids and class names
+ $folder_id = asciiwords($folder['id'], true, '_');
+ $classes = array();
+
+ // set special class for Sent, Drafts, Trash and Junk
+ if ($folder['id'] == $rcmail->config->get('sent_mbox'))
+ $classes[] = 'sent';
+ else if ($folder['id'] == $rcmail->config->get('drafts_mbox'))
+ $classes[] = 'drafts';
+ else if ($folder['id'] == $rcmail->config->get('trash_mbox'))
+ $classes[] = 'trash';
+ else if ($folder['id'] == $rcmail->config->get('junk_mbox'))
+ $classes[] = 'junk';
+ else if ($folder['id'] == 'INBOX')
+ $classes[] = 'inbox';
+ else
+ $classes[] = '_'.asciiwords($folder_class ? $folder_class : strtolower($folder['id']), true);
+
+ if ($folder['virtual'])
+ $classes[] = 'virtual';
+
+ if ($nestLevel > 0)
+ $classes[] = 'subfolder';
+
+ $out .= html::tag('li', array('class' => join(' ', $classes)), html::a(array('href' => $command, 'onclick' => "rcm_set_dest_folder('" . rcmail::JQ($folder['id']) ."')", 'class' => 'active', 'title' => $title), html::span(null, str_repeat('&nbsp;&nbsp;', $nestLevel) . rcmail::Q($foldername))));
+
+ if (!empty($folder['folders']))
+ $out .= $this->_gen_folder_list($folder['folders'], $command, $nestLevel+1, $folderTotal);
+
+ $folderTotal++;
+ }
+
+ if ($nestLevel == 0) {
+ if ($folderTotal > 5) {
+ $out = html::tag('ul', array('class' => 'toolbarmenu folders scrollable'), $out);
+ $out = html::tag('div', array('class' => 'scroll_up_pas'), '') . $out . html::tag('div', array('class' => 'scroll_down_act'), '');
+ $out = html::tag('div', array('class' => 'popupmenu'), $out);
+ }
+ else {
+ $out = html::tag('ul', array('class' => 'popupmenu toolbarmenu folders'), $out);
+ }
+ }
+
+ return $out;
+ }
+}
+
+?> \ No newline at end of file
diff --git a/plugins/copymessage/localization/ca_ES.inc b/plugins/copymessage/localization/ca_ES.inc
new file mode 100644
index 000000000..f5fdf3005
--- /dev/null
+++ b/plugins/copymessage/localization/ca_ES.inc
@@ -0,0 +1,9 @@
+<?php
+/* Author: Daniel López */
+
+$labels = array();
+$labels['copyto'] = 'Copia a ...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/copymessage/localization/cs_CZ.inc b/plugins/copymessage/localization/cs_CZ.inc
new file mode 100644
index 000000000..713bda6ee
--- /dev/null
+++ b/plugins/copymessage/localization/cs_CZ.inc
@@ -0,0 +1,9 @@
+<?php
+/* Author: Ales Pospichal */
+
+$labels = array();
+$labels['copyto'] = 'Kopírovat do...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/copymessage/localization/da_DK.inc b/plugins/copymessage/localization/da_DK.inc
new file mode 100644
index 000000000..fa635135c
--- /dev/null
+++ b/plugins/copymessage/localization/da_DK.inc
@@ -0,0 +1,9 @@
+<?php
+/* Author: John Loft Christiansen */
+
+$labels = array();
+$labels['copyto'] = 'Kopier til...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/copymessage/localization/de_CH.inc b/plugins/copymessage/localization/de_CH.inc
new file mode 100644
index 000000000..b0bba791a
--- /dev/null
+++ b/plugins/copymessage/localization/de_CH.inc
@@ -0,0 +1,9 @@
+<?php
+/* Author: Roland Liebl */
+
+$labels = array();
+$labels['copyto'] = 'Kopieren nach...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/copymessage/localization/de_DE.inc b/plugins/copymessage/localization/de_DE.inc
new file mode 100644
index 000000000..b0bba791a
--- /dev/null
+++ b/plugins/copymessage/localization/de_DE.inc
@@ -0,0 +1,9 @@
+<?php
+/* Author: Roland Liebl */
+
+$labels = array();
+$labels['copyto'] = 'Kopieren nach...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/copymessage/localization/en_GB.inc b/plugins/copymessage/localization/en_GB.inc
new file mode 100644
index 000000000..43e15c37d
--- /dev/null
+++ b/plugins/copymessage/localization/en_GB.inc
@@ -0,0 +1,9 @@
+<?php
+/* Author: Philip Weir */
+
+$labels = array();
+$labels['copyto'] = 'Copy to...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/copymessage/localization/en_US.inc b/plugins/copymessage/localization/en_US.inc
new file mode 100644
index 000000000..43e15c37d
--- /dev/null
+++ b/plugins/copymessage/localization/en_US.inc
@@ -0,0 +1,9 @@
+<?php
+/* Author: Philip Weir */
+
+$labels = array();
+$labels['copyto'] = 'Copy to...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/copymessage/localization/es_ES.inc b/plugins/copymessage/localization/es_ES.inc
new file mode 100644
index 000000000..00893bf8b
--- /dev/null
+++ b/plugins/copymessage/localization/es_ES.inc
@@ -0,0 +1,9 @@
+<?php
+/* Author: Daniel López */
+
+$labels = array();
+$labels['copyto'] = 'Copiar a...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/copymessage/localization/fr_FR.inc b/plugins/copymessage/localization/fr_FR.inc
new file mode 100644
index 000000000..6f03d47c8
--- /dev/null
+++ b/plugins/copymessage/localization/fr_FR.inc
@@ -0,0 +1,9 @@
+<?php
+/* Author: */
+
+$labels = array();
+$labels['copyto'] = 'Copier vers...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/copymessage/localization/gl_ES.inc b/plugins/copymessage/localization/gl_ES.inc
new file mode 100644
index 000000000..4f1050805
--- /dev/null
+++ b/plugins/copymessage/localization/gl_ES.inc
@@ -0,0 +1,9 @@
+<?php
+/* Author: David Garabana Barro */
+
+$labels = array();
+$labels['copyto'] = 'Copiar a...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/copymessage/localization/hu_HU.inc b/plugins/copymessage/localization/hu_HU.inc
new file mode 100644
index 000000000..937b34196
--- /dev/null
+++ b/plugins/copymessage/localization/hu_HU.inc
@@ -0,0 +1,9 @@
+<?php
+/* Author: Németh János */
+
+$labels = array();
+$labels['copyto'] = 'Másolás...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/copymessage/localization/it_IT.inc b/plugins/copymessage/localization/it_IT.inc
new file mode 100644
index 000000000..ca2248dd6
--- /dev/null
+++ b/plugins/copymessage/localization/it_IT.inc
@@ -0,0 +1,9 @@
+<?php
+/* Author: Alessio Cecchi */
+
+$labels = array();
+$labels['copyto'] = 'Copia in...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/copymessage/localization/nl_NL.inc b/plugins/copymessage/localization/nl_NL.inc
new file mode 100644
index 000000000..bf7c4e510
--- /dev/null
+++ b/plugins/copymessage/localization/nl_NL.inc
@@ -0,0 +1,9 @@
+<?php
+/* Author: Wouter Kevenaar */
+
+$labels = array();
+$labels['copyto'] = 'Kopiëren naar...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/copymessage/localization/pl_PL.inc b/plugins/copymessage/localization/pl_PL.inc
new file mode 100644
index 000000000..803b4d0d0
--- /dev/null
+++ b/plugins/copymessage/localization/pl_PL.inc
@@ -0,0 +1,9 @@
+<?php
+/* Author: Michał Jałocha */
+
+$labels = array();
+$labels['copyto'] = 'Kopiuj do...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/copymessage/localization/pt_BR.inc b/plugins/copymessage/localization/pt_BR.inc
new file mode 100644
index 000000000..f5ba8c67d
--- /dev/null
+++ b/plugins/copymessage/localization/pt_BR.inc
@@ -0,0 +1,9 @@
+<?php
+/* Author: Alexandre Gorges */
+
+$labels = array();
+$labels['copyto'] = 'Copiar para...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/copymessage/localization/ro_RO.inc b/plugins/copymessage/localization/ro_RO.inc
new file mode 100644
index 000000000..82ebd71f7
--- /dev/null
+++ b/plugins/copymessage/localization/ro_RO.inc
@@ -0,0 +1,9 @@
+<?php
+/* Author: Ovidiu Bica */
+
+$labels = array();
+$labels['copyto'] = 'Copiaza in';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/copymessage/localization/ru_RU.inc b/plugins/copymessage/localization/ru_RU.inc
new file mode 100644
index 000000000..040d7d544
--- /dev/null
+++ b/plugins/copymessage/localization/ru_RU.inc
@@ -0,0 +1,9 @@
+<?php
+/* Author: Peter Zotov */
+
+$labels = array();
+$labels['copyto'] = 'Скопировать в...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/copymessage/localization/sv_SE.inc b/plugins/copymessage/localization/sv_SE.inc
new file mode 100644
index 000000000..e7b203a18
--- /dev/null
+++ b/plugins/copymessage/localization/sv_SE.inc
@@ -0,0 +1,9 @@
+<?php
+/* Author: Jonas Nasholm */
+
+$labels = array();
+$labels['copyto'] = 'Kopiera till...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/copymessage/localization/tr_TR.inc b/plugins/copymessage/localization/tr_TR.inc
new file mode 100644
index 000000000..c64145d07
--- /dev/null
+++ b/plugins/copymessage/localization/tr_TR.inc
@@ -0,0 +1,9 @@
+<?php
+/* Author: Mustafa Icer */
+
+$labels = array();
+$labels['copyto'] = '... kopyala';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/copymessage/package.xml b/plugins/copymessage/package.xml
new file mode 100644
index 000000000..0b699220d
--- /dev/null
+++ b/plugins/copymessage/package.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<package xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" packagerversion="1.9.0" version="2.0" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0
+ http://pear.php.net/dtd/tasks-1.0.xsd
+ http://pear.php.net/dtd/package-2.0
+ http://pear.php.net/dtd/package-2.0.xsd">
+ <name>copymessage</name>
+ <uri>http://github.com/JohnDoh/Roundcube-Plugin-Copy-Message/</uri>
+ <summary>Adds a copy message option to the context menu</summary>
+ <description>Adds a copy message option to the context menu, allowing messages to be copied to another folder.</description>
+ <lead>
+ <name>Philip Weir</name>
+ <user>JohnDoh</user>
+ <email>roundcube@tehinterweb.co.uk</email>
+ <active>yes</active>
+ </lead>
+ <date>2013-02-24</date>
+ <time>10:16:53</time>
+ <version>
+ <release>1.3</release>
+ <api>1.3</api>
+ </version>
+ <stability>
+ <release>stable</release>
+ <api>stable</api>
+ </stability>
+ <license uri="http://www.gnu.org/licenses/gpl.html">GNU GPLv3+</license>
+ <notes>Repo only</notes>
+ <contents>
+ <dir baseinstalldir="/" name="/">
+ <file name="copymessage.php" role="php">
+ <tasks:replace from="@name@" to="name" type="package-info"/>
+ <tasks:replace from="@package_version@" to="version" type="package-info"/>
+ </file>
+ <file name="copymessage.js" role="data">
+ <tasks:replace from="@name@" to="name" type="package-info"/>
+ <tasks:replace from="@package_version@" to="version" type="package-info"/>
+ </file>
+ <file name="CHANGELOG" role="data"/>
+ <file name="README.md" role="data"/>
+ <file name="localization/ca_ES.inc" role="data"/>
+ <file name="localization/cs_CZ.inc" role="data"/>
+ <file name="localization/da_DK.inc" role="data"/>
+ <file name="localization/de_CH.inc" role="data"/>
+ <file name="localization/de_DE.inc" role="data"/>
+ <file name="localization/en_GB.inc" role="data"/>
+ <file name="localization/en_US.inc" role="data"/>
+ <file name="localization/es_ES.inc" role="data"/>
+ <file name="localization/fr_FR.inc" role="data"/>
+ <file name="localization/gl_ES.inc" role="data"/>
+ <file name="localization/hu_HU.inc" role="data"/>
+ <file name="localization/it_IT.inc" role="data"/>
+ <file name="localization/nl_NL.inc" role="data"/>
+ <file name="localization/pl_PL.inc" role="data"/>
+ <file name="localization/pt_BR.inc" role="data"/>
+ <file name="localization/ro_RO.inc" role="data"/>
+ <file name="localization/ru_RU.inc" role="data"/>
+ <file name="localization/sv_SE.inc" role="data"/>
+ <file name="localization/tr_TR.inc" role="data"/>
+ </dir>
+ <!-- / -->
+ </contents>
+ <dependencies>
+ <required>
+ <php>
+ <min>5.2.1</min>
+ </php>
+ <pearinstaller>
+ <min>1.7.0</min>
+ </pearinstaller>
+ <package>
+ <name>contextmenu</name>
+ <uri>http://github.com/JohnDoh/Roundcube-Plugin-Context-Menu/</uri>
+ <min>1.9</min>
+ </package>
+ </required>
+ </dependencies>
+ <phprelease/>
+</package>
diff --git a/plugins/dkimstatus/dkimstatus.php b/plugins/dkimstatus/dkimstatus.php
new file mode 100644
index 000000000..a26fac4af
--- /dev/null
+++ b/plugins/dkimstatus/dkimstatus.php
@@ -0,0 +1,155 @@
+<?php
+
+/**
+ * This plugin displays an icon showing the status
+ * of dkim verification of the message
+ *
+ * @version 0.4.7
+ * @author Julien vehent
+ * @mail julien@linuxwall.info
+ *
+ * original plugin from Vladimir Mach - wladik@gmail.com
+ * http://www.wladik.net
+ *
+ * Changelog:
+ * 20110912 - Added X-Spam-Status for spamassassin (thanks Ashish Shukla for the patch)
+ * 20110619 - Added License information for GPLv2
+ * 20110406 - added italian translation from Roberto Puzzanghera
+ * 20110128 - updated german translation by Simon
+ * 20101118 - japanese translation from Taka
+ * 20100811 - from Sergio Cambra: SPF fix, image function and spanish translation
+ * 20100202 - fix for amavis and add cz translation
+ * 20100201 - add control of header.i and header.from to detect third party signature, change icons
+ * 20100115 - add 'no information' status with image using x-dkim-authentication-results
+ * 20090920 - fixed space in matching status (thanks Pim Pronk for suggestion)
+ */
+class dkimstatus extends rcube_plugin
+{
+ public $task = 'mail';
+ function init()
+ {
+ $rcmail = rcmail::get_instance();
+ if ($rcmail->action == 'show' || $rcmail->action == 'preview') {
+ $this->add_hook('imap_init', array($this, 'imap_init'));
+ $this->add_hook('message_headers_output', array($this, 'message_headers'));
+ } else if ($rcmail->action == '') {
+ // with enabled_caching we're fetching additional headers before show/preview
+ $this->add_hook('imap_init', array($this, 'imap_init'));
+ }
+ }
+
+ function imap_init($p)
+ {
+ $rcmail = rcmail::get_instance();
+ $p['fetch_headers'] = trim($p['fetch_headers'].' ' . strtoupper('Authentication-Results').' '. strtoupper('X-DKIM-Authentication-Results').' ' .strtoupper('X-Spam-Status'));
+ return $p;
+ }
+
+ function image($image, $alt, $title)
+ {
+ return '<img src="plugins/dkimstatus/images/'.$image.'" alt="'.$this->gettext($alt).'" title="'.$this->gettext($alt).$title.'" /> ';
+ }
+
+ function message_headers($p)
+ {
+ $this->add_texts('localization');
+
+ /* First, if dkimproxy did not find a signature, stop here
+ */
+ if($p['headers']->others['x-dkim-authentication-results'] || $p['headers']->others['authentication-results'] || $p['headers']->others['x-spam-status']){
+
+ $results = $p['headers']->others['x-dkim-authentication-results'];
+
+ if(preg_match("/none/", $results)) {
+ $image = 'nosiginfo.png';
+ $alt = 'nosignature';
+ } else {
+ /* Second, check the authentication-results header
+ */
+ if($p['headers']->others['authentication-results']) {
+
+ $results = $p['headers']->others['authentication-results'];
+
+ if(preg_match("/dkim=([a-zA-Z0-9]*)/", $results, $m)) {
+ $status = ($m[1]);
+ }
+
+ if(preg_match("/domainkeys=([a-zA-Z0-9]*)/", $results, $m)) {
+ $status = ($m[1]);
+ }
+
+
+ if($status == 'pass') {
+
+ /* Verify if its an author's domain signature or a third party
+ */
+
+ if(preg_match("/[@][a-zA-Z0-9]+([.][a-zA-Z0-9]+)?\.[a-zA-Z]{2,4}/", $p['headers']->from, $m)) {
+ $authordomain = $m[0];
+ if(preg_match("/header\.i=(([a-zA-Z0-9]+[_\.\-]?)+)?($authordomain)/", $results) ||
+ preg_match("/header\.from=(([a-zA-Z0-9]+[_\.\-]?)+)?($authordomain)/", $results)) {
+ $image = 'authorsign.png';
+ $alt = 'verifiedsender';
+ $title = $results;
+ } else {
+ $image = 'thirdpty.png';
+ $alt = 'thirdpartysig';
+ $title = $results;
+ }
+ }
+
+ }
+ /* If signature proves invalid, show appropriate warning
+ */
+ else if ($status) {
+ $image = 'invalidsig.png';
+ $alt = 'invalidsignature';
+ $title = $results;
+ }
+ /* If no status it can be a spf verification
+ */
+ else {
+ $image = 'nosiginfo.png';
+ $alt = 'nosignature';
+ }
+
+ /* Third, check for spamassassin's X-Spam-Status
+ */
+ } else if ($p['headers']->others['x-spam-status']) {
+
+ $image = 'nosiginfo.png';
+ $alt = 'nosignature';
+
+ /* DKIM_* are defined at: http://search.cpan.org/~kmcgrail/Mail-SpamAssassin-3.3.2/lib/Mail/SpamAssassin/Plugin/DKIM.pm */
+ $results = $p['headers']->others['x-spam-status'];
+ if(preg_match_all('/DKIM_[^,]+/', $results, $m)) {
+ if(array_search('DKIM_SIGNED', $m[0]) !== FALSE) {
+ if(array_search('DKIM_VALID', $m[0]) !== FALSE) {
+ if(array_search('DKIM_VALID_AU', $m[0])) {
+ $image = 'authorsign.png';
+ $alt = 'verifiedsender';
+ $title = 'DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU';
+ } else {
+ $image = 'thirdpty.png';
+ $alt = 'thirdpartysig';
+ $title = 'DKIM_SIGNED, DKIM_VALID';
+ }
+ } else {
+ $image = 'invalidsig.png';
+ $alt = 'invalidsignature';
+ $title = 'DKIM_SIGNED';
+ }
+ }
+ }
+ }
+ }
+ } else {
+ $image = 'nosiginfo.png';
+ $alt = 'nosignature';
+ }
+ if ($image && $alt) {
+ $p['output']['from']['value'] = $this->image($image, $alt, $title) . $p['output']['from']['value'];
+ }
+ return $p;
+ }
+}
diff --git a/plugins/dkimstatus/images/authorsign.png b/plugins/dkimstatus/images/authorsign.png
new file mode 100644
index 000000000..b43bf66b7
--- /dev/null
+++ b/plugins/dkimstatus/images/authorsign.png
Binary files differ
diff --git a/plugins/dkimstatus/images/invalidsig.png b/plugins/dkimstatus/images/invalidsig.png
new file mode 100644
index 000000000..ee42c1183
--- /dev/null
+++ b/plugins/dkimstatus/images/invalidsig.png
Binary files differ
diff --git a/plugins/dkimstatus/images/nosiginfo.png b/plugins/dkimstatus/images/nosiginfo.png
new file mode 100644
index 000000000..4701919cd
--- /dev/null
+++ b/plugins/dkimstatus/images/nosiginfo.png
Binary files differ
diff --git a/plugins/dkimstatus/images/thirdpty.png b/plugins/dkimstatus/images/thirdpty.png
new file mode 100644
index 000000000..a2928859f
--- /dev/null
+++ b/plugins/dkimstatus/images/thirdpty.png
Binary files differ
diff --git a/plugins/dkimstatus/localization/cs_CZ.inc b/plugins/dkimstatus/localization/cs_CZ.inc
new file mode 100644
index 000000000..1017148e8
--- /dev/null
+++ b/plugins/dkimstatus/localization/cs_CZ.inc
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Czech translation
+ *
+ * @version 0.4
+ * @author Vladimír Mach
+ * @mail wladik@gmail.com
+ *
+ */
+$labels = array();
+$labels['verifiedsender'] = 'Platný podpis z domény odesílatele. Ověřil: ';
+$labels['invalidsignature'] = 'Neplatný podpis! Ověřil: ';
+$labels['nosignature'] = 'Podpis není k dospozici.';
+$labels['thirdpartysig'] = 'Podpis odesílatele není k dispozici, ale je tu podpis třetí strany. Ověřil: ';
+
+?>
diff --git a/plugins/dkimstatus/localization/de_DE.inc b/plugins/dkimstatus/localization/de_DE.inc
new file mode 100644
index 000000000..4d52ddcdd
--- /dev/null
+++ b/plugins/dkimstatus/localization/de_DE.inc
@@ -0,0 +1,8 @@
+<?php
+
+$labels = array();
+$labels['verifiedsender'] = 'Die Absenderdomain besitzt eine g&uuml;ltige Unterschrift! &Uuml;berpr&uuml;ft von ';
+$labels['invalidsignature'] = 'Die Unterschrift ist nicht g&uuml;ltig! &Uuml;berpr&uuml;ft von ';
+$labels['nosignature'] = 'Keine Informationen &uuml;ber die Unterschrift vorhanden.';
+$labels['thirdpartysig'] = 'Die Absenderdomain besitzt keine Unterschrift. Es gibt jedoch eine Unterschrift die bestätigt wurde durch ';
+?>
diff --git a/plugins/dkimstatus/localization/en_US.inc b/plugins/dkimstatus/localization/en_US.inc
new file mode 100644
index 000000000..ff20a6874
--- /dev/null
+++ b/plugins/dkimstatus/localization/en_US.inc
@@ -0,0 +1,9 @@
+<?php
+
+$labels = array();
+$labels['verifiedsender'] = 'Valid signature from the author\'s domain. verified by ';
+$labels['invalidsignature'] = 'Signature is not valid ! verified by ';
+$labels['nosignature'] = 'No signature information';
+$labels['thirdpartysig'] = 'No author\'s domain signature but a third party signature is present. verified by ';
+
+?>
diff --git a/plugins/dkimstatus/localization/es_ES.inc b/plugins/dkimstatus/localization/es_ES.inc
new file mode 100644
index 000000000..e7b518dff
--- /dev/null
+++ b/plugins/dkimstatus/localization/es_ES.inc
@@ -0,0 +1,9 @@
+<?php
+
+$labels = array();
+$labels['verifiedsender'] = 'Firma válida del dominio del autor. Verificada por ';
+$labels['invalidsignature'] = '¡La firma no es válida! Verificada por ';
+$labels['nosignature'] = 'Sin información de firma';
+$labels['thirdpartysig'] = 'No hay firma del dominio del autor pero hay una firma de terceros. Verificada por ';
+
+?>
diff --git a/plugins/dkimstatus/localization/fr_FR.inc b/plugins/dkimstatus/localization/fr_FR.inc
new file mode 100644
index 000000000..28fa05145
--- /dev/null
+++ b/plugins/dkimstatus/localization/fr_FR.inc
@@ -0,0 +1,10 @@
+<?php
+
+$labels = array();
+$labels['verifiedsender'] = 'Signature valide provenant du domaine de l\'auteur. verifie par ';
+$labels['invalidsignature'] = 'Signature invalide ! verifie par ';
+$labels['nosignature'] = 'Pas d\'information de signature';
+$labels['thirdpartysig'] = 'Pas de signature du domaine de l\'auteur, mais une signature tierce partie est presente. verifie par ';
+
+
+?>
diff --git a/plugins/dkimstatus/localization/it_IT.inc b/plugins/dkimstatus/localization/it_IT.inc
new file mode 100644
index 000000000..0bd68a124
--- /dev/null
+++ b/plugins/dkimstatus/localization/it_IT.inc
@@ -0,0 +1,7 @@
+<?php
+$labels = array();
+$labels['verifiedsender'] = 'Firma valida dal dominio del mittente. verificato da ';
+$labels['invalidsignature'] = 'La firma non valida! verificato da ';
+$labels['nosignature'] = 'Nessuna informazione sulla firma';
+$labels['thirdpartysig'] = 'Nessuna firma da parte del dominio del mittente ma presente una firma di terza parti. verificato da ';
+?> \ No newline at end of file
diff --git a/plugins/dkimstatus/localization/ja_JP.inc b/plugins/dkimstatus/localization/ja_JP.inc
new file mode 100644
index 000000000..f16829aa6
--- /dev/null
+++ b/plugins/dkimstatus/localization/ja_JP.inc
@@ -0,0 +1,9 @@
+<?php
+
+$labels = array();
+$labels['verifiedsender'] = '送信者のドメインによる正当な署名です。検証内容: ';
+$labels['invalidsignature'] = '不正な署名です! 検証内容: ';
+$labels['nosignature'] = '署名されていません';
+$labels['thirdpartysig'] = '送信者のドメインによる署名はありませんが、第三者による署名があります。検証内容: ';
+
+?>
diff --git a/plugins/dkimstatus/localization/pl_PL.inc b/plugins/dkimstatus/localization/pl_PL.inc
new file mode 100644
index 000000000..a237eb4e5
--- /dev/null
+++ b/plugins/dkimstatus/localization/pl_PL.inc
@@ -0,0 +1,9 @@
+<?php
+
+$labels = array();
+$labels['verifiedsender'] = 'Poprawna sygnatura domeny nadawczej. zweryfikowane przez ';
+$labels['invalidsignature'] = 'Sygnatura nie jest poprawna! zweryfikowane przez ';
+$labels['nosignature'] = 'Brak sygnatury';
+$labels['thirdpartysig'] = 'Brak sygnatury domeny nadawczej. Obecna inny typ sygnatury. zweryfikowane przez ';
+
+?>
diff --git a/plugins/dkimstatus/localization/ro_RO.inc b/plugins/dkimstatus/localization/ro_RO.inc
new file mode 100644
index 000000000..7842492fd
--- /dev/null
+++ b/plugins/dkimstatus/localization/ro_RO.inc
@@ -0,0 +1,9 @@
+<?php
+
+$labels = array();
+$labels['verifiedsender'] = 'Semnat in domeniul autorului. Semnatura comparata si validata de catre ';
+$labels['invalidsignature'] = 'Semnatura falsa! Comparata si invalidata de catre ';
+$labels['nosignature'] = 'Imposibil de comparat si validat semnatura de catre ';
+$labels['thirdpartysig'] = 'Nesemnat in domeniul autorului. O semnatura este prezenta intr-o terta pozitie. Comparat si validat cu aceasta semnatura de catre ';
+
+?>
diff --git a/plugins/dovecot_impersonate/config.inc.php.dist b/plugins/dovecot_impersonate/config.inc.php.dist
new file mode 100644
index 000000000..a631d365f
--- /dev/null
+++ b/plugins/dovecot_impersonate/config.inc.php.dist
@@ -0,0 +1,10 @@
+<?php
+
+// set the dovecot seperator character. Check your dovecot config file for 'auth_master_user_separator'
+//
+// to read about this dovecot feature go to: http://wiki.dovecot.org/Authentication/MasterUsers
+//
+
+$rcmail_config['dovecot_impersonate_seperator'] = '*';
+
+?>
diff --git a/plugins/dovecot_impersonate/dovecot_impersonate.php b/plugins/dovecot_impersonate/dovecot_impersonate.php
new file mode 100644
index 000000000..48165fb4e
--- /dev/null
+++ b/plugins/dovecot_impersonate/dovecot_impersonate.php
@@ -0,0 +1,52 @@
+<?php
+
+/**
+ * This plugin lets you impersonate another user using a master login. Only works with dovecot.
+ *
+ * http://wiki.dovecot.org/Authentication/MasterUsers
+ *
+ * @author Cor Bosman (roundcube@wa.ter.net)
+ */
+
+class dovecot_impersonate extends rcube_plugin {
+
+ public function init()
+ {
+ $this->add_hook('imap_connect', array($this, 'impersonate'));
+ $this->add_hook('managesieve_connect', array($this, 'impersonate'));
+ $this->add_hook('sieverules_connect', array($this, 'impersonate_sieverules'));
+ $this->add_hook('authenticate', array($this, 'login'));
+ }
+
+ function login($data) {
+ // find the seperator character
+ $rcmail = rcmail::get_instance();
+ $this->load_config();
+
+ $seperator = $rcmail->config->get('dovecot_impersonate_seperator', '*');
+
+ if(strpos($data['user'], $seperator)) {
+ $arr = explode($seperator, $data['user']);
+ if(count($arr) == 2) {
+ $data['user'] = $arr[0];
+ $_SESSION['plugin.dovecot_impersonate_master'] = $seperator . $arr[1];
+ }
+ }
+ return($data);
+ }
+
+ function impersonate($data) {
+ if(isset($_SESSION['plugin.dovecot_impersonate_master'])) {
+ $data['user'] = $data['user'] . $_SESSION['plugin.dovecot_impersonate_master'];
+ }
+ return($data);
+ }
+
+ function impersonate_sieverules($data) {
+ if(isset($_SESSION['plugin.dovecot_impersonate_master'])) {
+ $data['username'] = $data['username'] . $_SESSION['plugin.dovecot_impersonate_master'];
+ }
+ return($data);
+ }
+}
+?>
diff --git a/plugins/dovecot_impersonate/package.xml b/plugins/dovecot_impersonate/package.xml
new file mode 100644
index 000000000..3ed45cad8
--- /dev/null
+++ b/plugins/dovecot_impersonate/package.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<package xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" packagerversion="1.9.0" version="2.0" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0
+ http://pear.php.net/dtd/tasks-1.0.xsd
+ http://pear.php.net/dtd/package-2.0
+ http://pear.php.net/dtd/package-2.0.xsd">
+ <name>dovecot_impersonate</name>
+ <lead>
+ <name>Cor Bosman</name>
+ <user>cor</user>
+ <email>cor@roundcu.be</email>
+ <active>yes</active>
+ </lead>
+ <uri>https://github.com/corbosman/dovecot_impersonate</uri>
+ <version>
+ <release>2.0</release>
+ </version>
+ <license uri="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPLv2</license>
+</package>
diff --git a/plugins/enigma/home/aldric/pubring.gpg b/plugins/enigma/home/aldric/pubring.gpg
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/plugins/enigma/home/aldric/pubring.gpg
diff --git a/plugins/enigma/home/aldric/secring.gpg b/plugins/enigma/home/aldric/secring.gpg
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/plugins/enigma/home/aldric/secring.gpg
diff --git a/plugins/enigma/home/aldric/trustdb.gpg b/plugins/enigma/home/aldric/trustdb.gpg
new file mode 100644
index 000000000..c7fb1d524
--- /dev/null
+++ b/plugins/enigma/home/aldric/trustdb.gpg
Binary files differ
diff --git a/plugins/enigma/home/hugues/pubring.gpg b/plugins/enigma/home/hugues/pubring.gpg
new file mode 100644
index 000000000..1cef241de
--- /dev/null
+++ b/plugins/enigma/home/hugues/pubring.gpg
Binary files differ
diff --git a/plugins/enigma/home/hugues/secring.gpg b/plugins/enigma/home/hugues/secring.gpg
new file mode 100644
index 000000000..f9725b338
--- /dev/null
+++ b/plugins/enigma/home/hugues/secring.gpg
Binary files differ
diff --git a/plugins/enigma/home/hugues/trustdb.gpg b/plugins/enigma/home/hugues/trustdb.gpg
new file mode 100644
index 000000000..3bf84308a
--- /dev/null
+++ b/plugins/enigma/home/hugues/trustdb.gpg
Binary files differ
diff --git a/plugins/fail2ban/fail2ban.php b/plugins/fail2ban/fail2ban.php
new file mode 100644
index 000000000..c877e5c98
--- /dev/null
+++ b/plugins/fail2ban/fail2ban.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * RoundCube Fail2Ban Plugin
+ *
+ * @version 1.1
+ * @author Matt Rude [m@mattrude.com]
+ * @url http://mattrude.com/plugins/roundcube-fail2ban-plugin/
+ * @license GPLv3
+ */
+class fail2ban extends rcube_plugin
+{
+ function init()
+ {
+ $this->add_hook('login_failed', array($this, 'log'));
+ }
+
+ function log($args)
+ {
+ $log_entry = 'FAILED login for ' .$args['user']. ' from ' .getenv('REMOTE_ADDR');
+ $log_config = rcmail::get_instance()->config->get('log_driver');
+
+ if ($log_config == 'syslog'){
+ syslog(LOG_WARNING, $log_entry);
+ } elseif ($log_config == 'file'){
+ error_log('['.date('d-M-Y H:i:s O')."]: ".$log_entry."\n", 3, "logs/userlogins");
+ } else {
+ echo 'WARNING!! The RoundCube Fail2Ban Plugin was unable to retrieve the log driver from the config, please check your config file for log_driver.';
+ }
+ }
+
+}
+
+?>
diff --git a/plugins/jqueryui/css b/plugins/jqueryui/css
new file mode 120000
index 000000000..1e77965e6
--- /dev/null
+++ b/plugins/jqueryui/css
@@ -0,0 +1 @@
+../../../javascript/jquery-ui/css \ No newline at end of file
diff --git a/plugins/jqueryui/js/jquery-ui.min.js b/plugins/jqueryui/js/jquery-ui.min.js
new file mode 120000
index 000000000..a9cebcd7a
--- /dev/null
+++ b/plugins/jqueryui/js/jquery-ui.min.js
@@ -0,0 +1 @@
+../../../../javascript/jquery-ui/jquery-ui.min.js \ No newline at end of file
diff --git a/plugins/keyboard_shortcuts/keyboard_shortcuts.css b/plugins/keyboard_shortcuts/keyboard_shortcuts.css
new file mode 100644
index 000000000..cf29e6628
--- /dev/null
+++ b/plugins/keyboard_shortcuts/keyboard_shortcuts.css
@@ -0,0 +1,23 @@
+#keyboard_shortcuts_help {
+ display: none;
+}
+
+#keyboard_shortcuts_help div {
+ float: left;
+ width: 350px;
+}
+
+#keyboard_shortcuts_help div div.shortcut_key {
+ width: 30px;
+ float: left;
+ font-weight: bold;
+ text-align: center;
+}
+
+#keyboard_shortcuts_title {
+ margin-left: 12px;
+}
+
+#keyboard_shortcuts_link {
+ width: 31px !important;
+} \ No newline at end of file
diff --git a/plugins/keyboard_shortcuts/keyboard_shortcuts.js b/plugins/keyboard_shortcuts/keyboard_shortcuts.js
new file mode 100644
index 000000000..440c543e6
--- /dev/null
+++ b/plugins/keyboard_shortcuts/keyboard_shortcuts.js
@@ -0,0 +1,139 @@
+function keyboard_shortcuts_show_help() {
+ $('#keyboard_shortcuts_help').dialog('open');
+}
+
+$(function() {
+ rcmail.env.keyboard_shortcuts = true;
+
+ // initialize a dialog window
+ $('#keyboard_shortcuts_help').dialog({
+ autoOpen: false,
+ draggable: true,
+ modal: false,
+ resizable: false,
+ width: 750,
+ title: rcmail.gettext("keyboard_shortcuts.keyboard_shortcuts")
+ });
+
+ // if we're in an input or textarea form, skip this plugin
+ $('input,textarea').focus(function (e) {
+ rcmail.env.keyboard_shortcuts = false;
+ });
+
+ // if we move out of an input or textarea form, enable this plugin
+ $('input,textarea').blur(function (e) {
+ rcmail.env.keyboard_shortcuts = true;
+ });
+
+ // fire up the keypress event listener
+ $(document).keypress(function (e) {
+ key_pressed(e);
+ });
+
+
+ function key_pressed (e) {
+ if (!rcmail.env.keyboard_shortcuts || rcmail.env.action == 'compose' || rcmail.env.task == 'login' || e.ctrlKey || e.metaKey)
+ return true;
+
+ if (rcmail.env.action == '') { // list mailbox
+
+ if(rcmail.env.ks_functions[e.which]) {
+ this[rcmail.env.ks_functions[e.which]]();
+ return false;
+ }
+
+ switch (e.which) {
+ case 63: // ? = help
+ //keyboard_shortcuts_show_help();
+ var ks_function = rcmail.env.ks_functions[e.which];
+ this[ks_function]();
+
+ return false;
+ case 65: // A = mark all as read
+ rcmail.command('select-all');
+ rcmail.command('mark', 'read');
+ return false;
+ case 67: // C = collapse-all
+ rcmail.command('collapse-all');
+ return false;
+ case 69: // E = expand-all
+ rcmail.command('expand-all');
+ return false;
+ case 82: // R = reply-all
+ if (rcmail.message_list.selection.length == 1)
+ rcmail.command('reply-all');
+ return false;
+ case 85: // U = expand-unread
+ rcmail.command('expand-unread');
+ return false;
+ case 97: // a = select all
+ rcmail.command('select-all');
+ return false;
+ case 99: // c = compose
+ rcmail.command('compose');
+ return false;
+ case 100: // d = delete
+ rcmail.command('delete', '', rcmail);
+ return false;
+ case 102: // f = forward
+ if (rcmail.message_list.selection.length == 1)
+ rcmail.command('forward');
+ return false;
+ case 106: // j = previous page (similar to Gmail)
+ rcmail.command('previouspage');
+ return false;
+ case 107: // k = next page (similar to Gmail)
+ rcmail.command('nextpage');
+ return false;
+ case 112: // p = print
+ if (rcmail.message_list.selection.length == 1)
+ rcmail.command('print');
+ return false;
+ case 114: // r = reply
+ if (rcmail.message_list.selection.length == 1)
+ rcmail.command('reply');
+ return false;
+ case 115: // s = search
+ $('#quicksearchbox').focus();
+ $('#quicksearchbox').select();
+ return false;
+ case 117: // u = update (check for mail)
+ rcmail.command('checkmail');
+ return false;
+ }
+ } else if (rcmail.env.action == 'show' || rcmail.env.action == 'preview') {
+ switch (e.which) {
+ case 82: // R = reply-all
+ rcmail.command('reply-all');
+ return false;
+ case 99: // c = compose
+ rcmail.command('compose');
+ return false;
+ case 100: // d = delete
+ rcmail.command('delete');
+ return false;
+ case 102: // f = forward
+ rcmail.command('forward');
+ return false;
+ case 106: // j = previous message (similar to Gmail)
+ rcmail.command('previousmessage');
+ return false;
+ case 107: // k = next message (similar to Gmail)
+ rcmail.command('nextmessage');
+ return false;
+ case 112: // p = print
+ rcmail.command('print');
+ return false;
+ case 114: // r = reply
+ rcmail.command('reply');
+ return false;
+
+ }
+ }
+ }
+});
+
+// support functions for each function we support
+function ks_help() {
+ keyboard_shortcuts_show_help();
+}
diff --git a/plugins/keyboard_shortcuts/keyboard_shortcuts.php b/plugins/keyboard_shortcuts/keyboard_shortcuts.php
new file mode 100644
index 000000000..3599c7b2f
--- /dev/null
+++ b/plugins/keyboard_shortcuts/keyboard_shortcuts.php
@@ -0,0 +1,130 @@
+<?php
+/**
+ * keyboard_shortcuts
+ *
+ * Enables some common tasks to be executed with keyboard shortcuts
+ *
+ * @version 1.4 - 07.07.2010
+ * @author Patrik Kullman / Roland 'rosali' Liebl / Cor Bosman <roundcube@wa.ter.net>
+ * @licence GNU GPL
+ *
+ **/
+ /** *
+ **/
+
+/**
+ * Shortcuts, list view:
+ * ?: Show shortcut help
+ * a: Select all visible messages
+ * A: Mark all as read (as Google Reader)
+ * c: Compose new message
+ * d: Delete message
+ * f: Forward message
+ * j: Go to previous page of messages (as Gmail)
+ * k: Go to next page of messages (as Gmail)
+ * p: Print message
+ * r: Reply to message
+ * R: Reply to all of message
+ * s: Jump to quicksearch
+ * u: Check for new mail (update)
+ *
+ * Shortcuts, threads view:
+ * E: Expand all
+ * C: Collapse all
+ * U: Expand Unread
+ *
+ * Shortcuts, mail view:
+ * d: Delete message
+ * f: Forward message
+ * j: Go to previous message (as Gmail)
+ * k: Go to next message (as Gmail)
+ * p: Print message
+ * r: Reply to message
+ * R: Reply to all of message
+ */
+
+class keyboard_shortcuts extends rcube_plugin
+{
+ public $task = 'mail';
+
+ function init()
+ {
+ // only init in authenticated state and if newuserdialog is finished
+ // do not init on compose (css incompatibility with compose_addressbook plugin
+ $rcmail = rcmail::get_instance();
+ $this->require_plugin('jqueryui');
+
+ if($_SESSION['username'] && empty($_SESSION['plugin.newuserdialog']) && $rcmail->action != 'compose'){
+ $this->include_stylesheet('keyboard_shortcuts.css');
+ $this->include_script('keyboard_shortcuts.js');
+ $this->add_hook('template_container', array($this, 'html_output'));
+ $this->add_texts('localization', true);
+ }
+ }
+
+ function html_output($p) {
+ if ($p['name'] == "listcontrols") {
+ $rcmail = rcmail::get_instance();
+ $skin = $rcmail->config->get('skin');
+
+ if(!file_exists('plugins/keyboard_shortcuts/skins/' . $skin . '/images/keyboard.png')){
+ $skin = "default";
+ }
+
+ $this->load_config();
+ $keyboard_shortcuts = $rcmail->config->get('keyboard_shortcuts_extras', array());
+
+ $c = "";
+ $c .= '<span id="keyboard_shortcuts_title">' . $this->gettext("title") . ":&nbsp;</span><a id='keyboard_shortcuts_link' href='#' class='button' title='".$this->gettext("show_keyboard_shortcuts")."' onclick='return keyboard_shortcuts_show_help()'><img align='top' src='plugins/keyboard_shortcuts/skins/".$skin."/images/keyboard.png' alt='".$this->gettext("keyboard_shortcuts")." ".$this->gettext("show")."' /></a>\n";
+ $c .= "<div id='keyboard_shortcuts_help'>";
+ $c .= "<div><h4>".$this->gettext("mailboxview")."</h4>";
+ $c .= "<div class='shortcut_key'>?</div> ".$this->gettext('help')."<br class='clear' />";
+ $c .= "<div class='shortcut_key'>a</div> ".$this->gettext('selectallvisiblemessages')."<br class='clear' />";
+ $c .= "<div class='shortcut_key'>A</div> ".$this->gettext('markallvisiblemessagesasread')."<br class='clear' />";
+ $c .= "<div class='shortcut_key'>c</div> ".$this->gettext('compose')."<br class='clear' />";
+ $c .= "<div class='shortcut_key'>d</div> ".$this->gettext('deletemessage')."<br class='clear' />";
+ $c .= "<div class='shortcut_key'>f</div> ".$this->gettext('forwardmessage')."<br class='clear' />";
+ $c .= "<div class='shortcut_key'>j</div> ".$this->gettext('previouspage')."<br class='clear' />";
+ $c .= "<div class='shortcut_key'>k</div> ".$this->gettext('nextpage')."<br class='clear' />";
+ $c .= "<div class='shortcut_key'>p</div> ".$this->gettext('printmessage')."<br class='clear' />";
+ $c .= "<div class='shortcut_key'>r</div> ".$this->gettext('replytomessage')."<br class='clear' />";
+ $c .= "<div class='shortcut_key'>R</div> ".$this->gettext('replytoallmessage')."<br class='clear' />";
+ $c .= "<div class='shortcut_key'>s</div> ".$this->gettext('quicksearch')."<br class='clear' />";
+ $c .= "<div class='shortcut_key'>u</div> ".$this->gettext('checkmail')."<br class='clear' />";
+ $c .= "<div class='shortcut_key'> </div> <br class='clear' />";
+ $c .= "</div>";
+
+ if(!is_object($rcmail->imap)){
+ $rcmail->imap_connect();
+ }
+ $threading_supported = $rcmail->imap->get_capability('thread=references')
+ || $rcmail->imap->get_capability('thread=orderedsubject')
+ || $rcmail->imap->get_capability('thread=refs');
+
+ if ($threading_supported) {
+ $c .= "<div><h4>".$this->gettext("threads")."</h4>";
+ $c .= "<div class='shortcut_key'>E</div> ".$this->gettext('expand-all')."<br class='clear' />";
+ $c .= "<div class='shortcut_key'>C</div> ".$this->gettext('collapse-all')."<br class='clear' />";
+ $c .= "<div class='shortcut_key'>U</div> ".$this->gettext('expand-unread')."<br class='clear' />";
+ $c .= "<div class='shortcut_key'> </div> <br class='clear' />";
+ $c .= "</div>";
+ }
+ $c .= "<div><h4>".$this->gettext("messagesdisplaying")."</h4>";
+ $c .= "<div class='shortcut_key'>d</div> ".$this->gettext('deletemessage')."<br class='clear' />";
+ $c .= "<div class='shortcut_key'>c</div> ".$this->gettext('compose')."<br class='clear' />";
+ $c .= "<div class='shortcut_key'>f</div> ".$this->gettext('forwardmessage')."<br class='clear' />";
+ $c .= "<div class='shortcut_key'>j</div> ".$this->gettext('previousmessage')."<br class='clear' />";
+ $c .= "<div class='shortcut_key'>k</div> ".$this->gettext('nextmessage')."<br class='clear' />";
+ $c .= "<div class='shortcut_key'>p</div> ".$this->gettext('printmessage')."<br class='clear' />";
+ $c .= "<div class='shortcut_key'>r</div> ".$this->gettext('replytomessage')."<br class='clear' />";
+ $c .= "<div class='shortcut_key'>R</div> ".$this->gettext('replytoallmessage')."<br class='clear' />";
+ $c .= "<div class='shortcut_key'> </div> <br class='clear' />";
+ $c .= "</div></div>";
+
+ $rcmail->output->set_env('ks_functions', array('63' => 'ks_help'));
+
+ $p['content'] = $c . $p['content'];
+ }
+ return $p;
+ }
+}
diff --git a/plugins/keyboard_shortcuts/localization/cs_CZ.inc b/plugins/keyboard_shortcuts/localization/cs_CZ.inc
new file mode 100644
index 000000000..edaa05d96
--- /dev/null
+++ b/plugins/keyboard_shortcuts/localization/cs_CZ.inc
@@ -0,0 +1,24 @@
+<?php
+
+/*
++-----------------------------------------------------------------------+
+| language/cs_CZ/labels.inc |
+| |
+| Language file of the RoundCube Webmail client |
+| Copyright (C) 2008-2009, RoundQube Dev. - Switzerland |
+| Licensed under the GNU GPL |
+| |
++-----------------------------------------------------------------------+
+| Author: Ales Pospichal <ales@pospichalales.info> |
++-----------------------------------------------------------------------+
+
+*/
+
+$labels = array();
+$labels['keyboard_shortcuts'] = 'Klávesnicové zkratky';
+$labels['show_keyboard_shortcuts'] = 'Zobrazit klávesnicové zkratky';
+$labels['help'] = 'Nápověda';
+$labels['selectallvisiblemessages'] = 'Vybrat všechny viditelné zprávy';
+$labels['markallvisiblemessagesasread'] = 'Označit všechny viditelné zprávy jako přečtené';
+
+?>
diff --git a/plugins/keyboard_shortcuts/localization/de_DE.inc b/plugins/keyboard_shortcuts/localization/de_DE.inc
new file mode 100644
index 000000000..c7c489514
--- /dev/null
+++ b/plugins/keyboard_shortcuts/localization/de_DE.inc
@@ -0,0 +1,10 @@
+<?php
+
+$labels = array();
+$labels['keyboard_shortcuts'] = 'Tastatur Shortcuts';
+$labels['show_keyboard_shortcuts'] = 'Anzeigen Tastatur Shortcuts';
+$labels['help'] = 'Hilfe';
+$labels['selectallvisiblemessages'] = 'Alle Nachrichten auswählen';
+$labels['markallvisiblemessagesasread'] = 'Alle Nachrichten als gelesen markieren';
+
+?>
diff --git a/plugins/keyboard_shortcuts/localization/en_US.inc b/plugins/keyboard_shortcuts/localization/en_US.inc
new file mode 100644
index 000000000..fcd549f88
--- /dev/null
+++ b/plugins/keyboard_shortcuts/localization/en_US.inc
@@ -0,0 +1,11 @@
+<?php
+
+$labels = array();
+$labels['keyboard_shortcuts'] = 'Keyboard shortcuts';
+$labels['show_keyboard_shortcuts'] = 'Show keyboard shortcuts';
+$labels['help'] = 'Help';
+$labels['selectallvisiblemessages'] = 'Select all visible messages';
+$labels['markallvisiblemessagesasread'] = 'Mark all visible messages as read';
+$labels['title'] = 'Shortcuts';
+
+?>
diff --git a/plugins/keyboard_shortcuts/localization/fr_FR.inc b/plugins/keyboard_shortcuts/localization/fr_FR.inc
new file mode 100644
index 000000000..4ffe7878f
--- /dev/null
+++ b/plugins/keyboard_shortcuts/localization/fr_FR.inc
@@ -0,0 +1,11 @@
+<?php
+
+$labels = array();
+$labels['keyboard_shortcuts'] = 'Raccourcis clavier';
+$labels['show_keyboard_shortcuts'] = 'Voir les raccourcis clavier';
+$labels['help'] = 'Aide';
+$labels['selectallvisiblemessages'] = 'Sélectionner tous les messages visibles';
+$labels['markallvisiblemessagesasread'] = 'Marquer tous les messages visibles comme lus';
+$labels['title'] = 'Raccourcis';
+
+?>
diff --git a/plugins/keyboard_shortcuts/localization/nl_NL.inc b/plugins/keyboard_shortcuts/localization/nl_NL.inc
new file mode 100644
index 000000000..718a1be7f
--- /dev/null
+++ b/plugins/keyboard_shortcuts/localization/nl_NL.inc
@@ -0,0 +1,11 @@
+<?php
+
+$labels = array();
+$labels['keyboard_shortcuts'] = 'Sneltoetsen';
+$labels['show_keyboard_shortcuts'] = 'Show sneltoetsen';
+$labels['help'] = 'Help';
+$labels['selectallvisiblemessages'] = 'Selecteer alle berichten op deze pagina';
+$labels['markallvisiblemessagesasread'] = 'Markeer alle berichten op deze pagina als gelezen';
+$labels['title'] = 'Sneltoetsen';
+
+?>
diff --git a/plugins/keyboard_shortcuts/localization/pl_PL.inc b/plugins/keyboard_shortcuts/localization/pl_PL.inc
new file mode 100644
index 000000000..eafbe7ab8
--- /dev/null
+++ b/plugins/keyboard_shortcuts/localization/pl_PL.inc
@@ -0,0 +1,11 @@
+<?php
+/* Author: DZIOBAK */
+
+$labels = array();
+$labels['keyboard_shortcuts'] = 'Skróty klawiszowe';
+$labels['show_keyboard_shortcuts'] = 'Pokaż skróty klawiszowe';
+$labels['help'] = 'Pomoc';
+$labels['selectallvisiblemessages'] = 'Zaznacz wszystkie widoczne wiadomości';
+$labels['markallvisiblemessagesasread'] = 'Zaznacz wszystkie widoczne wiadomości jako przeczytane';
+
+?>
diff --git a/plugins/keyboard_shortcuts/localization/ru_RU.inc b/plugins/keyboard_shortcuts/localization/ru_RU.inc
new file mode 100644
index 000000000..45f70d84f
--- /dev/null
+++ b/plugins/keyboard_shortcuts/localization/ru_RU.inc
@@ -0,0 +1,11 @@
+<?php
+
+$labels = array();
+$labels['keyboard_shortcuts'] = 'Горячие клавиши';
+$labels['show_keyboard_shortcuts'] = 'Показать Горячие клавиши';
+$labels['help'] = 'Помощь';
+$labels['selectallvisiblemessages'] = 'Выделить все видимые сообщения';
+$labels['markallvisiblemessagesasread'] = 'Пометить все видимые сообщения как прочитанные';
+$labels['title'] = 'Горячие клавиши';
+
+?>
diff --git a/plugins/keyboard_shortcuts/localization/sv_SE.inc b/plugins/keyboard_shortcuts/localization/sv_SE.inc
new file mode 100644
index 000000000..e858e1221
--- /dev/null
+++ b/plugins/keyboard_shortcuts/localization/sv_SE.inc
@@ -0,0 +1,10 @@
+<?php
+
+$labels = array();
+$labels['keyboard_shortcuts'] = 'Kortkommandon';
+$labels['show_keyboard_shortcuts'] = 'Visa kortkommandon';
+$labels['help'] = 'Hj&auml;lp';
+$labels['selectallvisiblemessages'] = 'Markera alla synliga meddelanden';
+$labels['markallvisiblemessagesasread'] = 'Markera alla synliga meddelanden som l&auml;sta';
+
+?>
diff --git a/plugins/keyboard_shortcuts/localization/zh_TW.inc b/plugins/keyboard_shortcuts/localization/zh_TW.inc
new file mode 100644
index 000000000..a198dea38
--- /dev/null
+++ b/plugins/keyboard_shortcuts/localization/zh_TW.inc
@@ -0,0 +1,11 @@
+<?php
+
+$labels = array();
+$labels['keyboard_shortcuts'] = '快速鍵';
+$labels['show_keyboard_shortcuts'] = '顯示快速鍵';
+$labels['help'] = '說明';
+$labels['selectallvisiblemessages'] = '選擇所有此頁的訊息';
+$labels['markallvisiblemessagesasread'] = '標示所有此頁訊息以閱讀';
+$labels['title'] = '快速鍵';
+
+?>
diff --git a/plugins/keyboard_shortcuts/package.xml b/plugins/keyboard_shortcuts/package.xml
new file mode 100644
index 000000000..aa39b0dd9
--- /dev/null
+++ b/plugins/keyboard_shortcuts/package.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<package xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" packagerversion="1.9.0" version="2.0" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0
+ http://pear.php.net/dtd/tasks-1.0.xsd
+ http://pear.php.net/dtd/package-2.0
+ http://pear.php.net/dtd/package-2.0.xsd">
+ <name>keyboard_shortcuts</name>
+ <lead>
+ <name>Cor Bosman</name>
+ <user>cor</user>
+ <email>cor@roundcu.be</email>
+ <active>yes</active>
+ </lead>
+ <uri>https://github.com/corbosman/keyboard_shortcuts</uri>
+ <version>
+ <release>2.0.2</release>
+ </version>
+ <license uri="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPLv2</license>
+</package>
diff --git a/plugins/keyboard_shortcuts/skins/classic/images/keyboard.png b/plugins/keyboard_shortcuts/skins/classic/images/keyboard.png
new file mode 100644
index 000000000..5719b76b2
--- /dev/null
+++ b/plugins/keyboard_shortcuts/skins/classic/images/keyboard.png
Binary files differ
diff --git a/plugins/keyboard_shortcuts/skins/larry/images/keyboard.png b/plugins/keyboard_shortcuts/skins/larry/images/keyboard.png
new file mode 100644
index 000000000..5719b76b2
--- /dev/null
+++ b/plugins/keyboard_shortcuts/skins/larry/images/keyboard.png
Binary files differ
diff --git a/plugins/listcommands/listcommands.php b/plugins/listcommands/listcommands.php
new file mode 100644
index 000000000..7a7948fd6
--- /dev/null
+++ b/plugins/listcommands/listcommands.php
@@ -0,0 +1,106 @@
+<?php
+
+/**
+ * This plugin parses email headers looking for mailinglist specific
+ * information. If headers are found, it uses them to create an additional
+ * header in the header box to easily perform certain mailinglist commands
+ * like subscribing, unsubscribing, asking for help, and sending a new mail.
+ *
+ * @version 2.1
+ * @author Cor Bosman
+ *
+ */
+
+class listcommands extends rcube_plugin
+{
+ public $task = 'mail';
+
+ function init()
+ {
+ $rcmail = rcmail::get_instance();
+ if (!$rcmail->action || in_array($rcmail->action, array('list', 'show', 'preview'))) {
+ $this->add_hook('storage_init', array($this, 'storage_init'));
+ $this->add_hook('message_headers_output', array($this, 'listcommands_output'));
+ }
+ }
+
+ function storage_init($p)
+ {
+ $rcmail = rcmail::get_instance();
+ $mailinglist_headers = array_keys($this->get_list_headers());
+ $p['fetch_headers'] .= trim($p['fetch_headers']. ' ' . strtoupper(join(' ', $mailinglist_headers)));
+ return($p);
+ }
+
+ function listcommands_output($p)
+ {
+ $list_output = "";
+ $rcmail = rcmail::get_instance();
+ $this->add_texts('localization/', false);
+ $mailinglist_headers = $this->get_list_headers();
+
+ foreach ($mailinglist_headers as $header => $title) {
+ $key = strtolower($header);
+
+ if($value = $p['headers']->others[$key]) {
+ if(is_string($value)){
+ $list_output .= $this->create_link($key, $value, $title) . '&nbsp;&nbsp;';
+ }
+ else{
+ $list_output .= $this->create_link($key, $value[0], $title) . '&nbsp;&nbsp;';
+ }
+ }
+ }
+ if($list_output != "")
+ $p['output']['Mailinglist'] = array(
+ 'title' => $this->gettext('listcommands_mailinglist'), 'value' => $list_output);
+ return($p);
+ }
+
+ private function get_list_headers()
+ {
+ $mailinglist_headers = array(
+ 'List-Help' => $this->gettext('listcommands_help'),
+ 'List-Subscribe' => $this->gettext('listcommands_subscribe'),
+ 'List-Unsubscribe' => $this->gettext('listcommands_unsubscribe'),
+ 'List-Post' => $this->gettext('listcommands_post'),
+ 'List-Owner' => $this->gettext('listcommands_admin'),
+ 'List-Archive' => $this->gettext('listcommands_archive')
+ );
+ return($mailinglist_headers);
+ }
+
+ private function create_link($key, $value, $title)
+ {
+ $proto = "";
+
+ // some headers have multiple targets
+ $targets = explode(',', $value);
+
+ // only use 1 of the targets
+ $target = strip_quotes($targets[0]);
+
+ // first strip angle brackets
+ $link = trim($target, "<>");
+
+ if(preg_match('/^(mailto|http|https)(:\/\/|:)(.*)$/', $link, $matches)) {
+ $proto = $matches[1];
+ $target = $matches[3];
+ }
+
+ // use RC for emailing instead of relying on the mailto header
+ if($proto == "mailto") {
+ $onclick = "return rcmail.command('compose','$target',this)";
+ } else {
+ $onclick = "";
+ }
+
+ $a = html::a(array('href' => $link ,
+ 'target' => '_blank',
+ 'onclick' => $onclick
+ ), $title);
+
+ return($a);
+ }
+}
+?>
diff --git a/plugins/listcommands/localization/en_US.inc b/plugins/listcommands/localization/en_US.inc
new file mode 100644
index 000000000..8af9bdc78
--- /dev/null
+++ b/plugins/listcommands/localization/en_US.inc
@@ -0,0 +1,12 @@
+<?php
+
+$labels = array();
+$labels['listcommands_mailinglist'] = 'Mailing List';
+$labels['listcommands_help'] = 'Help';
+$labels['listcommands_subscribe'] = 'Subscribe';
+$labels['listcommands_unsubscribe'] = 'Unsubscribe';
+$labels['listcommands_post'] = 'Post';
+$labels['listcommands_admin'] = 'Contact Administrator';
+$labels['listcommands_archive'] = 'List Archive';
+
+?>
diff --git a/plugins/listcommands/localization/es_ES.inc b/plugins/listcommands/localization/es_ES.inc
new file mode 100644
index 000000000..e27cb8774
--- /dev/null
+++ b/plugins/listcommands/localization/es_ES.inc
@@ -0,0 +1,12 @@
+<?php
+
+$labels = array();
+$labels['listcommands_mailinglist'] = 'Lista de correo';
+$labels['listcommands_help'] = 'Ayuda';
+$labels['listcommands_subscribe'] = 'Darse de alta';
+$labels['listcommands_unsubscribe'] = 'Darse de baja';
+$labels['listcommands_post'] = 'Publicar';
+$labels['listcommands_admin'] = 'Contactar con el administrador';
+$labels['listcommands_archive'] = 'Archivo de la lista';
+
+?>
diff --git a/plugins/listcommands/localization/fr_FR.inc b/plugins/listcommands/localization/fr_FR.inc
new file mode 100644
index 000000000..1a08a1a7b
--- /dev/null
+++ b/plugins/listcommands/localization/fr_FR.inc
@@ -0,0 +1,13 @@
+<?php
+
+$labels = array();
+
+$labels['listcommands_mailinglist'] = 'Mailing List';
+$labels['listcommands_help'] = 'Aide';
+$labels['listcommands_subscribe'] = 'S\'abonner';
+$labels['listcommands_unsubscribe'] = 'Se désabonner';
+$labels['listcommands_post'] = 'Envoyer';
+$labels['listcommands_admin'] = 'Contactez l\'administrateur';
+$labels['listcommands_archive'] = 'Archives de la liste';
+
+?> \ No newline at end of file
diff --git a/plugins/listcommands/localization/nl_NL.inc b/plugins/listcommands/localization/nl_NL.inc
new file mode 100644
index 000000000..373870a83
--- /dev/null
+++ b/plugins/listcommands/localization/nl_NL.inc
@@ -0,0 +1,12 @@
+<?php
+
+$labels = array();
+$labels['listcommands_mailinglist'] = 'Email Lijst';
+$labels['listcommands_help'] = 'Hulp';
+$labels['listcommands_subscribe'] = 'Aanmelden';
+$labels['listcommands_unsubscribe'] = 'Afmelden';
+$labels['listcommands_post'] = 'Nieuw Bericht';
+$labels['listcommands_admin'] = 'Email Beheerder';
+$labels['listcommands_archive'] = 'Lijst Archief';
+
+?>
diff --git a/plugins/listcommands/localization/pl_PL.inc b/plugins/listcommands/localization/pl_PL.inc
new file mode 100644
index 000000000..faefae7ba
--- /dev/null
+++ b/plugins/listcommands/localization/pl_PL.inc
@@ -0,0 +1,12 @@
+<?php
+
+$labels = array();
+$labels['listcommands_mailinglist'] = 'Lista';
+$labels['listcommands_help'] = 'Pomoc';
+$labels['listcommands_subscribe'] = 'Subskrybuj';
+$labels['listcommands_unsubscribe'] = 'Odsubskrybuj';
+$labels['listcommands_post'] = 'Wyślij';
+$labels['listcommands_admin'] = 'Kontakt z administratorem';
+$labels['listcommands_archive'] = 'Archiwum listy';
+
+?>
diff --git a/plugins/listcommands/localization/ru_RU.inc b/plugins/listcommands/localization/ru_RU.inc
new file mode 100644
index 000000000..3565d6cb5
--- /dev/null
+++ b/plugins/listcommands/localization/ru_RU.inc
@@ -0,0 +1,12 @@
+<?php
+
+$labels = array();
+$labels['listcommands_mailinglist'] = 'Рассылка';
+$labels['listcommands_help'] = 'Помощь';
+$labels['listcommands_subscribe'] = 'Подписаться';
+$labels['listcommands_unsubscribe'] = 'Отписаться';
+$labels['listcommands_post'] = 'Ответить в рассылку';
+$labels['listcommands_admin'] = 'Связаться с администратором';
+$labels['listcommands_archive'] = 'Просмотреть Архив';
+
+?> \ No newline at end of file
diff --git a/plugins/listcommands/package.xml b/plugins/listcommands/package.xml
new file mode 100644
index 000000000..6c18bbc1f
--- /dev/null
+++ b/plugins/listcommands/package.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<package xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" packagerversion="1.9.0" version="2.0" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0
+ http://pear.php.net/dtd/tasks-1.0.xsd
+ http://pear.php.net/dtd/package-2.0
+ http://pear.php.net/dtd/package-2.0.xsd">
+ <name>listcommands</name>
+ <lead>
+ <name>Cor Bosman</name>
+ <user>cor</user>
+ <email>cor@roundcu.be</email>
+ <active>yes</active>
+ </lead>
+ <uri>https://github.com/corbosman/listcommands</uri>
+ <version>
+ <release>2.0</release>
+ </version>
+ <license uri="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPLv2</license>
+</package>
diff --git a/plugins/markasjunk2/config.inc.php.dist b/plugins/markasjunk2/config.inc.php.dist
new file mode 100644
index 000000000..7cfcfd5ea
--- /dev/null
+++ b/plugins/markasjunk2/config.inc.php.dist
@@ -0,0 +1,152 @@
+<?php
+
+/**
+ * MarkAsJunk2 configuration file
+ */
+
+// Learning driver
+// Use an external process such as sa-learn to learn from spam/ham messages. Default: null.
+// Please see the README for more information
+$rcmail_config['markasjunk2_learning_driver'] = null;
+
+// Ham mailbox
+// Mailbox messages should be moved to when they are marked as ham. null = INBOX
+// set to FALSE to disable message moving
+$rcmail_config['markasjunk2_ham_mbox'] = null;
+
+// Spam mailbox
+// Mailbox messages should be moved to when they are marked as spam.
+// null = the mailbox assigned as the spam folder in Roundcube settings
+// set to FALSE to disable message moving
+$rcmail_config['markasjunk2_spam_mbox'] = null;
+
+// Mark messages as read when reporting them as spam
+$rcmail_config['markasjunk2_read_spam'] = true;
+
+// Mark messages as unread when reporting them as ham
+$rcmail_config['markasjunk2_unread_ham'] = false;
+
+// Add flag to messages marked as spam (flag will be removed when marking as ham)
+// If you do not want to use message flags set this to null
+$rcmail_config['markasjunk2_spam_flag'] = 'Junk';
+
+// Add flag to messages marked as ham (flag will be removed when marking as spam)
+// If you do not want to use message flags set this to null
+$rcmail_config['markasjunk2_ham_flag'] = null;
+
+// Write output from spam/ham commands to the log for debug
+$rcmail_config['markasjunk2_debug'] = false;
+
+// Show icon on mailbox toolbar
+// The mark as spam/ham icon can either be displayed on the toolbar or as part of the mark messages menu
+$rcmail_config['markasjunk2_mb_toolbar'] = true;
+
+// Show icon on compose toolbar
+// The mark as spam/ham icon can either be displayed on the toolbar or as part of the mark messages menu
+$rcmail_config['markasjunk2_cp_toolbar'] = true;
+
+// Learn any message moved to the spam mailbox as spam (not just when the button is pressed)
+$rcmail_config['markasjunk2_move_spam'] = false;
+
+// Learn any message moved from the spam mailbox to the ham mailbox as ham (not just when the button is pressed)
+$rcmail_config['markasjunk2_move_ham'] = false;
+
+// cmd_learn Driver options
+// ------------------------
+// The command used to learn that a message is spam
+// The command can contain the following macros that will be expanded as follows:
+// %u is replaced with the username (from the session info)
+// %l is replaced with the local part of the username (if the username is an email address)
+// %d is replaced with the domain part of the username (if the username is an email address or default mail domain if not)
+// %i is replaced with the email address from the user's default identity
+// %xds is replaced with the X-DSPAM-Signature header
+// %f is replaced with the path to the message file
+// If you do not want run the command set this to null
+$rcmail_config['markasjunk2_spam_cmd'] = null;
+
+// The command used to learn that a message is ham
+// The command can contain the following macros that will be expanded as follows:
+// %u is replaced with the username (from the session info)
+// %l is replaced with the local part of the username (if the username is an email address)
+// %d is replaced with the domain part of the username (if the username is an email address or default mail domain if not)
+// %i is replaced with the email address from the user's default identity
+// %xds is replaced with the X-DSPAM-Signature header
+// %f is replaced with the path to the message file
+// If you do not want run the command set this to null
+$rcmail_config['markasjunk2_ham_cmd'] = null;
+
+// dir_learn Driver options
+// ------------------------
+// The full path of the directory used to store spam (must be writable by webserver)
+$rcmail_config['markasjunk2_spam_dir'] = null;
+
+// The full path of the directory used to store ham (must be writable by webserver)
+$rcmail_config['markasjunk2_ham_dir'] = null;
+
+// The filename prefix
+// The filename can contain the following macros that will be expanded as follows:
+// %u is replaced with the username (from the session info)
+// %l is replaced with the local part of the username (if the username is an email address)
+// %d is replaced with the domain part of the username (if the username is an email address or default mail domain if not)
+// %t is replaced with the type of message (spam/ham)
+$rcmail_config['markasjunk2_filename'] = null;
+
+// email_learn Driver options
+// --------------------------
+// The email address that spam messages will be sent to
+// The address can contain the following macros that will be expanded as follows:
+// %u is replaced with the username (from the session info)
+// %l is replaced with the local part of the username (if the username is an email address)
+// %d is replaced with the domain part of the username (if the username is an email address or default mail domain if not)
+// %i is replaced with the email address from the user's default identity
+// If you do not want to send an email set this to null
+$rcmail_config['markasjunk2_email_spam'] = null;
+
+// The email address that ham messages will be sent to
+// The address can contain the following macros that will be expanded as follows:
+// %u is replaced with the username (from the session info)
+// %l is replaced with the local part of the username (if the username is an email address)
+// %d is replaced with the domain part of the username (if the username is an email address or default mail domain if not)
+// %i is replaced with the email address from the user's default identity
+// If you do not want to send an email set this to null
+$rcmail_config['markasjunk2_email_ham'] = null;
+
+// Should the spam/ham message be sent as an attachment
+$rcmail_config['markasjunk2_email_attach'] = true;
+
+// The email subject (when sending as attachment)
+// The subject can contain the following macros that will be expanded as follows:
+// %u is replaced with the username (from the session info)
+// %l is replaced with the local part of the username (if the username is an email address)
+// %d is replaced with the domain part of the username (if the username is an email address or default mail domain if not)
+// %t is replaced with the type of message (spam/ham)
+$rcmail_config['markasjunk2_email_subject'] = 'learn this message as %t';
+
+// sa_blacklist Driver options
+// ---------------------------
+// Path to SAUserPrefs config file
+$rcmail_config['markasjunk2_sauserprefs_config'] = '../sauserprefs/config.inc.php';
+
+// edit_headers Driver options
+// ---------------------------
+// Patterns to match and replace headers for spam messages
+// Replacement method uses preg_replace - http://www.php.net/manual/function.preg-replace.php
+// WARNING: Be sure to match the entire header line, including the name of the header, also use ^ and $ and the 'm' flag
+// see the README for an example
+// TEST CAREFULLY BEFORE USE ON REAL MESSAGES
+$rcmail_config['markasjunk2_spam_patterns'] = array(
+ 'patterns' => array(),
+ 'replacements' => array()
+ );
+
+// Patterns to match and replace headers for spam messages
+// Replacement method uses preg_replace - http://www.php.net/manual/function.preg-replace.php
+// WARNING: Be sure to match the entire header line, including the name of the header, also use ^ and $ and the 'm' flag
+// see the README for an example
+// TEST CAREFULLY BEFORE USE ON REAL MESSAGES
+$rcmail_config['markasjunk2_ham_patterns'] = array(
+ 'patterns' => array(),
+ 'replacements' => array()
+ );
+
+?> \ No newline at end of file
diff --git a/plugins/markasjunk2/drivers/cmd_learn.php b/plugins/markasjunk2/drivers/cmd_learn.php
new file mode 100644
index 000000000..f27adc1d1
--- /dev/null
+++ b/plugins/markasjunk2/drivers/cmd_learn.php
@@ -0,0 +1,74 @@
+<?php
+
+/**
+ * Command line learn driver
+ * @version 2.0
+ * @author Philip Weir
+ * Patched by Julien Vehent to support DSPAM
+ * Enhanced support for DSPAM by Stevan Bajic <stevan@bajic.ch>
+ */
+
+class markasjunk2_cmd_learn
+{
+ public function spam($uids)
+ {
+ $this->_do_salearn($uids, true);
+ }
+
+ public function ham($uids)
+ {
+ $this->_do_salearn($uids, false);
+ }
+
+ private function _do_salearn($uids, $spam)
+ {
+ $rcmail = rcube::get_instance();
+ $temp_dir = realpath($rcmail->config->get('temp_dir'));
+
+ if ($spam)
+ $command = $rcmail->config->get('markasjunk2_spam_cmd');
+ else
+ $command = $rcmail->config->get('markasjunk2_ham_cmd');
+
+ if (!$command)
+ return;
+
+ $command = str_replace('%u', $_SESSION['username'], $command);
+ $command = str_replace('%l', $rcmail->user->get_username('local'), $command);
+ $command = str_replace('%d', $rcmail->user->get_username('domain'), $command);
+ if (preg_match('/%i/', $command)) {
+ $identity_arr = $rcmail->user->get_identity();
+ $command = str_replace('%i', $identity_arr['email'], $command);
+ }
+
+ foreach (explode(",", $uids) as $uid) {
+ // get DSPAM signature from header (if %xds macro is used)
+ if (preg_match('/%xds/', $command)) {
+ if (preg_match('/^X\-DSPAM\-Signature:\s+((\d+,)?([a-f\d]+))\s*$/im', $rcmail->storage->get_raw_headers($uid), $dspam_signature))
+ $tmp_command = str_replace('%xds', $dspam_signature[1], $command);
+ else
+ continue; // no DSPAM signature found in headers -> continue with next uid/message
+ }
+
+ if (preg_match('/%f/', $command)) {
+ $tmpfname = tempnam($temp_dir, 'rcmSALearn');
+ file_put_contents($tmpfname, $rcmail->storage->get_raw_body($uid));
+ $tmp_command = str_replace('%f', $tmpfname, $command);
+ }
+
+ exec($tmp_command, $output);
+
+ if ($rcmail->config->get('markasjunk2_debug')) {
+ rcube::write_log('markasjunk2', $tmp_command);
+ rcube::write_log('markasjunk2', $output);
+ }
+
+ if (preg_match('/%f/', $command))
+ unlink($tmpfname);
+
+ $output = '';
+ }
+ }
+}
+
+?> \ No newline at end of file
diff --git a/plugins/markasjunk2/drivers/dir_learn.php b/plugins/markasjunk2/drivers/dir_learn.php
new file mode 100644
index 000000000..88dc7e4eb
--- /dev/null
+++ b/plugins/markasjunk2/drivers/dir_learn.php
@@ -0,0 +1,49 @@
+<?php
+
+/**
+ * Copy spam/ham messages to a direcotry for learning later
+ * @version 2.0
+ * @author Philip Weir
+ */
+
+class markasjunk2_dir_learn
+{
+ public function spam($uids)
+ {
+ $this->_do_messagemove($uids, true);
+ }
+
+ public function ham($uids)
+ {
+ $this->_do_messagemove($uids, false);
+ }
+
+ private function _do_messagemove($uids, $spam)
+ {
+ $rcmail = rcube::get_instance();
+
+ if ($spam)
+ $dest_dir = unslashify($rcmail->config->get('markasjunk2_spam_dir'));
+ else
+ $dest_dir = unslashify($rcmail->config->get('markasjunk2_ham_dir'));
+
+ if (!$dest_dir)
+ return;
+
+ $filename = $rcmail->config->get('markasjunk2_filename');
+ $filename = str_replace('%u', $_SESSION['username'], $filename);
+ $filename = str_replace('%t', ($spam) ? 'spam' : 'ham', $filename);
+ $filename = str_replace('%l', $rcmail->user->get_username('local'), $filename);
+ $filename = str_replace('%d', $rcmail->user->get_username('domain'), $filename);
+
+ foreach (explode(",", $uids) as $uid) {
+ $tmpfname = tempnam($dest_dir, $filename);
+ file_put_contents($tmpfname, $rcmail->storage->get_raw_body($uid));
+
+ if ($rcmail->config->get('markasjunk2_debug'))
+ rcube::write_log('markasjunk2', $tmpfname);
+ }
+ }
+}
+
+?> \ No newline at end of file
diff --git a/plugins/markasjunk2/drivers/edit_headers.php b/plugins/markasjunk2/drivers/edit_headers.php
new file mode 100644
index 000000000..9ee71ff79
--- /dev/null
+++ b/plugins/markasjunk2/drivers/edit_headers.php
@@ -0,0 +1,53 @@
+<?php
+
+/**
+ * Edit headers
+ * @version 1.0
+ * @author Philip Weir
+ */
+
+class markasjunk2_edit_headers
+{
+ public function spam(&$uids)
+ {
+ $this->_edit_headers($uids, true);
+ }
+
+ public function ham(&$uids)
+ {
+ $this->_edit_headers($uids, false);
+ }
+
+ private function _edit_headers(&$uids, $spam)
+ {
+ $rcmail = rcube::get_instance();
+ $args = $spam ? $rcmail->config->get('markasjunk2_spam_patterns') : $rcmail->config->get('markasjunk2_ham_patterns');
+
+ if (sizeof($args['patterns']) == 0)
+ return;
+
+ $mbox = rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_POST);
+
+ $new_uids = array();
+ foreach (explode(",", $uids) as $uid) {
+ $raw_message = $rcmail->storage->get_raw_body($uid);
+ $raw_headers = $rcmail->storage->get_raw_headers($uid);
+
+ $updated_headers = preg_replace($args['patterns'], $args['replacements'], $raw_headers);
+ $raw_message = str_replace($raw_headers, $updated_headers, $raw_message);
+
+ $saved = $rcmail->storage->save_message($mbox, $raw_message);
+
+ if ($saved !== false) {
+ $rcmail->output->command('rcmail_markasjunk2_move', null, $uid);
+ array_push($new_uids, $saved);
+ }
+
+ }
+
+ if (sizeof($new_uids) > 0)
+ $uids = implode(',', $new_uids);
+ }
+}
+
+?> \ No newline at end of file
diff --git a/plugins/markasjunk2/drivers/email_learn.php b/plugins/markasjunk2/drivers/email_learn.php
new file mode 100644
index 000000000..b7f9f87ea
--- /dev/null
+++ b/plugins/markasjunk2/drivers/email_learn.php
@@ -0,0 +1,191 @@
+<?php
+
+/**
+ * Email learn driver
+ * @version 2.0
+ * @author Philip Weir
+ */
+
+class markasjunk2_email_learn
+{
+ public function spam($uids)
+ {
+ $this->_do_emaillearn($uids, true);
+ }
+
+ public function ham($uids)
+ {
+ $this->_do_emaillearn($uids, false);
+ }
+
+ private function _do_emaillearn($uids, $spam)
+ {
+ $rcmail = rcube::get_instance();
+ $identity_arr = $rcmail->user->get_identity();
+ $from = $identity_arr['email'];
+
+ if ($spam)
+ $mailto = $rcmail->config->get('markasjunk2_email_spam');
+ else
+ $mailto = $rcmail->config->get('markasjunk2_email_ham');
+
+ $mailto = str_replace('%u', $_SESSION['username'], $mailto);
+ $mailto = str_replace('%l', $rcmail->user->get_username('local'), $mailto);
+ $mailto = str_replace('%d', $rcmail->user->get_username('domain'), $mailto);
+ $mailto = str_replace('%i', $from, $mailto);
+
+ if (!$mailto)
+ return;
+
+ $message_charset = $rcmail->output->get_charset();
+ // chose transfer encoding
+ $charset_7bit = array('ASCII', 'ISO-2022-JP', 'ISO-8859-1', 'ISO-8859-2', 'ISO-8859-15');
+ $transfer_encoding = in_array(strtoupper($message_charset), $charset_7bit) ? '7bit' : '8bit';
+
+ $temp_dir = realpath($rcmail->config->get('temp_dir'));
+
+ $subject = $rcmail->config->get('markasjunk2_email_subject');
+ $subject = str_replace('%u', $_SESSION['username'], $subject);
+ $subject = str_replace('%t', ($spam) ? 'spam' : 'ham', $subject);
+ $subject = str_replace('%l', $rcmail->user->get_username('local'), $subject);
+ $subject = str_replace('%d', $rcmail->user->get_username('domain'), $subject);
+
+ // compose headers array
+ $headers = array();
+ $headers['Date'] = date('r');
+ $headers['From'] = format_email_recipient($identity_arr['email'], $identity_arr['name']);
+ $headers['To'] = $mailto;
+ $headers['Subject'] = $subject;
+
+ foreach (explode(",", $uids) as $uid) {
+ $MESSAGE = new rcube_message($uid);
+
+ // set message charset as default
+ if (!empty($MESSAGE->headers->charset))
+ $rcmail->storage->set_charset($MESSAGE->headers->charset);
+
+ $MAIL_MIME = new Mail_mime($rcmail->config->header_delimiter());
+
+ if ($rcmail->config->get('markasjunk2_email_attach', false)) {
+ $tmpPath = tempnam($temp_dir, 'rcmMarkASJunk2');
+
+ // send mail as attachment
+ $MAIL_MIME->setTXTBody(($spam ? 'Spam' : 'Ham'). ' report from ' . $rcmail->config->get('product_name'), false, true);
+
+ $raw_message = $rcmail->storage->get_raw_body($uid);
+ $subject = $MESSAGE->get_header('subject');
+
+ if (isset($subject) && $subject !="")
+ $disp_name = $subject . ".eml";
+ else
+ $disp_name = "message_rfc822.eml";
+
+ if (file_put_contents($tmpPath, $raw_message)) {
+ $MAIL_MIME->addAttachment($tmpPath, "message/rfc822", $disp_name, true,
+ $transfer_encoding, 'attachment', '', '', '',
+ $rcmail->config->get('mime_param_folding') ? 'quoted-printable' : NULL,
+ $rcmail->config->get('mime_param_folding') == 2 ? 'quoted-printable' : NULL,
+ '', RCUBE_CHARSET
+ );
+ }
+
+ // encoding settings for mail composing
+ $MAIL_MIME->setParam('text_encoding', $transfer_encoding);
+ $MAIL_MIME->setParam('html_encoding', 'quoted-printable');
+ $MAIL_MIME->setParam('head_encoding', 'quoted-printable');
+ $MAIL_MIME->setParam('head_charset', $message_charset);
+ $MAIL_MIME->setParam('html_charset', $message_charset);
+ $MAIL_MIME->setParam('text_charset', $message_charset);
+
+ // pass headers to message object
+ $MAIL_MIME->headers($headers);
+ }
+ else {
+ $headers['Resent-From'] = $headers['From'];
+ $headers['Resent-Date'] = $headers['Date'];
+ $headers['Date'] = $MESSAGE->headers->date;
+ $headers['From'] = $MESSAGE->headers->from;
+ $headers['Subject'] = $MESSAGE->headers->subject;
+ $MAIL_MIME->headers($headers);
+
+ if ($MESSAGE->has_html_part()) {
+ $body = $MESSAGE->first_html_part();
+ $MAIL_MIME->setHTMLBody($body);
+ }
+
+ $body = $MESSAGE->first_text_part();
+ $MAIL_MIME->setTXTBody($body, false, true);
+
+ foreach ($MESSAGE->attachments as $attachment) {
+ $MAIL_MIME->addAttachment(
+ $MESSAGE->get_part_content($attachment->mime_id),
+ $attachment->mimetype,
+ $attachment->filename,
+ false,
+ $attachment->encoding,
+ $attachment->disposition,
+ '', $attachment->charset
+ );
+ }
+
+ foreach ($MESSAGE->mime_parts as $attachment) {
+ if (!empty($attachment->content_id)) {
+ // covert CID to Mail_MIME format
+ $attachment->content_id = str_replace('<', '', $attachment->content_id);
+ $attachment->content_id = str_replace('>', '', $attachment->content_id);
+
+ if (empty($attachment->filename))
+ $attachment->filename = $attachment->content_id;
+
+ $message_body = $MAIL_MIME->getHTMLBody();
+ $dispurl = 'cid:' . $attachment->content_id;
+ $message_body = str_replace($dispurl, $attachment->filename, $message_body);
+ $MAIL_MIME->setHTMLBody($message_body);
+
+ $MAIL_MIME->addHTMLImage(
+ $MESSAGE->get_part_content($attachment->mime_id),
+ $attachment->mimetype,
+ $attachment->filename,
+ false
+ );
+ }
+ }
+
+ // encoding settings for mail composing
+ $MAIL_MIME->setParam('head_encoding', $MESSAGE->headers->encoding);
+ $MAIL_MIME->setParam('head_charset', $MESSAGE->headers->charset);
+
+ foreach ($MESSAGE->mime_parts as $mime_id => $part) {
+ $mimetype = strtolower($part->ctype_primary . '/' . $part->ctype_secondary);
+
+ if ($mimetype == 'text/html') {
+ $MAIL_MIME->setParam('text_encoding', $part->encoding);
+ $MAIL_MIME->setParam('html_charset', $part->charset);
+ }
+ else if ($mimetype == 'text/plain') {
+ $MAIL_MIME->setParam('html_encoding', $part->encoding);
+ $MAIL_MIME->setParam('text_charset', $part->charset);
+ }
+ }
+ }
+
+ $rcmail->rcmail_deliver_message($MAIL_MIME, $from, $mailto, $smtp_error, $body_file);
+
+ // clean up
+ if (file_exists($tmpPath))
+ unlink($tmpPath);
+
+ if ($rcmail->config->get('markasjunk2_debug')) {
+ if ($spam)
+ rcube::write_log('markasjunk2', $uid . ' SPAM ' . $mailto . ' (' . $subject . ')');
+ else
+ rcube::write_log('markasjunk2', $uid . ' HAM ' . $mailto . ' (' . $subject . ')');
+
+ if ($smtp_error['vars'])
+ rcube::write_log('markasjunk2', $smtp_error['vars']);
+ }
+ }
+ }
+}
+
+?> \ No newline at end of file
diff --git a/plugins/markasjunk2/drivers/sa_blacklist.php b/plugins/markasjunk2/drivers/sa_blacklist.php
new file mode 100644
index 000000000..dd2ce6bc7
--- /dev/null
+++ b/plugins/markasjunk2/drivers/sa_blacklist.php
@@ -0,0 +1,103 @@
+<?php
+
+/**
+ * SpamAssassin Blacklist driver
+ * @version 2.0
+ * @requires SAUserPrefs plugin
+ * @author Philip Weir
+ */
+
+class markasjunk2_sa_blacklist
+{
+ public function spam($uids)
+ {
+ $this->_do_list($uids, true);
+ }
+
+ public function ham($uids)
+ {
+ $this->_do_list($uids, false);
+ }
+
+ private function _do_list($uids, $spam)
+ {
+ $rcmail = rcube::get_instance();
+ if (is_file($rcmail->config->get('markasjunk2_sauserprefs_config')) && !$rcmail->config->load_from_file($rcmail->config->get('markasjunk2_sauserprefs_config'))) {
+ rcube::raise_error(array('code' => 527, 'type' => 'php',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => "Failed to load config from " . $rcmail->config->get('markasjunk2_sauserprefs_config')), true, false);
+ return false;
+ }
+
+ $db = rcube_db::factory($rcmail->config->get('sauserprefs_db_dsnw'), $rcmail->config->get('sauserprefs_db_dsnr'), $rcmail->config->get('sauserprefs_db_persistent'));
+ $db->db_connect('w');
+
+ // check DB connections and exit on failure
+ if ($err_str = $db->is_error()) {
+ rcube::raise_error(array(
+ 'code' => 603,
+ 'type' => 'db',
+ 'message' => $err_str), FALSE, TRUE);
+ }
+
+ foreach (explode(",", $uids) as $uid) {
+ $message = new rcube_message($uid);
+ $email = $message->sender['mailto'];
+
+ if ($spam) {
+ // delete any whitelisting for this address
+ $db->query(
+ "DELETE FROM ". $rcmail->config->get('sauserprefs_sql_table_name') ." WHERE ". $rcmail->config->get('sauserprefs_sql_username_field') ." = ? AND ". $rcmail->config->get('sauserprefs_sql_preference_field') ." = ? AND ". $rcmail->config->get('sauserprefs_sql_value_field') ." = ?;",
+ $_SESSION['username'],
+ 'whitelist_from',
+ $email);
+
+ // check address is not already blacklisted
+ $sql_result = $db->query(
+ "SELECT value FROM ". $rcmail->config->get('sauserprefs_sql_table_name') ." WHERE ". $rcmail->config->get('sauserprefs_sql_username_field') ." = ? AND ". $rcmail->config->get('sauserprefs_sql_preference_field') ." = ? AND ". $rcmail->config->get('sauserprefs_sql_value_field') ." = ?;",
+ $_SESSION['username'],
+ 'blacklist_from',
+ $email);
+
+ if (!$db->fetch_array($sql_result)) {
+ $db->query(
+ "INSERT INTO ". $rcmail->config->get('sauserprefs_sql_table_name') ." (". $rcmail->config->get('sauserprefs_sql_username_field') .", ". $rcmail->config->get('sauserprefs_sql_preference_field') .", ". $rcmail->config->get('sauserprefs_sql_value_field') .") VALUES (?, ?, ?);",
+ $_SESSION['username'],
+ 'blacklist_from',
+ $email);
+
+ if ($rcmail->config->get('markasjunk2_debug'))
+ rcube::write_log('markasjunk2', $_SESSION['username'] . ' blacklist ' . $email);
+ }
+ }
+ else {
+ // delete any blacklisting for this address
+ $db->query(
+ "DELETE FROM ". $rcmail->config->get('sauserprefs_sql_table_name') ." WHERE ". $rcmail->config->get('sauserprefs_sql_username_field') ." = ? AND ". $rcmail->config->get('sauserprefs_sql_preference_field') ." = ? AND ". $rcmail->config->get('sauserprefs_sql_value_field') ." = ?;",
+ $_SESSION['username'],
+ 'blacklist_from',
+ $email);
+
+ // check address is not already whitelisted
+ $sql_result = $db->query(
+ "SELECT value FROM ". $rcmail->config->get('sauserprefs_sql_table_name') ." WHERE ". $rcmail->config->get('sauserprefs_sql_username_field') ." = ? AND ". $rcmail->config->get('sauserprefs_sql_preference_field') ." = ? AND ". $rcmail->config->get('sauserprefs_sql_value_field') ." = ?;",
+ $_SESSION['username'],
+ 'whitelist_from',
+ $email);
+
+ if (!$db->fetch_array($sql_result)) {
+ $db->query(
+ "INSERT INTO ". $rcmail->config->get('sauserprefs_sql_table_name') ." (". $rcmail->config->get('sauserprefs_sql_username_field') .", ". $rcmail->config->get('sauserprefs_sql_preference_field') .", ". $rcmail->config->get('sauserprefs_sql_value_field') .") VALUES (?, ?, ?);",
+ $_SESSION['username'],
+ 'whitelist_from',
+ $email);
+
+ if ($rcmail->config->get('markasjunk2_debug'))
+ rcube::write_log('markasjunk2', $_SESSION['username'] . ' whitelist ' . $email);
+ }
+ }
+ }
+ }
+}
+
+?> \ No newline at end of file
diff --git a/plugins/markasjunk2/drivers/sa_detach.php b/plugins/markasjunk2/drivers/sa_detach.php
new file mode 100644
index 000000000..947b4b8a7
--- /dev/null
+++ b/plugins/markasjunk2/drivers/sa_detach.php
@@ -0,0 +1,47 @@
+<?php
+
+/**
+ * SpamAssassin detach ham driver
+ * @version 2.0
+ * @author Philip Weir
+ */
+
+class markasjunk2_sa_detach
+{
+ public function spam($uids)
+ {
+ // do nothing
+ }
+
+ public function ham(&$uids)
+ {
+ $rcmail = rcube::get_instance();
+ $storage = $rcmail->storage;
+ $mbox = rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_POST);
+
+ $new_uids = array();
+ foreach (explode(",", $uids) as $uid) {
+ $saved = false;
+ $message = new rcube_message($uid);
+
+ if (sizeof($message->attachments) > 0) {
+ foreach ($message->attachments as $part) {
+ if ($part->ctype_primary == 'message' && $part->ctype_secondary == 'rfc822') {
+ $orig_message_raw = $storage->get_message_part($message->uid, $part->mime_id, $part);
+ $saved = $storage->save_message($mbox, $orig_message_raw);
+
+ if ($saved !== false) {
+ $rcmail->output->command('rcmail_markasjunk2_move', null, $uid);
+ array_push($new_uids, $saved);
+ }
+ }
+ }
+ }
+ }
+
+ if (sizeof($new_uids) > 0)
+ $uids = implode(',', $new_uids);
+ }
+}
+
+?> \ No newline at end of file
diff --git a/plugins/markasjunk2/localization/ca_ES.inc b/plugins/markasjunk2/localization/ca_ES.inc
new file mode 100644
index 000000000..2268cf76a
--- /dev/null
+++ b/plugins/markasjunk2/localization/ca_ES.inc
@@ -0,0 +1,14 @@
+<?php
+/* Author: Daniel López */
+
+$labels = array();
+$labels['buttonjunk'] = 'Marca com a Spam';
+$labels['markasjunk'] = 'És Spam';
+$labels['buttonnotjunk'] = 'Aquest missatge no és Spam';
+$labels['markasnotjunk'] = 'No és Spam';
+
+$messages = array();
+$messages['reportedasjunk'] = 'Reportat conrrectament com spam.';
+$messages['reportedasnotjunk'] = 'Missatge mogut a la safata d\'Entrada';
+
+?> \ No newline at end of file
diff --git a/plugins/markasjunk2/localization/cs_CZ.inc b/plugins/markasjunk2/localization/cs_CZ.inc
new file mode 100644
index 000000000..e9564a855
--- /dev/null
+++ b/plugins/markasjunk2/localization/cs_CZ.inc
@@ -0,0 +1,14 @@
+<?php
+/* Author: Martin Frajdl */
+
+$labels = array();
+$labels['buttonjunk'] = 'Oznacit jako spam';
+$labels['markasjunk'] = 'Jako spam';
+$labels['buttonnotjunk'] = 'Tato zpráva není spam';
+$labels['markasnotjunk'] = 'Nemí spam';
+
+$messages = array();
+$messages['reportedasjunk'] = 'Úspešne hlášeny jako spam';
+$messages['reportedasnotjunk'] = 'Úspešne hlášeny jako spam';
+
+?> \ No newline at end of file
diff --git a/plugins/markasjunk2/localization/de_CH.inc b/plugins/markasjunk2/localization/de_CH.inc
new file mode 100644
index 000000000..71492b481
--- /dev/null
+++ b/plugins/markasjunk2/localization/de_CH.inc
@@ -0,0 +1,15 @@
+<?php
+/* Author: Rrainer Rhalbmann */
+
+$labels = array();
+$labels['buttonjunk'] = 'als Spam markieren';
+$labels['markasjunk'] = 'als Spam';
+$labels['buttonnotjunk'] = 'Diese Nachricht ist kein Spam';
+$labels['markasnotjunk'] = 'kein Spam';
+$labels['notjunk'] = 'kein Spam';
+
+$messages = array();
+$messages['reportedasjunk'] = 'Erfolgreich als Spam gekennzeichnet';
+$messages['reportedasnotjunk'] = 'Nachricht in Posteingang verschoben';
+
+?> \ No newline at end of file
diff --git a/plugins/markasjunk2/localization/de_DE.inc b/plugins/markasjunk2/localization/de_DE.inc
new file mode 100644
index 000000000..71492b481
--- /dev/null
+++ b/plugins/markasjunk2/localization/de_DE.inc
@@ -0,0 +1,15 @@
+<?php
+/* Author: Rrainer Rhalbmann */
+
+$labels = array();
+$labels['buttonjunk'] = 'als Spam markieren';
+$labels['markasjunk'] = 'als Spam';
+$labels['buttonnotjunk'] = 'Diese Nachricht ist kein Spam';
+$labels['markasnotjunk'] = 'kein Spam';
+$labels['notjunk'] = 'kein Spam';
+
+$messages = array();
+$messages['reportedasjunk'] = 'Erfolgreich als Spam gekennzeichnet';
+$messages['reportedasnotjunk'] = 'Nachricht in Posteingang verschoben';
+
+?> \ No newline at end of file
diff --git a/plugins/markasjunk2/localization/en_GB.inc b/plugins/markasjunk2/localization/en_GB.inc
new file mode 100644
index 000000000..e63548094
--- /dev/null
+++ b/plugins/markasjunk2/localization/en_GB.inc
@@ -0,0 +1,15 @@
+<?php
+/* Author: Philip Weir */
+
+$labels = array();
+$labels['buttonjunk'] = 'Mark as spam';
+$labels['markasjunk'] = 'As spam';
+$labels['buttonnotjunk'] = 'This message is not spam';
+$labels['markasnotjunk'] = 'As not spam';
+$labels['notjunk'] = 'Not spam';
+
+$messages = array();
+$messages['reportedasjunk'] = 'Successfully reported as spam';
+$messages['reportedasnotjunk'] = 'Successfully reported as not spam';
+
+?> \ No newline at end of file
diff --git a/plugins/markasjunk2/localization/en_US.inc b/plugins/markasjunk2/localization/en_US.inc
new file mode 100644
index 000000000..b67fbedfb
--- /dev/null
+++ b/plugins/markasjunk2/localization/en_US.inc
@@ -0,0 +1,15 @@
+<?php
+/* Author: Philip Weir */
+
+$labels = array();
+$labels['buttonjunk'] = 'Mark as junk';
+$labels['markasjunk'] = 'As junk';
+$labels['buttonnotjunk'] = 'This message is not junk';
+$labels['markasnotjunk'] = 'As not junk';
+$labels['notjunk'] = 'Not junk';
+
+$messages = array();
+$messages['reportedasjunk'] = 'Successfully reported as junk';
+$messages['reportedasnotjunk'] = 'Successfully reported as not junk';
+
+?> \ No newline at end of file
diff --git a/plugins/markasjunk2/localization/es_AR.inc b/plugins/markasjunk2/localization/es_AR.inc
new file mode 100644
index 000000000..2095b0721
--- /dev/null
+++ b/plugins/markasjunk2/localization/es_AR.inc
@@ -0,0 +1,14 @@
+<?php
+/* Author: Guillermo Asernitzky */
+
+$labels = array();
+$labels['buttonjunk'] = 'Marcar como Spam';
+$labels['markasjunk'] = 'Como Spam';
+$labels['buttonnotjunk'] = 'Este mensaje no es Spam';
+$labels['markasnotjunk'] = 'No es Spam';
+
+$messages = array();
+$messages['reportedasjunk'] = 'Reportado como Spam';
+$messages['reportedasnotjunk'] = 'Mensaje movido a la bandeja de entrada';
+
+?> \ No newline at end of file
diff --git a/plugins/markasjunk2/localization/es_ES.inc b/plugins/markasjunk2/localization/es_ES.inc
new file mode 100644
index 000000000..58388f227
--- /dev/null
+++ b/plugins/markasjunk2/localization/es_ES.inc
@@ -0,0 +1,14 @@
+<?php
+/* Author: David Garabana Barro */
+
+$labels = array();
+$labels['buttonjunk'] = 'Marcar como spam';
+$labels['markasjunk'] = 'Es spam';
+$labels['buttonnotjunk'] = 'Este mensaje no es spam';
+$labels['markasnotjunk'] = 'No es spam';
+
+$messages = array();
+$messages['reportedasjunk'] = 'Reportado correctamente como spam.';
+$messages['reportedasnotjunk'] = 'Movido a la bandeja de entrada.';
+
+?> \ No newline at end of file
diff --git a/plugins/markasjunk2/localization/fa_IR.inc b/plugins/markasjunk2/localization/fa_IR.inc
new file mode 100644
index 000000000..1fd7b82ae
--- /dev/null
+++ b/plugins/markasjunk2/localization/fa_IR.inc
@@ -0,0 +1,14 @@
+<?php
+/* Author: KiarasH Mozafari */
+
+$labels = array();
+$labels['buttonjunk'] = 'بنجل کن';
+$labels['markasjunk'] = 'بنجل';
+$labels['buttonnotjunk'] = 'این نامه بنجل نیست';
+$labels['markasnotjunk'] = 'بنجل نیست';
+
+$messages = array();
+$messages['reportedasjunk'] = 'این نامه با موفقیت به صورت بنجل گزارش داده شد';
+$messages['reportedasnotjunk'] = 'نامه به صندق منتقل شد';
+
+?> \ No newline at end of file
diff --git a/plugins/markasjunk2/localization/fr_FR.inc b/plugins/markasjunk2/localization/fr_FR.inc
new file mode 100644
index 000000000..843f01242
--- /dev/null
+++ b/plugins/markasjunk2/localization/fr_FR.inc
@@ -0,0 +1,14 @@
+<?php
+/* Author: */
+
+$labels = array();
+$labels['buttonjunk'] = 'Marquer comme spam';
+$labels['markasjunk'] = 'Comme spam';
+$labels['buttonnotjunk'] = 'Ceci n\'est pas un spam';
+$labels['markasnotjunk'] = 'Comme acceptable';
+
+$messages = array();
+$messages['reportedasjunk'] = 'Message classé en spam';
+$messages['reportedasnotjunk'] = 'Message déplacé dans Inbox';
+
+?> \ No newline at end of file
diff --git a/plugins/markasjunk2/localization/gl_ES.inc b/plugins/markasjunk2/localization/gl_ES.inc
new file mode 100644
index 000000000..b2b65e5d6
--- /dev/null
+++ b/plugins/markasjunk2/localization/gl_ES.inc
@@ -0,0 +1,14 @@
+<?php
+/* Author: David Garabana Barro */
+
+$labels = array();
+$labels['buttonjunk'] = 'Marcar coma correo lixo';
+$labels['markasjunk'] = 'É correo lixo';
+$labels['buttonnotjunk'] = 'Esta mensaxe non é correo lixo';
+$labels['markasnotjunk'] = 'Non é correo lixo';
+
+$messages = array();
+$messages['reportedasjunk'] = 'Marcouse correctamente coma correo lixo ';
+$messages['reportedasnotjunk'] = 'A mensaxe moveuse a caixa de entrada';
+
+?> \ No newline at end of file
diff --git a/plugins/markasjunk2/localization/hu_HU.inc b/plugins/markasjunk2/localization/hu_HU.inc
new file mode 100644
index 000000000..9f8ef1bbe
--- /dev/null
+++ b/plugins/markasjunk2/localization/hu_HU.inc
@@ -0,0 +1,14 @@
+<?php
+/* Author: Attila Sipos */
+
+$labels = array();
+$labels['buttonjunk'] = 'Megkelölés levélszemétként';
+$labels['markasjunk'] = 'Levélszemétként';
+$labels['buttonnotjunk'] = 'Ez az üzenet nem levélszemét';
+$labels['markasnotjunk'] = 'Nem levélszemét';
+
+$messages = array();
+$messages['reportedasjunk'] = 'Sikeresen jelentve, mint levélszemét';
+$messages['reportedasnotjunk'] = 'Az üzenet visszakerült a Érkezett levelekbe';
+
+?> \ No newline at end of file
diff --git a/plugins/markasjunk2/localization/it_IT.inc b/plugins/markasjunk2/localization/it_IT.inc
new file mode 100644
index 000000000..c7760d05e
--- /dev/null
+++ b/plugins/markasjunk2/localization/it_IT.inc
@@ -0,0 +1,15 @@
+<?php
+/* Author: Alessio Cecchi */
+
+$labels = array();
+$labels['buttonjunk'] = 'Segnala come Spam';
+$labels['markasjunk'] = 'Spam';
+$labels['buttonnotjunk'] = 'Questo messaggiono non è Spam';
+$labels['markasnotjunk'] = 'Non Spam';
+$labels['notjunk'] = 'Non Spam';
+
+$messages = array();
+$messages['reportedasjunk'] = 'Segnalato con successo come Spam';
+$messages['reportedasnotjunk'] = 'Messaggio spostato in Posta in arrivo';
+
+?> \ No newline at end of file
diff --git a/plugins/markasjunk2/localization/lv_LV.inc b/plugins/markasjunk2/localization/lv_LV.inc
new file mode 100644
index 000000000..738de15b1
--- /dev/null
+++ b/plugins/markasjunk2/localization/lv_LV.inc
@@ -0,0 +1,15 @@
+<?php
+/* Author: Mārtiņš Dzērve */
+
+$labels = array();
+$labels['buttonjunk'] = 'Atzīmēt mēstules';
+$labels['markasjunk'] = 'Kā mēstuli';
+$labels['buttonnotjunk'] = 'Atzīmēt ne-mēstules';
+$labels['markasnotjunk'] = 'Kā ne-mēstule';
+$labels['notjunk'] = 'Ne-mēstules';
+
+$messages = array();
+$messages['reportedasjunk'] = 'Veiksmīgi ziņots par mēstuli';
+$messages['reportedasnotjunk'] = 'Veiksmīgi ziņots par ne-mēstuli';
+
+?> \ No newline at end of file
diff --git a/plugins/markasjunk2/localization/nl_NL.inc b/plugins/markasjunk2/localization/nl_NL.inc
new file mode 100644
index 000000000..4eb572901
--- /dev/null
+++ b/plugins/markasjunk2/localization/nl_NL.inc
@@ -0,0 +1,14 @@
+<?php
+/* Author: Hans Spaans */
+
+$labels = array();
+$labels['buttonjunk'] = 'Markeer als spam';
+$labels['markasjunk'] = 'Is spam';
+$labels['buttonnotjunk'] = 'Dit bericht is geen spam';
+$labels['markasnotjunk'] = 'Geen spam';
+
+$messages = array();
+$messages['reportedasjunk'] = 'Bericht gemarkeerd als spam';
+$messages['reportedasnotjunk'] = 'Bericht verplaatst naar Inbox';
+
+?> \ No newline at end of file
diff --git a/plugins/markasjunk2/localization/pl_PL.inc b/plugins/markasjunk2/localization/pl_PL.inc
new file mode 100644
index 000000000..7cbe359c7
--- /dev/null
+++ b/plugins/markasjunk2/localization/pl_PL.inc
@@ -0,0 +1,15 @@
+<?php
+/* Author: Bartosz Mierzwiak */
+
+$labels = array();
+$labels['buttonjunk'] = 'Oznacz jako Spam';
+$labels['markasjunk'] = 'Jako Spam';
+$labels['buttonnotjunk'] = 'Ta wiadomość nie jest Spamem';
+$labels['markasnotjunk'] = 'Jako nie Spam';
+$labels['notjunk'] = 'Nie Spam';
+
+$messages = array();
+$messages['reportedasjunk'] = 'Pomyślnie oznaczono jako Spam';
+$messages['reportedasnotjunk'] = 'Wiadomość przeniesiona do Odebranych';
+
+?> \ No newline at end of file
diff --git a/plugins/markasjunk2/localization/pt_BR.inc b/plugins/markasjunk2/localization/pt_BR.inc
new file mode 100644
index 000000000..cf62fc6c9
--- /dev/null
+++ b/plugins/markasjunk2/localization/pt_BR.inc
@@ -0,0 +1,14 @@
+<?php
+/* Author: Arthur Furlan */
+
+$labels = array();
+$labels['buttonjunk'] = 'Marcar como Spam';
+$labels['markasjunk'] = 'Spam';
+$labels['buttonnotjunk'] = 'Esta mensagem não é Spam';
+$labels['markasnotjunk'] = 'Não Spam';
+
+$messages = array();
+$messages['reportedasjunk'] = 'Mensagem marcada como Spam com sucesso';
+$messages['reportedasnotjunk'] = 'Mensagem movida para a Caixa da Entrada';
+
+?> \ No newline at end of file
diff --git a/plugins/markasjunk2/localization/ro_RO.inc b/plugins/markasjunk2/localization/ro_RO.inc
new file mode 100644
index 000000000..13567a8b2
--- /dev/null
+++ b/plugins/markasjunk2/localization/ro_RO.inc
@@ -0,0 +1,14 @@
+<?php
+/* Author: Ovidiu Bica */
+
+$labels = array();
+$labels['buttonjunk'] = 'Marcheaza ca spam';
+$labels['markasjunk'] = 'Este Spam';
+$labels['buttonnotjunk'] = 'Acest mesaj nu este spam';
+$labels['markasnotjunk'] = 'Nu este spam';
+
+$messages = array();
+$messages['reportedasjunk'] = 'Raportat cu succes ca Spam';
+$messages['reportedasnotjunk'] = 'Mesajul a fost mutat in Inbox';
+
+?> \ No newline at end of file
diff --git a/plugins/markasjunk2/localization/ru_RU.inc b/plugins/markasjunk2/localization/ru_RU.inc
new file mode 100644
index 000000000..e91f6a454
--- /dev/null
+++ b/plugins/markasjunk2/localization/ru_RU.inc
@@ -0,0 +1,15 @@
+<?php
+/* Author: Peter Zotov */
+
+$labels = array();
+$labels['buttonjunk'] = 'Пометить как спам';
+$labels['markasjunk'] = 'Как спам';
+$labels['buttonnotjunk'] = 'Это сообщение не спам';
+$labels['markasnotjunk'] = 'Не спам';
+$labels['notjunk'] = 'Не спам';
+
+$messages = array();
+$messages['reportedasjunk'] = 'Помечено как спам';
+$messages['reportedasnotjunk'] = 'Сообщение перемещено во Входящие';
+
+?> \ No newline at end of file
diff --git a/plugins/markasjunk2/localization/tr_TR.inc b/plugins/markasjunk2/localization/tr_TR.inc
new file mode 100644
index 000000000..7da3f0a40
--- /dev/null
+++ b/plugins/markasjunk2/localization/tr_TR.inc
@@ -0,0 +1,14 @@
+<?php
+/* Author: Mustafa Icer */
+
+$labels = array();
+$labels['buttonjunk'] = 'Spam olarak işaretle';
+$labels['markasjunk'] = 'Spam olarak';
+$labels['buttonnotjunk'] = 'Bu mesaj Spam değildir';
+$labels['markasnotjunk'] = 'Spam değildir';
+
+$messages = array();
+$messages['reportedasjunk'] = 'Başarıyla spam olarak bildirildi';
+$messages['reportedasnotjunk'] = 'Mesaj, gelen klasörüne taşındı';
+
+?> \ No newline at end of file
diff --git a/plugins/markasjunk2/localization/zh_TW.inc b/plugins/markasjunk2/localization/zh_TW.inc
new file mode 100644
index 000000000..9d9d4a541
--- /dev/null
+++ b/plugins/markasjunk2/localization/zh_TW.inc
@@ -0,0 +1,14 @@
+<?php
+/* Author: Denny Lin */
+
+$labels = array();
+$labels['buttonjunk'] = '標為垃圾郵件';
+$labels['markasjunk'] = '標為垃圾郵件';
+$labels['buttonnotjunk'] = '非垃圾郵件';
+$labels['markasnotjunk'] = '非垃圾郵件';
+
+$messages = array();
+$messages['reportedasjunk'] = '已標為垃圾郵件';
+$messages['reportedasnotjunk'] = '已移至收件匣';
+
+?> \ No newline at end of file
diff --git a/plugins/markasjunk2/markasjunk2.js b/plugins/markasjunk2/markasjunk2.js
new file mode 100644
index 000000000..5dc141f6a
--- /dev/null
+++ b/plugins/markasjunk2/markasjunk2.js
@@ -0,0 +1,199 @@
+/**
+ * MarkAsJunk2 plugin script
+ */
+
+function rcmail_markasjunk2(prop) {
+ if (!rcmail.env.uid && (!rcmail.message_list || !rcmail.message_list.get_selection().length))
+ return;
+
+ if (!prop || prop == 'markasjunk2')
+ prop = 'junk';
+
+ var prev_sel = null;
+
+ // also select childs of (collapsed) threads
+ if (rcmail.message_list) {
+ if (rcmail.env.uid) {
+ if (rcmail.message_list.rows[rcmail.env.uid].has_children && !rcmail.message_list.rows[rcmail.env.uid].expanded) {
+ if (!rcmail.message_list.in_selection(rcmail.env.uid)) {
+ prev_sel = rcmail.message_list.get_selection();
+ rcmail.message_list.select_row(rcmail.env.uid);
+ }
+
+ rcmail.message_list.select_childs(rcmail.env.uid);
+ rcmail.env.uid = null;
+ }
+ else if (rcmail.message_list.get_single_selection() == rcmail.env.uid) {
+ rcmail.env.uid = null;
+ }
+ }
+ else {
+ selection = rcmail.message_list.get_selection();
+ for (var i in selection) {
+ if (rcmail.message_list.rows[selection[i]].has_children && !rcmail.message_list.rows[selection[i]].expanded)
+ rcmail.message_list.select_childs(selection[i]);
+ }
+ }
+ }
+
+ var uids = rcmail.env.uid ? rcmail.env.uid : rcmail.message_list.get_selection().join(',');
+
+ var lock = rcmail.set_busy(true, 'loading');
+ rcmail.http_post('plugin.markasjunk2.' + prop, '_uid='+uids+'&_mbox='+urlencode(rcmail.env.mailbox), lock);
+
+ if (prev_sel) {
+ rcmail.message_list.clear_selection();
+
+ for (var i in prev_sel)
+ rcmail.message_list.select_row(prev_sel[i], CONTROL_KEY);
+ }
+}
+
+function rcmail_markasjunk2_notjunk(prop) {
+ rcmail_markasjunk2('not_junk');
+}
+
+rcube_webmail.prototype.rcmail_markasjunk2_move = function(mbox, uid) {
+ var prev_uid = rcmail.env.uid;
+ var prev_sel = null;
+ var a_uids = uid.split(",");
+
+ if (rcmail.message_list && a_uids.length == 1 && !rcmail.message_list.rows[a_uids[0]]) {
+ rcmail.env.uid = a_uids[0];
+ }
+ else if (rcmail.message_list && a_uids.length == 1 && !rcmail.message_list.in_selection(a_uids[0]) && !rcmail.env.threading) {
+ rcmail.env.uid = a_uids[0];
+ rcmail.message_list.remove_row(rcmail.env.uid, false);
+ }
+ else if (rcmail.message_list && (!rcmail.message_list.in_selection(a_uids[0]) || a_uids.length != rcmail.message_list.selection.length)) {
+ prev_sel = rcmail.message_list.get_selection();
+ rcmail.message_list.clear_selection();
+
+ for (var i in a_uids)
+ rcmail.message_list.select_row(a_uids[i], CONTROL_KEY);
+ }
+
+ if (mbox)
+ rcmail.move_messages(mbox);
+ else
+ rcmail.delete_messages();
+
+ rcmail.env.uid = prev_uid;
+
+ if (prev_sel) {
+ rcmail.message_list.clear_selection();
+
+ for (var i in prev_sel) {
+ if (prev_sel[i] != uid)
+ rcmail.message_list.select_row(prev_sel[i], CONTROL_KEY);
+ }
+ }
+}
+
+function rcmail_markasjunk2_init() {
+ if (window.rcm_contextmenu_register_command) {
+ rcm_contextmenu_register_command('markasjunk2', 'rcmail_markasjunk2', rcmail.gettext('markasjunk2.markasjunk'), 'reply', null, true, null, null, 'markmessage markasjunk2');
+ rcm_contextmenu_register_command('markasnotjunk2', 'rcmail_markasjunk2_notjunk', rcmail.gettext('markasjunk2.markasnotjunk'), 'reply', null, true, null, null, 'markmessage markasnotjunk2');
+ $('#rcmContextMenu li.unflagged').removeClass('separator_below');
+ $('#rcmContextMenu li.reply').addClass('separator_above');
+ }
+}
+
+function rcmail_markasjunk2_update() {
+ var spamobj = $('#' + rcmail.buttons['plugin.markasjunk2.junk'][0].id);
+ var hamobj = $('#' + rcmail.buttons['plugin.markasjunk2.not_junk'][0].id);
+
+ if (spamobj.parent('li').length > 0) {
+ spamobj = spamobj.parent();
+ hamobj = hamobj.parent();
+ }
+
+ if (!rcmail.env.markasjunk2_override && rcmail.env.markasjunk2_spam_mailbox && rcmail.env.mailbox != rcmail.env.markasjunk2_spam_mailbox) {
+ $('#rcmContextMenu li.markasjunk2').show();
+ $('#rcmContextMenu li.markasnotjunk2').hide();
+ spamobj.show();
+ hamobj.hide();
+ }
+ else if (!rcmail.env.markasjunk2_override) {
+ $('#rcmContextMenu li.markasjunk2').hide();
+ $('#rcmContextMenu li.markasnotjunk2').show();
+ spamobj.hide();
+ hamobj.show();
+ }
+}
+
+function rcmail_markasjunk2_status(command) {
+ switch (command) {
+ case 'beforedelete':
+ if (!rcmail.env.flag_for_deletion && rcmail.env.trash_mailbox &&
+ rcmail.env.mailbox != rcmail.env.trash_mailbox &&
+ (rcmail.message_list && !rcmail.message_list.shiftkey))
+ rcmail.enable_command('plugin.markasjunk2.junk', 'plugin.markasjunk2.not_junk', false);
+
+ break;
+ case 'beforemove':
+ case 'beforemoveto':
+ rcmail.enable_command('plugin.markasjunk2.junk', 'plugin.markasjunk2.not_junk', false);
+ break;
+ case 'aftermove':
+ case 'aftermoveto':
+ if (rcmail.env.action == 'show')
+ rcmail.enable_command('plugin.markasjunk2.junk', 'plugin.markasjunk2.not_junk', true);
+
+ break;
+ case 'afterpurge':
+ case 'afterexpunge':
+ if (!rcmail.env.messagecount && rcmail.task == 'mail')
+ rcmail.enable_command('plugin.markasjunk2.junk', 'plugin.markasjunk2.not_junk', false);
+
+ break;
+ }
+}
+
+$(document).ready(function() {
+ if (window.rcmail) {
+ rcmail.addEventListener('init', function(evt) {
+ // register command (directly enable in message view mode)
+ rcmail.register_command('plugin.markasjunk2.junk', rcmail_markasjunk2, rcmail.env.uid);
+ rcmail.register_command('plugin.markasjunk2.not_junk', rcmail_markasjunk2_notjunk, rcmail.env.uid);
+
+ if (rcmail.message_list) {
+ rcmail.message_list.addEventListener('select', function(list) {
+ rcmail.enable_command('plugin.markasjunk2.junk', list.get_selection().length > 0);
+ rcmail.enable_command('plugin.markasjunk2.not_junk', list.get_selection().length > 0);
+ });
+ }
+ });
+
+ rcmail.add_onload('rcmail_markasjunk2_init()');
+ rcmail.addEventListener('listupdate', function(props) { rcmail_markasjunk2_update(); } );
+
+ rcmail.addEventListener('beforemoveto', function(mbox) {
+ if (mbox && typeof mbox === 'object')
+ mbox = mbox.id;
+
+ // check if destination mbox equals junk box (and we're not already in the junk box)
+ if (rcmail.env.markasjunk2_move_spam && mbox && mbox == rcmail.env.markasjunk2_spam_mailbox && mbox != rcmail.env.mailbox) {
+ rcmail_markasjunk2();
+ return false;
+
+ }
+ // or if destination mbox equals ham box and we are in the junk box
+ else if (rcmail.env.markasjunk2_move_ham && mbox && mbox == rcmail.env.markasjunk2_ham_mailbox && rcmail.env.mailbox == rcmail.env.markasjunk2_spam_mailbox) {
+ rcmail_markasjunk2_notjunk();
+ return false;
+ }
+
+ return;
+ } );
+
+ // update button activation after external events
+ rcmail.addEventListener('beforedelete', function(props) { rcmail_markasjunk2_status('beforedelete'); } );
+ rcmail.addEventListener('beforemove', function(props) { rcmail_markasjunk2_status('beforemove'); } );
+ rcmail.addEventListener('beforemoveto', function(props) { rcmail_markasjunk2_status('beforemoveto'); } );
+ rcmail.addEventListener('aftermove', function(props) { rcmail_markasjunk2_status('aftermove'); } );
+ rcmail.addEventListener('aftermoveto', function(props) { rcmail_markasjunk2_status('aftermoveto'); } );
+ rcmail.addEventListener('afterpurge', function(props) { rcmail_markasjunk2_status('afterpurge'); } );
+ rcmail.addEventListener('afterexpunge', function(props) { rcmail_markasjunk2_status('afterexpunge'); } );
+ }
+}); \ No newline at end of file
diff --git a/plugins/markasjunk2/markasjunk2.php b/plugins/markasjunk2/markasjunk2.php
new file mode 100644
index 000000000..313798685
--- /dev/null
+++ b/plugins/markasjunk2/markasjunk2.php
@@ -0,0 +1,211 @@
+<?php
+
+/**
+ * MarkAsJunk2
+ *
+ * Sample plugin that adds a new button to the mailbox toolbar
+ * to mark the selected messages as Junk and move them to the Junk folder
+ * or to move messages in the Junk folder to the inbox - moving only the
+ * attachment if it is a Spamassassin spam report email
+ *
+ * @version @package_version@
+ * @author Philip Weir
+ * Based on the Markasjunk plugin by Thomas Bruederli
+ */
+class markasjunk2 extends rcube_plugin
+{
+ public $task = 'mail';
+ private $spam_mbox = null;
+ private $ham_mbox = null;
+ private $spam_flag = 'JUNK';
+ private $ham_flag = 'NOTJUNK';
+ private $toolbar = true;
+
+ function init()
+ {
+ $this->register_action('plugin.markasjunk2.junk', array($this, 'mark_junk'));
+ $this->register_action('plugin.markasjunk2.not_junk', array($this, 'mark_notjunk'));
+
+ $rcmail = rcube::get_instance();
+ $this->load_config();
+ $this->ham_mbox = $rcmail->config->get('markasjunk2_ham_mbox', 'INBOX');
+ $this->spam_mbox = $rcmail->config->get('markasjunk2_spam_mbox', $rcmail->config->get('junk_mbox', null));
+ $this->toolbar = $rcmail->action == 'show' ? $rcmail->config->get('markasjunk2_cp_toolbar', true) : $rcmail->config->get('markasjunk2_mb_toolbar', true);
+
+ if ($rcmail->action == '' || $rcmail->action == 'show') {
+ $this->include_script('markasjunk2.js');
+ $this->add_texts('localization', true);
+ $this->include_stylesheet($this->local_skin_path() .'/markasjunk2.css');
+ if ($rcmail->output->browser->ie && $rcmail->output->browser->ver == 6)
+ $this->include_stylesheet($this->local_skin_path() . '/ie6hacks.css');
+
+ $mb_override = ($this->spam_mbox) ? false : true;
+ $display_junk = $display_not_junk = '';
+ if ($_SESSION['mbox'] == $this->spam_mbox)
+ $display_junk = 'display: none;';
+ elseif (!$mb_override)
+ $display_not_junk = 'display: none;';
+
+ if ($this->toolbar) {
+ $this->add_button(array('command' => 'plugin.markasjunk2.junk', 'type' => 'link', 'class' => 'button buttonPas markasjunk2 disabled', 'classact' => 'button markasjunk2', 'classsel' => 'button markasjunk2Sel', 'title' => 'markasjunk2.buttonjunk', 'label' => 'junk', 'style' => $display_junk), 'toolbar');
+ $this->add_button(array('command' => 'plugin.markasjunk2.not_junk', 'type' => 'link', 'class' => 'button buttonPas markasnotjunk2 disabled', 'classact' => 'button markasnotjunk2', 'classsel' => 'button markasnotjunk2Sel', 'title' => 'markasjunk2.buttonnotjunk', 'label' => 'markasjunk2.notjunk', 'style' => $display_not_junk), 'toolbar');
+ }
+ else {
+ $markjunk = $this->api->output->button(array('command' => 'plugin.markasjunk2.junk', 'label' => 'markasjunk2.markasjunk', 'id' => 'markasjunk2', 'class' => 'icon markasjunk2', 'classact' => 'icon markasjunk2 active', 'innerclass' => 'icon markasjunk2'));
+ $marknotjunk = $this->api->output->button(array('command' => 'plugin.markasjunk2.not_junk', 'label' => 'markasjunk2.markasnotjunk', 'id' => 'markasnotjunk2', 'class' => 'icon markasnotjunk2', 'classact' => 'icon markasnotjunk2 active', 'innerclass' => 'icon markasnotjunk2'));
+ $this->api->add_content(html::tag('li', array('style' => $display_junk), $markjunk), 'markmenu');
+ $this->api->add_content(html::tag('li', array('style' => $display_not_junk), $marknotjunk), 'markmenu');
+ }
+
+ $this->api->output->set_env('markasjunk2_override', $mb_override);
+ $this->api->output->set_env('markasjunk2_ham_mailbox', $this->ham_mbox);
+ $this->api->output->set_env('markasjunk2_spam_mailbox', $this->spam_mbox);
+
+ $this->api->output->set_env('markasjunk2_move_spam', $rcmail->config->get('markasjunk2_move_spam', false));
+ $this->api->output->set_env('markasjunk2_move_ham', $rcmail->config->get('markasjunk2_move_ham', false));
+ }
+ }
+
+ function mark_junk()
+ {
+ $this->add_texts('localization');
+ $this->_set_flags();
+
+ $uids = rcube_utils::get_input_value('_uid', rcube_utils::INPUT_POST);
+ $mbox = rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_POST);
+
+ if ($this->_spam($uids, $mbox, $this->spam_mbox))
+ $this->api->output->command('display_message', $this->gettext('reportedasjunk'), 'confirmation');
+
+ $this->api->output->send();
+ }
+
+ function mark_notjunk()
+ {
+ $this->add_texts('localization');
+ $this->_set_flags();
+
+ $uids = rcube_utils::get_input_value('_uid', rcube_utils::INPUT_POST);
+ $mbox = rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_POST);
+
+ if ($this->_ham($uids, $mbox, $this->ham_mbox))
+ $this->api->output->command('display_message', $this->gettext('reportedasnotjunk'), 'confirmation');
+
+ $this->api->output->send();
+ }
+
+ private function _spam($uids, $mbox_name = NULL, $dest_mbox = NULL)
+ {
+ $rcmail = rcube::get_instance();
+ $storage = $rcmail->storage;
+
+ if ($rcmail->config->get('markasjunk2_learning_driver', false)) {
+ $result = $this->_call_driver($uids, true);
+
+ if (!$result)
+ return false;
+ }
+
+ if ($rcmail->config->get('markasjunk2_read_spam', false))
+ $storage->set_flag($uids, 'SEEN', $mbox_name);
+
+ if ($rcmail->config->get('markasjunk2_spam_flag', false))
+ $storage->set_flag($uids, $this->spam_flag, $mbox_name);
+
+ if ($rcmail->config->get('markasjunk2_ham_flag', false))
+ $storage->unset_flag($uids, $this->ham_flag, $mbox_name);
+
+ if ($dest_mbox && $mbox_name != $dest_mbox)
+ $this->api->output->command('rcmail_markasjunk2_move', $dest_mbox, $uids);
+ else
+ $this->api->output->command('command', 'list', $mbox_name);
+
+ return true;
+ }
+
+ private function _ham($uids, $mbox_name = NULL, $dest_mbox = NULL)
+ {
+ $rcmail = rcube::get_instance();
+ $storage = $rcmail->storage;
+
+ if ($rcmail->config->get('markasjunk2_learning_driver', false)) {
+ $result = $this->_call_driver($uids, false);
+
+ if (!$result)
+ return false;
+ }
+
+ if ($rcmail->config->get('markasjunk2_unread_ham', false))
+ $storage->unset_flag($uids, 'SEEN', $mbox_name);
+
+ if ($rcmail->config->get('markasjunk2_spam_flag', false))
+ $storage->unset_flag($uids, $this->spam_flag, $mbox_name);
+
+ if ($rcmail->config->get('markasjunk2_ham_flag', false))
+ $storage->set_flag($uids, $this->ham_flag, $mbox_name);
+
+ if ($dest_mbox && $mbox_name != $dest_mbox)
+ $this->api->output->command('rcmail_markasjunk2_move', $dest_mbox, $uids);
+ else
+ $this->api->output->command('command', 'list', $mbox_name);
+
+ return true;
+ }
+
+ private function _call_driver(&$uids, $spam)
+ {
+ $driver = $this->home.'/drivers/'. rcube::get_instance()->config->get('markasjunk2_learning_driver', 'cmd_learn') .'.php';
+ $class = 'markasjunk2_' . rcube::get_instance()->config->get('markasjunk2_learning_driver', 'cmd_learn');
+
+ if (!is_readable($driver)) {
+ rcube::raise_error(array(
+ 'code' => 600,
+ 'type' => 'php',
+ 'file' => __FILE__,
+ 'line' => __LINE__,
+ 'message' => "MarkasJunk2 plugin: Unable to open driver file $driver"
+ ), true, false);
+ }
+
+ include_once $driver;
+
+ if (!class_exists($class, false) || !method_exists($class, 'spam') || !method_exists($class, 'ham')) {
+ rcube::raise_error(array(
+ 'code' => 600,
+ 'type' => 'php',
+ 'file' => __FILE__,
+ 'line' => __LINE__,
+ 'message' => "MarkasJunk2 plugin: Broken driver: $driver"
+ ), true, false);
+ }
+
+ $object = new $class;
+ if ($spam)
+ $object->spam($uids);
+ else
+ $object->ham($uids);
+
+ return $object->is_error ? false : true;
+ }
+
+ private function _set_flags()
+ {
+ $rcmail = rcube::get_instance();
+
+ if ($rcmail->config->get('markasjunk2_spam_flag', false)) {
+ if ($flag = array_search($rcmail->config->get('markasjunk2_spam_flag'), $rcmail->storage->conn->flags))
+ $this->spam_flag = $flag;
+ else
+ $rcmail->storage->conn->flags[$this->spam_flag] = $rcmail->config->get('markasjunk2_spam_flag');
+ }
+
+ if ($rcmail->config->get('markasjunk2_ham_flag', false)) {
+ if ($flag = array_search($rcmail->config->get('markasjunk2_ham_flag'), $rcmail->storage->conn->flags))
+ $this->ham_flag = $flag;
+ else
+ $rcmail->storage->conn->flags[$this->ham_flag] = $rcmail->config->get('markasjunk2_ham_flag');
+ }
+ }
+}
+
+?> \ No newline at end of file
diff --git a/plugins/markasjunk2/package.xml b/plugins/markasjunk2/package.xml
new file mode 100644
index 000000000..3b16ed13a
--- /dev/null
+++ b/plugins/markasjunk2/package.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<package xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" packagerversion="1.9.0" version="2.0" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0
+ http://pear.php.net/dtd/tasks-1.0.xsd
+ http://pear.php.net/dtd/package-2.0
+ http://pear.php.net/dtd/package-2.0.xsd">
+ <name>markasjunk2</name>
+ <uri>http://github.com/JohnDoh/Roundcube-Plugin-Mark-as-Junk-2/</uri>
+ <summary>Learn messages as Junk/Not Junk</summary>
+ <description>Adds a new button to the mailbox toolbar to mark the selected messages as Junk/Not Junk, optionally detaching original messages from spam reports if the message is not junk and learning junk/not junk using various methods (sa-learn, etc.).</description>
+ <lead>
+ <name>Philip Weir</name>
+ <user>JohnDoh</user>
+ <email>roundcube@tehinterweb.co.uk</email>
+ <active>yes</active>
+ </lead>
+ <date>2013-02-24</date>
+ <time>10:16:53</time>
+ <version>
+ <release>1.6</release>
+ <api>1.6</api>
+ </version>
+ <stability>
+ <release>stable</release>
+ <api>stable</api>
+ </stability>
+ <license uri="http://www.gnu.org/licenses/gpl.html">GNU GPLv3+</license>
+ <notes>-</notes>
+ <contents>
+ <dir baseinstalldir="/" name="/">
+ <file name="markasjunk2.php" role="php">
+ <tasks:replace from="@name@" to="name" type="package-info"/>
+ <tasks:replace from="@package_version@" to="version" type="package-info"/>
+ </file>
+ <file name="markasjunk2.js" role="data">
+ <tasks:replace from="@name@" to="name" type="package-info"/>
+ <tasks:replace from="@package_version@" to="version" type="package-info"/>
+ </file>
+ <file name="config.inc.php.dist" role="data"/>
+ <file name="CHANGELOG" role="data"/>
+ <file name="README.md" role="data"/>
+ <file name="drivers/cmd_learn.php" role="php"/>
+ <file name="drivers/dir_learn.php" role="php"/>
+ <file name="drivers/edit_headers.php" role="php"/>
+ <file name="drivers/email_learn.php" role="php"/>
+ <file name="drivers/sa_blacklist.php" role="php"/>
+ <file name="drivers/sa_detach.php" role="php"/>
+ <file name="localization/ca_ES.inc" role="data"/>
+ <file name="localization/cs_CZ.inc" role="data"/>
+ <file name="localization/de_CH.inc" role="data"/>
+ <file name="localization/de_DE.inc" role="data"/>
+ <file name="localization/en_GB.inc" role="data"/>
+ <file name="localization/en_US.inc" role="data"/>
+ <file name="localization/es_AR.inc" role="data"/>
+ <file name="localization/es_ES.inc" role="data"/>
+ <file name="localization/fa_IR.inc" role="data"/>
+ <file name="localization/fr_FR.inc" role="data"/>
+ <file name="localization/gl_ES.inc" role="data"/>
+ <file name="localization/hu_HU.inc" role="data"/>
+ <file name="localization/it_IT.inc" role="data"/>
+ <file name="localization/lv_LV.inc" role="data"/>
+ <file name="localization/nl_NL.inc" role="data"/>
+ <file name="localization/pl_PL.inc" role="data"/>
+ <file name="localization/pt_BR.inc" role="data"/>
+ <file name="localization/ro_RO.inc" role="data"/>
+ <file name="localization/ru_RU.inc" role="data"/>
+ <file name="localization/tr_TR.inc" role="data"/>
+ <file name="localization/zh_TW.inc" role="data"/>
+ <file name="skins/classic/ie6hacks.css" role="data"/>
+ <file name="skins/classic/mail_toolbar.gif" role="data"/>
+ <file name="skins/classic/mail_toolbar.png" role="data"/>
+ <file name="skins/classic/markasjunk2.css" role="data"/>
+ <file name="skins/classic/messageactions.gif" role="data"/>
+ <file name="skins/classic/messageactions.png" role="data"/>
+ <file name="skins/larry/ie6hacks.css" role="data"/>
+ <file name="skins/larry/mail_toolbar.png" role="data"/>
+ <file name="skins/larry/markasjunk2.css" role="data"/>
+ <file name="skins/larry/messageactions.png" role="data"/>
+ </dir>
+ <!-- / -->
+ </contents>
+ <dependencies>
+ <required>
+ <php>
+ <min>5.2.1</min>
+ </php>
+ <pearinstaller>
+ <min>1.7.0</min>
+ </pearinstaller>
+ </required>
+ </dependencies>
+ <phprelease/>
+</package>
diff --git a/plugins/markasjunk2/skins/classic/ie6hacks.css b/plugins/markasjunk2/skins/classic/ie6hacks.css
new file mode 100644
index 000000000..3b61721e3
--- /dev/null
+++ b/plugins/markasjunk2/skins/classic/ie6hacks.css
@@ -0,0 +1,19 @@
+/**
+ * MarkAsJunk2 plugin styles (IE6 hacks)
+ */
+
+#messagetoolbar a.markasjunk2,
+#messagetoolbar a.markasjunk2Sel,
+#messagetoolbar a.markasnotjunk2,
+#messagetoolbar a.markasnotjunk2Sel
+{
+ background-image: url(mail_toolbar.gif);
+}
+
+#rcmContextMenu .markasjunk2 a,
+#rcmContextMenu .markasnotjunk2 a,
+#markmessagemenu a.markasjunk2,
+#markmessagemenu a.markasnotjunk2
+{
+ background-image: url(messageactions.gif);
+} \ No newline at end of file
diff --git a/plugins/markasjunk2/skins/classic/mail_toolbar.gif b/plugins/markasjunk2/skins/classic/mail_toolbar.gif
new file mode 100644
index 000000000..d1cdff0f2
--- /dev/null
+++ b/plugins/markasjunk2/skins/classic/mail_toolbar.gif
Binary files differ
diff --git a/plugins/markasjunk2/skins/classic/mail_toolbar.png b/plugins/markasjunk2/skins/classic/mail_toolbar.png
new file mode 100644
index 000000000..aad0e9ebc
--- /dev/null
+++ b/plugins/markasjunk2/skins/classic/mail_toolbar.png
Binary files differ
diff --git a/plugins/markasjunk2/skins/classic/markasjunk2.css b/plugins/markasjunk2/skins/classic/markasjunk2.css
new file mode 100644
index 000000000..311a45083
--- /dev/null
+++ b/plugins/markasjunk2/skins/classic/markasjunk2.css
@@ -0,0 +1,52 @@
+/**
+ * MarkAsJunk2 plugin styles
+ */
+
+#messagetoolbar a.markasjunk2,
+#messagetoolbar a.markasjunk2Sel,
+#messagetoolbar a.markasnotjunk2,
+#messagetoolbar a.markasnotjunk2Sel
+{
+ text-indent: -5000px;
+ background-image: url(mail_toolbar.png);
+}
+
+#messagetoolbar a.markasjunk2
+{
+ background-position: -32px 0;
+}
+
+#messagetoolbar a.markasjunk2Sel
+{
+ background-position: -32px -32px;
+}
+
+#messagetoolbar a.markasnotjunk2
+{
+ background-position: 0 0;
+}
+
+#messagetoolbar a.markasnotjunk2Sel
+{
+ background-position: 0 -32px;
+}
+
+#rcmContextMenu .markasjunk2 a,
+#rcmContextMenu .markasnotjunk2 a,
+#markmessagemenu a.markasjunk2,
+#markmessagemenu a.markasnotjunk2
+{
+ background-image: url(messageactions.png);
+}
+
+#rcmContextMenu .markasjunk2 a,
+#markmessagemenu a.markasjunk2
+{
+ background-position: 7px -17px;
+}
+
+#rcmContextMenu .markasnotjunk2 a,
+#markmessagemenu a.markasnotjunk2
+{
+ background-position: 7px 0;
+} \ No newline at end of file
diff --git a/plugins/markasjunk2/skins/classic/messageactions.gif b/plugins/markasjunk2/skins/classic/messageactions.gif
new file mode 100644
index 000000000..255ae3606
--- /dev/null
+++ b/plugins/markasjunk2/skins/classic/messageactions.gif
Binary files differ
diff --git a/plugins/markasjunk2/skins/classic/messageactions.png b/plugins/markasjunk2/skins/classic/messageactions.png
new file mode 100644
index 000000000..11a7f7f51
--- /dev/null
+++ b/plugins/markasjunk2/skins/classic/messageactions.png
Binary files differ
diff --git a/plugins/markasjunk2/skins/larry/ie6hacks.css b/plugins/markasjunk2/skins/larry/ie6hacks.css
new file mode 100644
index 000000000..cd33694ae
--- /dev/null
+++ b/plugins/markasjunk2/skins/larry/ie6hacks.css
@@ -0,0 +1,3 @@
+/**
+ * MarkAsJunk2 plugin styles (IE6 hacks)
+ */
diff --git a/plugins/markasjunk2/skins/larry/mail_toolbar.png b/plugins/markasjunk2/skins/larry/mail_toolbar.png
new file mode 100644
index 000000000..3d5981482
--- /dev/null
+++ b/plugins/markasjunk2/skins/larry/mail_toolbar.png
Binary files differ
diff --git a/plugins/markasjunk2/skins/larry/markasjunk2.css b/plugins/markasjunk2/skins/larry/markasjunk2.css
new file mode 100644
index 000000000..90362ed2a
--- /dev/null
+++ b/plugins/markasjunk2/skins/larry/markasjunk2.css
@@ -0,0 +1,51 @@
+/**
+ * MarkAsJunk2 plugin styles
+ */
+
+#messagetoolbar a.markasjunk2,
+#messagetoolbar a.markasjunk2Sel,
+#messagetoolbar a.markasnotjunk2,
+#messagetoolbar a.markasnotjunk2Sel
+{
+ background-image: url(mail_toolbar.png);
+}
+
+#messagetoolbar a.markasjunk2,
+#messagetoolbar a.markasjunk2Sel
+{
+ background-position: center -14px;
+}
+
+#messagetoolbar a.markasnotjunk2,
+#messagetoolbar a.markasnotjunk2Sel
+{
+ background-position: center -61px;
+}
+
+#rcmContextMenu .markasjunk2 a span,
+#rcmContextMenu .markasnotjunk2 a span,
+#markmessagemenu a.markasjunk2 span,
+#markmessagemenu a.markasnotjunk2 span
+{
+ background-image: url(messageactions.png);
+}
+
+#markmessagemenu a.markasjunk2 span
+{
+ background-position: 1px -17px;
+}
+
+#markmessagemenu a.markasnotjunk2 span
+{
+ background-position: 1px 5px;
+}
+
+#rcmContextMenu .markasjunk2 a span
+{
+ background-position: 7px -14px;
+}
+
+#rcmContextMenu .markasnotjunk2 a span
+{
+ background-position: 7px 7px;
+} \ No newline at end of file
diff --git a/plugins/markasjunk2/skins/larry/messageactions.png b/plugins/markasjunk2/skins/larry/messageactions.png
new file mode 100644
index 000000000..15f5d56ac
--- /dev/null
+++ b/plugins/markasjunk2/skins/larry/messageactions.png
Binary files differ
diff --git a/plugins/message_highlight/colorpicker/images/color.png b/plugins/message_highlight/colorpicker/images/color.png
new file mode 100644
index 000000000..809fb00e5
--- /dev/null
+++ b/plugins/message_highlight/colorpicker/images/color.png
Binary files differ
diff --git a/plugins/message_highlight/colorpicker/images/colorpicker.png b/plugins/message_highlight/colorpicker/images/colorpicker.png
new file mode 100644
index 000000000..3701eb1c1
--- /dev/null
+++ b/plugins/message_highlight/colorpicker/images/colorpicker.png
Binary files differ
diff --git a/plugins/message_highlight/colorpicker/images/graybar.jpg b/plugins/message_highlight/colorpicker/images/graybar.jpg
new file mode 100644
index 000000000..f807d24bb
--- /dev/null
+++ b/plugins/message_highlight/colorpicker/images/graybar.jpg
Binary files differ
diff --git a/plugins/message_highlight/colorpicker/images/grid.gif b/plugins/message_highlight/colorpicker/images/grid.gif
new file mode 100644
index 000000000..78b54c0f6
--- /dev/null
+++ b/plugins/message_highlight/colorpicker/images/grid.gif
Binary files differ
diff --git a/plugins/message_highlight/colorpicker/images/meta100.png b/plugins/message_highlight/colorpicker/images/meta100.png
new file mode 100644
index 000000000..72bea40e8
--- /dev/null
+++ b/plugins/message_highlight/colorpicker/images/meta100.png
Binary files differ
diff --git a/plugins/message_highlight/colorpicker/images/transparentpixel.gif b/plugins/message_highlight/colorpicker/images/transparentpixel.gif
new file mode 100644
index 000000000..b7406476a
--- /dev/null
+++ b/plugins/message_highlight/colorpicker/images/transparentpixel.gif
Binary files differ
diff --git a/plugins/message_highlight/colorpicker/mColorPicker.js b/plugins/message_highlight/colorpicker/mColorPicker.js
new file mode 100644
index 000000000..6b5d6c381
--- /dev/null
+++ b/plugins/message_highlight/colorpicker/mColorPicker.js
@@ -0,0 +1,564 @@
+/*
+ mColorPicker
+ Version: 1.0 r34
+
+ Copyright (c) 2010 Meta100 LLC.
+ http://www.meta100.com/
+
+ Licensed under the MIT license
+ http://www.opensource.org/licenses/mit-license.php
+*/
+
+// After this script loads set:
+// $.fn.mColorPicker.init.replace = '.myclass'
+// to have this script apply to input.myclass,
+// instead of the default input[type=color]
+// To turn of automatic operation and run manually set:
+// $.fn.mColorPicker.init.replace = false
+// To use manually call like any other jQuery plugin
+// $('input.foo').mColorPicker({options})
+// options:
+// imageFolder - Change to move image location.
+// swatches - Initial colors in the swatch, must an array of 10 colors.
+// init:
+// $.fn.mColorPicker.init.enhancedSwatches - Turn of saving and loading of swatch to cookies.
+// $.fn.mColorPicker.init.allowTransparency - Turn off transperancy as a color option.
+// $.fn.mColorPicker.init.showLogo - Turn on/off the meta100 logo (You don't really want to turn it off, do you?).
+
+(function($){
+
+ var $o;
+
+ $.fn.mColorPicker = function(options) {
+
+ $o = $.extend($.fn.mColorPicker.defaults, options);
+
+ if ($o.swatches.length < 10) $o.swatches = $.fn.mColorPicker.defaults.swatches
+ if ($("div#mColorPicker").length < 1) $.fn.mColorPicker.drawPicker();
+
+ if ($('#css_disabled_color_picker').length < 1) $('head').prepend('<style id="css_disabled_color_picker" type="text/css">.mColorPicker[disabled] + span, .mColorPicker[disabled="disabled"] + span, .mColorPicker[disabled="true"] + span {filter:alpha(opacity=50);-moz-opacity:0.5;-webkit-opacity:0.5;-khtml-opacity: 0.5;opacity: 0.5;}</style>');
+
+ $('.mColorPicker').live('keyup', function () {
+
+ try {
+
+ $(this).css({
+ 'background-color': $(this).val()
+ }).css({
+ 'color': $.fn.mColorPicker.textColor($(this).css('background-color'))
+ }).trigger('change');
+ } catch (r) {}
+ });
+
+ $('.mColorPickerTrigger').live('click', function () {
+
+ $.fn.mColorPicker.colorShow($(this).attr('id').replace('icp_', ''));
+ });
+
+ this.each(function () {
+
+ $.fn.mColorPicker.drawPickerTriggers($(this));
+ });
+
+ return this;
+ };
+
+ $.fn.mColorPicker.currentColor = false;
+ $.fn.mColorPicker.currentValue = false;
+ $.fn.mColorPicker.color = false;
+
+ $.fn.mColorPicker.init = {
+ replace: '[type=color]',
+ index: 0,
+ enhancedSwatches: true,
+ allowTransparency: true,
+ checkRedraw: 'DOMUpdated', // Change to 'ajaxSuccess' for ajax only or false if not needed
+ liveEvents: false,
+ showLogo: false
+ };
+
+ $.fn.mColorPicker.defaults = {
+ imageFolder: 'images/',
+ swatches: [
+ "#ffffff",
+ "#ffff00",
+ "#00ff00",
+ "#00ffff",
+ "#0000ff",
+ "#ff00ff",
+ "#ff0000",
+ "#4c2b11",
+ "#3b3b3b",
+ "#000000"
+ ]
+ };
+
+ $.fn.mColorPicker.liveEvents = function() {
+
+ $.fn.mColorPicker.init.liveEvents = true;
+
+ if ($.fn.mColorPicker.init.checkRedraw && $.fn.mColorPicker.init.replace) {
+
+ $(document).bind($.fn.mColorPicker.init.checkRedraw + '.mColorPicker', function () {
+
+ $('input[data-mcolorpicker!="true"]').filter(function() {
+
+ return ($.fn.mColorPicker.init.replace == '[type=color]')? this.getAttribute("type") == 'color': $(this).is($.fn.mColorPicker.init.replace);
+ }).mColorPicker();
+ });
+ }
+ };
+
+ $.fn.mColorPicker.drawPickerTriggers = function ($t) {
+
+ if ($t[0].nodeName.toLowerCase() != 'input') return false;
+
+ var id = $t.attr('id') || 'color_' + $.fn.mColorPicker.init.index++,
+ hidden = false;
+
+ $t.attr('id', id);
+
+ if ($t.attr('text') == 'hidden' || $t.attr('data-text') == 'hidden') hidden = true;
+
+ var color = $t.val(),
+ width = ($t.width() > 0)? $t.width(): parseInt($t.css('width'), 10),
+ height = ($t.height())? $t.height(): parseInt($t.css('height'), 10),
+ flt = $t.css('float'),
+ image = (color == 'transparent')? "url('" + $o.imageFolder + "/grid.gif')": '',
+ colorPicker = '';
+
+ $('body').append('<span id="color_work_area"></span>');
+ $('span#color_work_area').append($t.clone(true));
+ colorPicker = $('span#color_work_area').html().replace(/type="color"/gi, '').replace(/input /gi, (hidden)? 'input type="hidden"': 'input type="text"');
+ $('span#color_work_area').html('').remove();
+ $t.after(
+ (hidden)? '<span style="cursor:pointer;border:1px solid black;float:' + flt + ';width:' + width + 'px;height:' + height + 'px;" id="icp_' + id + '">&nbsp;</span>': ''
+ ).after(colorPicker).remove();
+
+ if (hidden) {
+
+ $('#icp_' + id).css({
+ 'background-color': color,
+ 'background-image': image,
+ 'display': 'inline-block'
+ }).attr(
+ 'class', $('#' + id).attr('class')
+ ).addClass(
+ 'mColorPickerTrigger'
+ );
+ } else {
+
+ $('#' + id).css({
+ 'background-color': color,
+ 'background-image': image
+ }).css({
+ 'color': $.fn.mColorPicker.textColor($('#' + id).css('background-color'))
+ }).after(
+ '<span style="cursor:pointer;" id="icp_' + id + '" class="mColorPickerTrigger"><img src="' + $o.imageFolder + 'color.png" style="border:0;margin:0 0 0 3px" align="absmiddle"></span>'
+ ).addClass('mColorPickerInput');
+ }
+
+ $('#icp_' + id).attr('data-mcolorpicker', 'true');
+
+ $('#' + id).addClass('mColorPicker');
+
+ return $('#' + id);
+ };
+
+ $.fn.mColorPicker.drawPicker = function () {
+
+ $(document.createElement("div")).attr(
+ "id","mColorPicker"
+ ).css(
+ 'display','none'
+ ).html(
+ '<div id="mColorPickerWrapper"><div id="mColorPickerImg" class="mColor"></div><div id="mColorPickerImgGray" class="mColor"></div><div id="mColorPickerSwatches"><div class="mClear"></div></div><div id="mColorPickerFooter"><input type="text" size="8" id="mColorPickerInput"/></div></div>'
+ ).appendTo("body");
+
+ $(document.createElement("div")).attr("id","mColorPickerBg").css({
+ 'display': 'none'
+ }).appendTo("body");
+
+ for (n = 9; n > -1; n--) {
+
+ $(document.createElement("div")).attr({
+ 'id': 'cell' + n,
+ 'class': "mPastColor" + ((n > 0)? ' mNoLeftBorder': '')
+ }).html(
+ '&nbsp;'
+ ).prependTo("#mColorPickerSwatches");
+ }
+
+ $('#mColorPicker').css({
+ 'border':'1px solid #ccc',
+ 'color':'#fff',
+ 'z-index':999998,
+ 'width':'194px',
+ 'height':'184px',
+ 'font-size':'12px',
+ 'font-family':'times'
+ });
+
+ $('.mPastColor').css({
+ 'height':'18px',
+ 'width':'18px',
+ 'border':'1px solid #000',
+ 'float':'left'
+ });
+
+ $('#colorPreview').css({
+ 'height':'50px'
+ });
+
+ $('.mNoLeftBorder').css({
+ 'border-left':0
+ });
+
+ $('.mClear').css({
+ 'clear':'both'
+ });
+
+ $('#mColorPickerWrapper').css({
+ 'position':'relative',
+ 'border':'solid 1px gray',
+ 'z-index':999999
+ });
+
+ $('#mColorPickerImg').css({
+ 'height':'128px',
+ 'width':'192px',
+ 'border':0,
+ 'cursor':'crosshair',
+ 'background-image':"url('" + $o.imageFolder + "colorpicker.png')"
+ });
+
+ $('#mColorPickerImgGray').css({
+ 'height':'8px',
+ 'width':'192px',
+ 'border':0,
+ 'cursor':'crosshair',
+ 'background-image':"url('" + $o.imageFolder + "graybar.jpg')"
+ });
+
+ $('#mColorPickerInput').css({
+ 'border':'solid 1px gray',
+ 'font-size':'10pt',
+ 'margin':'3px',
+ 'width':'80px'
+ });
+
+ $('#mColorPickerImgGrid').css({
+ 'border':0,
+ 'height':'20px',
+ 'width':'20px',
+ 'vertical-align':'text-bottom'
+ });
+
+ $('#mColorPickerSwatches').css({
+ 'border-right':'1px solid #000'
+ });
+
+
+ if ($.fn.mColorPicker.init.allowTransparency) $('#mColorPickerFooter').prepend('<span id="mColorPickerTransparent" class="mColor" style="font-size:16px;color:#000;padding-right:30px;padding-top:3px;cursor:pointer;overflow:hidden;float:right;">transparent</span>');
+ if ($.fn.mColorPicker.init.showLogo) $('#mColorPickerFooter').prepend('<a href="http://meta100.com/" title="Meta100 - Designing Fun" alt="Meta100 - Designing Fun" style="float:right;" target="_blank"><img src="' + $o.imageFolder + 'meta100.png" title="Meta100 - Designing Fun" alt="Meta100 - Designing Fun" style="border:0;border-left:1px solid #aaa;right:0;position:absolute;"/></a>');
+
+ $("#mColorPickerBg").click($.fn.mColorPicker.closePicker);
+
+ var swatch = $.fn.mColorPicker.getCookie('swatches'),
+ i = 0;
+
+ if (typeof swatch == 'string') swatch = swatch.split('||');
+ if (swatch == null || $.fn.mColorPicker.init.enhancedSwatches || swatch.length < 10) swatch = $o.swatches;
+
+ $(".mPastColor").each(function() {
+
+ $(this).css('background-color', swatch[i++].toLowerCase());
+ });
+ };
+
+ $.fn.mColorPicker.closePicker = function () {
+
+ $(".mColor, .mPastColor, #mColorPickerInput, #mColorPickerWrapper").unbind();
+ $("#mColorPickerBg").hide();
+ $("#mColorPicker").fadeOut()
+ };
+
+ $.fn.mColorPicker.colorShow = function (id) {
+
+ var $e = $("#icp_" + id);
+ pos = $e.offset(),
+ $i = $("#" + id);
+ hex = $i.attr('data-hex') || $i.attr('hex'),
+ pickerTop = pos.top + $e.outerHeight(),
+ pickerLeft = pos.left,
+ $d = $(document),
+ $m = $("#mColorPicker");
+
+ if ($i.attr('disabled')) return false;
+
+ // KEEP COLOR PICKER IN VIEWPORT
+ if (pickerTop + $m.height() > $d.height()) pickerTop = pos.top - $m.height();
+ if (pickerLeft + $m.width() > $d.width()) pickerLeft = pos.left - $m.width() + $e.outerWidth();
+
+ $m.css({
+ 'top':(pickerTop) + "px",
+ 'left':(pickerLeft) + "px",
+ 'position':'absolute'
+ }).fadeIn("fast");
+
+ $("#mColorPickerBg").css({
+ 'z-index':999990,
+ 'background':'black',
+ 'opacity': .01,
+ 'position':'absolute',
+ 'top':0,
+ 'left':0,
+ 'width': parseInt($d.width(), 10) + 'px',
+ 'height': parseInt($d.height(), 10) + 'px'
+ }).show();
+
+ var def = $i.val();
+
+ $('#colorPreview span').text(def);
+ $('#colorPreview').css('background', def);
+ $('#color').val(def);
+
+ if ($('#' + id).attr('data-text')) $.fn.mColorPicker.currentColor = $e.css('background-color');
+ else $.fn.mColorPicker.currentColor = $i.css('background-color');
+
+ if (hex == 'true') $.fn.mColorPicker.currentColor = $.fn.mColorPicker.RGBtoHex($.fn.mColorPicker.currentColor);
+
+ $("#mColorPickerInput").val($.fn.mColorPicker.currentColor);
+
+ $('.mColor, .mPastColor').bind('mousemove', function(e) {
+
+ var offset = $(this).offset();
+
+ $.fn.mColorPicker.color = $(this).css("background-color");
+
+ if ($(this).hasClass('mPastColor') && hex == 'true') $.fn.mColorPicker.color = $.fn.mColorPicker.RGBtoHex($.fn.mColorPicker.color);
+ else if ($(this).hasClass('mPastColor') && hex != 'true') $.fn.mColorPicker.color = $.fn.mColorPicker.hexToRGB($.fn.mColorPicker.color);
+ else if ($(this).attr('id') == 'mColorPickerTransparent') $.fn.mColorPicker.color = 'transparent';
+ else if (!$(this).hasClass('mPastColor')) $.fn.mColorPicker.color = $.fn.mColorPicker.whichColor(e.pageX - offset.left, e.pageY - offset.top + (($(this).attr('id') == 'mColorPickerImgGray')? 128: 0), hex);
+
+ $.fn.mColorPicker.setInputColor(id, $.fn.mColorPicker.color);
+ }).click(function() {
+
+ $.fn.mColorPicker.colorPicked(id);
+ });
+
+ $('#mColorPickerInput').bind('keyup', function (e) {
+
+ try {
+
+ $.fn.mColorPicker.color = $('#mColorPickerInput').val();
+ $.fn.mColorPicker.setInputColor(id, $.fn.mColorPicker.color);
+
+ if (e.which == 13) $.fn.mColorPicker.colorPicked(id);
+ } catch (r) {}
+
+ }).bind('blur', function () {
+
+ $.fn.mColorPicker.setInputColor(id, $.fn.mColorPicker.currentColor);
+ });
+
+ $('#mColorPickerWrapper').bind('mouseleave', function () {
+
+ $.fn.mColorPicker.setInputColor(id, $.fn.mColorPicker.currentColor);
+ });
+ };
+
+ $.fn.mColorPicker.setInputColor = function (id, color) {
+
+ var image = (color == 'transparent')? "url('" + $o.imageFolder + "grid.gif')": '',
+ textColor = $.fn.mColorPicker.textColor(color);
+
+ if ($('#' + id).attr('data-text') || $('#' + id).attr('text')) $("#icp_" + id).css({'background-color': color, 'background-image': image});
+ $("#" + id).val(color).css({'background-color': color, 'background-image': image, 'color' : textColor}).trigger('change');
+ $("#mColorPickerInput").val(color);
+ };
+
+ $.fn.mColorPicker.textColor = function (val) {
+
+ if (typeof val == 'undefined' || val == 'transparent') return "black";
+ val = $.fn.mColorPicker.RGBtoHex(val);
+ return (parseInt(val.substr(1, 2), 16) + parseInt(val.substr(3, 2), 16) + parseInt(val.substr(5, 2), 16) < 400)? 'white': 'black';
+ };
+
+ $.fn.mColorPicker.setCookie = function (name, value, days) {
+
+ var cookie_string = name + "=" + escape(value),
+ expires = new Date();
+ expires.setDate(expires.getDate() + days);
+ cookie_string += "; expires=" + expires.toGMTString();
+
+ document.cookie = cookie_string;
+ };
+
+ $.fn.mColorPicker.getCookie = function (name) {
+
+ var results = document.cookie.match ( '(^|;) ?' + name + '=([^;]*)(;|$)' );
+
+ if (results) return (unescape(results[2]));
+ else return null;
+ };
+
+ $.fn.mColorPicker.colorPicked = function (id) {
+
+ $.fn.mColorPicker.closePicker();
+
+ if ($.fn.mColorPicker.init.enhancedSwatches) $.fn.mColorPicker.addToSwatch();
+
+ $("#" + id).trigger('colorpicked');
+ };
+
+ $.fn.mColorPicker.addToSwatch = function (color) {
+
+ var swatch = []
+ i = 0;
+
+ if (typeof color == 'string') $.fn.mColorPicker.color = color.toLowerCase();
+
+ $.fn.mColorPicker.currentValue = $.fn.mColorPicker.currentColor = $.fn.mColorPicker.color;
+
+ if ($.fn.mColorPicker.color != 'transparent') swatch[0] = $.fn.mColorPicker.color.toLowerCase();
+
+ $('.mPastColor').each(function() {
+
+ $.fn.mColorPicker.color = $(this).css('background-color').toLowerCase();
+
+ if ($.fn.mColorPicker.color != swatch[0] && $.fn.mColorPicker.RGBtoHex($.fn.mColorPicker.color) != swatch[0] && $.fn.mColorPicker.hexToRGB($.fn.mColorPicker.color) != swatch[0] && swatch.length < 10) swatch[swatch.length] = $.fn.mColorPicker.color;
+
+ $(this).css('background-color', swatch[i++])
+ });
+
+ if ($.fn.mColorPicker.init.enhancedSwatches) $.fn.mColorPicker.setCookie('swatches', swatch.join('||'), 365);
+ };
+
+ $.fn.mColorPicker.whichColor = function (x, y, hex) {
+
+ var colorR = colorG = colorB = 255;
+
+ if (x < 32) {
+
+ colorG = x * 8;
+ colorB = 0;
+ } else if (x < 64) {
+
+ colorR = 256 - (x - 32 ) * 8;
+ colorB = 0;
+ } else if (x < 96) {
+
+ colorR = 0;
+ colorB = (x - 64) * 8;
+ } else if (x < 128) {
+
+ colorR = 0;
+ colorG = 256 - (x - 96) * 8;
+ } else if (x < 160) {
+
+ colorR = (x - 128) * 8;
+ colorG = 0;
+ } else {
+
+ colorG = 0;
+ colorB = 256 - (x - 160) * 8;
+ }
+
+ if (y < 64) {
+
+ colorR += (256 - colorR) * (64 - y) / 64;
+ colorG += (256 - colorG) * (64 - y) / 64;
+ colorB += (256 - colorB) * (64 - y) / 64;
+ } else if (y <= 128) {
+
+ colorR -= colorR * (y - 64) / 64;
+ colorG -= colorG * (y - 64) / 64;
+ colorB -= colorB * (y - 64) / 64;
+ } else if (y > 128) {
+
+ colorR = colorG = colorB = 256 - ( x / 192 * 256 );
+ }
+
+ colorR = Math.round(Math.min(colorR, 255));
+ colorG = Math.round(Math.min(colorG, 255));
+ colorB = Math.round(Math.min(colorB, 255));
+
+ if (hex == 'true') {
+
+ colorR = colorR.toString(16);
+ colorG = colorG.toString(16);
+ colorB = colorB.toString(16);
+
+ if (colorR.length < 2) colorR = 0 + colorR;
+ if (colorG.length < 2) colorG = 0 + colorG;
+ if (colorB.length < 2) colorB = 0 + colorB;
+
+ return "#" + colorR + colorG + colorB;
+ }
+
+ return "rgb(" + colorR + ', ' + colorG + ', ' + colorB + ')';
+ };
+
+ $.fn.mColorPicker.RGBtoHex = function (color) {
+
+ color = color.toLowerCase();
+
+ if (typeof color == 'undefined') return '';
+ if (color.indexOf('#') > -1 && color.length > 6) return color;
+ if (color.indexOf('rgb') < 0) return color;
+
+ if (color.indexOf('#') > -1) {
+
+ return '#' + color.substr(1, 1) + color.substr(1, 1) + color.substr(2, 1) + color.substr(2, 1) + color.substr(3, 1) + color.substr(3, 1);
+ }
+
+ var hexArray = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"],
+ decToHex = "#",
+ code1 = 0;
+
+ color = color.replace(/[^0-9,]/g, '').split(",");
+
+ for (var n = 0; n < color.length; n++) {
+
+ code1 = Math.floor(color[n] / 16);
+ decToHex += hexArray[code1] + hexArray[color[n] - code1 * 16];
+ }
+
+ return decToHex;
+ };
+
+ $.fn.mColorPicker.hexToRGB = function (color) {
+
+ color = color.toLowerCase();
+
+ if (typeof color == 'undefined') return '';
+ if (color.indexOf('rgb') > -1) return color;
+ if (color.indexOf('#') < 0) return color;
+
+ var c = color.replace('#', '');
+
+ if (c.length < 6) c = c.substr(0, 1) + c.substr(0, 1) + c.substr(1, 1) + c.substr(1, 1) + c.substr(2, 1) + c.substr(2, 1);
+
+ return 'rgb(' + parseInt(c.substr(0, 2), 16) + ', ' + parseInt(c.substr(2, 2), 16) + ', ' + parseInt(c.substr(4, 2), 16) + ')';
+ };
+
+ $(document).ready(function () {
+
+ if ($.fn.mColorPicker.init.replace) {
+
+ $('input[data-mcolorpicker!="true"]').filter(function() {
+
+ return ($.fn.mColorPicker.init.replace == '[type=color]')? this.getAttribute("type") == 'color': $(this).is($.fn.mColorPicker.init.replace);
+ }).mColorPicker({
+ imageFolder: 'plugins/message_highlight/colorpicker/images/',
+ allowTransparency: false,
+ showLogo: false,
+ liveEvents: false,
+ checkRedraw: 'ajaxSuccess'
+ });
+
+ $.fn.mColorPicker.liveEvents();
+ }
+ });
+})(jQuery);
diff --git a/plugins/message_highlight/localization/de_DE.inc b/plugins/message_highlight/localization/de_DE.inc
new file mode 100644
index 000000000..a8aecafc9
--- /dev/null
+++ b/plugins/message_highlight/localization/de_DE.inc
@@ -0,0 +1,15 @@
+<?php
+$labels['mh_title'] = 'Nachrichtenmarkierung';
+$labels['mh_matches'] = 'enthält';
+$labels['mh_color'] = 'Farbe';
+$labels['mh_delete'] = 'löschen';
+$labels['mh_delete_description'] = 'Diese Regel löschen';
+$labels['mh_add'] = 'hinzufügen';
+$labels['mh_add_description'] = 'Eine Regel hinzufügen';
+$labels['deleteconfirm'] = 'Möchten Sie diese Regel wirklich löschen?';
+
+// these should never happen, but add anyways
+$labels['headererror'] = 'Diese Regel ist fehlerhaft';
+$labels['inputempty'] = 'Ein oder mehrere Treffer sind leer';
+$labels['invalidcolor'] = 'Ungültige Farbauswahl';
+?>
diff --git a/plugins/message_highlight/localization/en_US.inc b/plugins/message_highlight/localization/en_US.inc
new file mode 100644
index 000000000..4768aba17
--- /dev/null
+++ b/plugins/message_highlight/localization/en_US.inc
@@ -0,0 +1,16 @@
+<?php
+$labels['mh_title'] = 'Message Highlights';
+$labels['mh_matches'] = 'matches';
+$labels['mh_color'] = 'color';
+$labels['mh_delete'] = 'delete';
+$labels['mh_delete_description'] = 'Delete this line';
+$labels['mh_add'] = 'add row';
+$labels['mh_add_description'] = 'Add an extra row beneath this row';
+$labels['deleteconfirm'] = 'Do you really want to delete this rule?';
+
+// these should never happen, but add anyways
+$labels['headererror'] = 'Error in message rule';
+$labels['inputempty'] = 'One or more of your matches are empty';
+$labels['invalidcolor'] = 'Invalid color';
+
+?> \ No newline at end of file
diff --git a/plugins/message_highlight/localization/fr_FR.inc b/plugins/message_highlight/localization/fr_FR.inc
new file mode 100644
index 000000000..fc342c22e
--- /dev/null
+++ b/plugins/message_highlight/localization/fr_FR.inc
@@ -0,0 +1,16 @@
+<?php
+$labels['mh_title'] = 'Mise en valeur des messages';
+$labels['mh_matches'] = 'Correspondance';
+$labels['mh_color'] = 'Couleur';
+$labels['mh_delete'] = 'Supprimer';
+$labels['mh_delete_description'] = 'Supprimer cette ligne';
+$labels['mh_add'] = 'Ajouter une ligne';
+$labels['mh_add_description'] = 'Ajouter une ligne supplémentaire sous cette ligne';
+$labels['deleteconfirm'] = 'Voulez-vous réellement supprimer cette règle ?';
+
+// Cela ne devrait jamais arriver, mais on ne sait jamais
+$labels['headererror'] = 'Erreur dans la règle sur les messages';
+$labels['inputempty'] = 'Une ou plusieurs de vos correspondances sont vides';
+$labels['invalidcolor'] = 'Couleur invalide';
+
+?> \ No newline at end of file
diff --git a/plugins/message_highlight/localization/nl_NL.inc b/plugins/message_highlight/localization/nl_NL.inc
new file mode 100644
index 000000000..b4d29c54a
--- /dev/null
+++ b/plugins/message_highlight/localization/nl_NL.inc
@@ -0,0 +1,15 @@
+<?php
+$labels['mh_title'] = 'Berichten markeren';
+$labels['mh_matches'] = 'bevat';
+$labels['mh_color'] = 'kleur';
+$labels['mh_delete'] = 'verwijderen';
+$labels['mh_delete_description'] = 'Verwijder deze regel';
+$labels['mh_add'] = 'regel toevoegen';
+$labels['mh_add_description'] = 'Voeg een extra regel toe onder deze regel';
+$labels['deleteconfirm'] = 'Wilt u deze regel echt verwijderen?';
+
+// these should never happen, but add anyways
+$labels['headererror'] = 'Fout in configuratie';
+$labels['invalidcolor'] = 'Onjuiste kleur';
+
+?> \ No newline at end of file
diff --git a/plugins/message_highlight/localization/ru_RU.inc b/plugins/message_highlight/localization/ru_RU.inc
new file mode 100644
index 000000000..8f24aa188
--- /dev/null
+++ b/plugins/message_highlight/localization/ru_RU.inc
@@ -0,0 +1,14 @@
+<?php
+$labels['mh_title'] = 'Подсветка сообщений';
+$labels['mh_matches'] = 'совпадения';
+$labels['mh_color'] = 'цвет';
+$labels['mh_delete'] = 'удалить';
+$labels['deleteconfirm'] = 'Вы действительно хотите удалить это правило?';
+
+// these should never happen, but add anyways
+$labels['headererror'] = 'Ошибка в правиле';
+$labels['inputempty'] = 'Одно или более совпадений пусты';
+$labels['invalidcolor'] = 'Неверный цвет';
+
+?>
+
diff --git a/plugins/message_highlight/message_highlight.css b/plugins/message_highlight/message_highlight.css
new file mode 100644
index 000000000..20b27e0d7
--- /dev/null
+++ b/plugins/message_highlight/message_highlight.css
@@ -0,0 +1,74 @@
+.rcmfd_mh_row td {
+ background-color: transparent !important;
+}
+
+.rcmfd_mh_header {
+ font-size: 10pt;
+ margin-right: 10px;
+}
+
+.rcmfd_mh_input {
+ font-size: 10pt;
+ margin-left: 10px !important;
+ margin-right: 10px !important;
+}
+
+.mh_color {
+ margin-right: 10px;
+}
+
+.mh_color_input_2 {
+ background-color:#FF764D;
+ border:1px solid black;
+ cursor:pointer;
+ display:inline-block;
+ float:none;
+ height: 20px;
+ width:100px;
+ margin-left: 10px;
+ vertical-align: top;
+}
+
+.mh_color_input {
+ width: 100px;
+ height: 20px;
+ display: none;
+ padding-top: 4px;
+ margin-right: 10px;
+}
+
+.mh_button {
+ margin-left: 10px;
+}
+
+.mh_first {
+ display: none;
+}
+
+/* icon */
+#sections-table #rcmrowmh_preferences td.section {
+ background-position: 6px -238px;
+}
+
+#sections-table #rcmrowmh_preferences.selected td.section {
+ background-position: 6px -262px;
+}
+
+/* remove some colorpicker elements */
+#mColorPickerTransparent, #mColorPickerSwatches, #mColorPickerImgGray {
+ display: none;
+}
+
+#mColorPickerFooter {
+ background-color: #ffffff !important;
+}
+
+#mColorPickerImg {
+ height: 55px !important;
+}
+
+#mColorPicker {
+ height: 83px !important;
+ padding: 2px !important;
+ background-color: #ffffff !important;
+}
diff --git a/plugins/message_highlight/message_highlight.js b/plugins/message_highlight/message_highlight.js
new file mode 100644
index 000000000..167432d2d
--- /dev/null
+++ b/plugins/message_highlight/message_highlight.js
@@ -0,0 +1,58 @@
+var mh_cur_row;
+
+$(document).ready(function() {
+ if(window.rcmail) {
+
+ rcmail.addEventListener('plugin.mh_receive_row', mh_receive_row);
+
+ rcmail.addEventListener('insertrow', function(evt) {
+ var message = rcmail.env.messages[evt.row.uid];
+
+ // check if our color info is present
+ if(message.flags && message.flags.plugin_mh_color) {
+ $(evt.row.obj).addClass('rcmfd_mh_row');
+ evt.row.obj.style.backgroundColor = message.flags.plugin_mh_color;
+ }
+ });
+
+
+ $('.mh_delete').live('click', function() {
+ mh_delete(this);
+ });
+
+ $('.mh_add').live('click', function() {
+ mh_add(this);
+ });
+ }
+});
+
+
+function mh_delete(button) {
+ if(confirm(rcmail.get_label('message_highlight.deleteconfirm'))) {
+ $(button).closest('tr', '#prefs-details').remove();
+ }
+}
+
+// do an ajax call to get a new row
+function mh_add(button) {
+ mh_cur_row = $(button).closest('tr', '#prefs-details');
+ lock = rcmail.set_busy(true, 'loading');
+ rcmail.http_request('plugin.mh_add_row', '', lock);
+}
+
+// ajax return call
+function mh_receive_row(data) {
+ var row = data.row;
+ $(mh_cur_row).after('<tr><td>'+row+'</td></tr>');
+ //$('.mh_color_input:last').mColorPicker();
+
+ $('input[data-mcolorpicker!="true"]').filter(function() {
+ return ($.fn.mColorPicker.init.replace == '[type=color]')? this.getAttribute("type") == 'color': $(this).is($.fn.mColorPicker.init.replace);
+ }).mColorPicker({
+ imageFolder: 'plugins/message_highlight/colorpicker/images/',
+ allowTransparency: false,
+ showLogo: false,
+ liveEvents: false,
+ checkRedraw: 'ajaxSuccess'
+ });
+}
diff --git a/plugins/message_highlight/message_highlight.php b/plugins/message_highlight/message_highlight.php
new file mode 100644
index 000000000..573257dc0
--- /dev/null
+++ b/plugins/message_highlight/message_highlight.php
@@ -0,0 +1,176 @@
+<?php
+
+/**
+* @version 2.1
+* @author Cor Bosman (cor@roundcu.be)
+*/
+
+class message_highlight extends rcube_plugin
+{
+ public $task = 'mail|settings';
+ private $rcmail;
+ private $prefs;
+
+ public function init()
+ {
+ $this->add_texts('localization/', array('deleteconfirm'));
+ $this->add_hook('messages_list', array($this, 'mh_highlight'));
+ $this->add_hook('preferences_list', array($this, 'mh_preferences'));
+ $this->add_hook('preferences_save', array($this, 'mh_save'));
+ $this->add_hook('preferences_sections_list',array($this, 'mh_preferences_section'));
+ $this->add_hook('storage_init', array($this, 'storage_init'));
+
+ $this->register_action('plugin.mh_add_row', array($this, 'mh_add_row'));
+
+ $this->include_script('message_highlight.js');
+ $this->include_script('colorpicker/mColorPicker.js');
+ $this->include_stylesheet('message_highlight.css');
+ }
+
+ function storage_init($p)
+ {
+ $p['fetch_headers'] .= trim($p['fetch_headers']. ' ' . 'CC');
+ return($p);
+ }
+
+
+ // add color information for all messages
+ function mh_highlight($p)
+ {
+ $rcmail = rcmail::get_instance();
+ $this->prefs = $rcmail->config->get('message_highlight', array());
+
+ // dont loop over all messages if we dont have any highlights or no msgs
+ if(!count($this->prefs) or !isset($p['messages']) or !is_array($p['messages'])) return $p;
+
+ // loop over all messages and add highlight color to each message
+ foreach($p['messages'] as $message) {
+ if(($color = $this->mh_find_match($message)) !== false ) {
+ $message->list_flags['extra_flags']['plugin_mh_color'] = $color;
+ }
+ }
+ return($p);
+ }
+
+ // find a match for this message
+ function mh_find_match($message) {
+ foreach($this->prefs as $p) {
+ if(stristr($message->$p['header'], $p['input'])) {
+ return($p['color']);
+ }
+ }
+ return false;
+ }
+
+ // user preferences
+ function mh_preferences($args) {
+ if($args['section'] == 'mh_preferences') {
+ $this->add_texts('localization/', false);
+ $rcmail = rcmail::get_instance();
+
+ $args['blocks']['mh_preferences'] = array(
+ 'options' => array(),
+ 'name' => Q($this->gettext('mh_title'))
+ );
+
+ $i = 1;
+ $prefs = $rcmail->config->get('message_highlight', array());
+
+ foreach($prefs as $p) {
+ $args['blocks']['mh_preferences']['options'][$i++] = array(
+ 'content' => $this->mh_get_form_row($p['header'], $p['input'], $p['color'], true)
+ );
+ }
+
+ // no rows yet, add 1 empty row
+ if($i == 1) {
+ $args['blocks']['mh_preferences']['options'][$i] = array(
+ 'content' => $this->mh_get_form_row()
+ );
+ }
+ }
+
+ return($args);
+ }
+
+ function mh_add_row() {
+ $rcmail = rcmail::get_instance();
+ $rcmail->output->command('plugin.mh_receive_row', array('row' => $this->mh_get_form_row()));
+ }
+
+ // create a form row
+ function mh_get_form_row($header = 'from', $input = '', $color = '#ffffff', $delete = false) {
+
+ // header select box
+ $header_select = new html_select(array('name' => '_mh_header[]', 'class' => 'rcmfd_mh_header'));
+ $header_select->add(Q($this->gettext('subject')), 'subject');
+ $header_select->add(Q($this->gettext('from')), 'from');
+ $header_select->add(Q($this->gettext('to')), 'to');
+ $header_select->add(Q($this->gettext('cc')), 'cc');
+
+ // input field
+ $input = new html_inputfield(array('name' => '_mh_input[]', 'class' => 'rcmfd_mh_input', 'type' => 'text', 'autocomplete' => 'off', 'value' => $input));
+
+ // color box
+ $color = html::tag('input', array('id' => uniqid() ,'name' => '_mh_color[]' ,'type' => 'color' ,'text' => 'hidden', 'class' => 'mh_color_input', 'value' => $color, 'data-hex' => 'true'));
+
+ // delete button
+ $button = html::tag('input', array('class' => 'button mh_delete mh_button', 'type' => 'button', 'value' => $this->gettext('mh_delete'), 'title' => $this->gettext('mh_delete_description')));
+
+ // add button
+ $add_button = html::tag('input', array('class' => 'button mh_add mh_button', 'type' => 'button', 'value' => $this->gettext('mh_add'), 'title' => $this->gettext('mh_add_description')));
+
+ $content = $header_select->show($header) .
+ html::span('mh_matches', Q($this->gettext('mh_matches'))) .
+ $input->show() .
+ html::span('mh_color', Q($this->gettext('mh_color'))) .
+ $color . $button . $add_button;
+
+ if(rcmail::get_instance()->config->get('request_saver_compress_html', false)){
+ $content = request_saver::html_compress($content);
+ }
+
+ return($content);
+ }
+
+ // add a section to the preferences tab
+ function mh_preferences_section($args) {
+ $this->add_texts('localization/', false);
+ $args['list']['mh_preferences'] = array(
+ 'id' => 'mh_preferences',
+ 'section' => Q($this->gettext('mh_title'))
+ );
+ return($args);
+ }
+
+ // save preferences
+ function mh_save($args) {
+ if($args['section'] != 'mh_preferences') return;
+
+ $rcmail = rcmail::get_instance();
+
+ $header = get_input_value('_mh_header', RCUBE_INPUT_POST);
+ $input = get_input_value('_mh_input', RCUBE_INPUT_POST);
+ $color = get_input_value('_mh_color', RCUBE_INPUT_POST);
+
+
+ for($i=0; $i < count($header); $i++) {
+ if(!in_array($header[$i], array('subject', 'from', 'to', 'cc'))) {
+ $rcmail->output->show_message('message_highlight.headererror', 'error');
+ return;
+ }
+ if(!preg_match('/^#[0-9a-fA-F]{2,6}$/', $color[$i])) {
+ $rcmail->output->show_message('message_highlight.invalidcolor', 'error');
+ return;
+ }
+ if($input[$i] == '') {
+ continue;
+ }
+ $prefs[] = array('header' => $header[$i], 'input' => $input[$i], 'color' => $color[$i]);
+ }
+
+ $args['prefs']['message_highlight'] = $prefs;
+ return($args);
+ }
+}
+?>
diff --git a/plugins/message_highlight/package.xml b/plugins/message_highlight/package.xml
new file mode 100644
index 000000000..8da1c72f5
--- /dev/null
+++ b/plugins/message_highlight/package.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<package xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" packagerversion="1.9.0" version="2.0" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0
+ http://pear.php.net/dtd/tasks-1.0.xsd
+ http://pear.php.net/dtd/package-2.0
+ http://pear.php.net/dtd/package-2.0.xsd">
+ <name>message_highlight</name>
+ <lead>
+ <name>Cor Bosman</name>
+ <user>cor</user>
+ <email>cor@roundcu.be</email>
+ <active>yes</active>
+ </lead>
+ <uri>https://github.com/corbosman/message_highlight</uri>
+ <version>
+ <release>2.0</release>
+ </version>
+ <license uri="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPLv2</license>
+</package>
diff --git a/plugins/quickrules/localization/cs_CZ.inc b/plugins/quickrules/localization/cs_CZ.inc
new file mode 100644
index 000000000..d2fa4f533
--- /dev/null
+++ b/plugins/quickrules/localization/cs_CZ.inc
@@ -0,0 +1,9 @@
+<?php
+/* Author: Libor Klepac */
+
+$labels = array();
+$labels['createfilter'] = 'Vytvořit filtr...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/quickrules/localization/de_CH.inc b/plugins/quickrules/localization/de_CH.inc
new file mode 100644
index 000000000..f1fe8e579
--- /dev/null
+++ b/plugins/quickrules/localization/de_CH.inc
@@ -0,0 +1,10 @@
+<?php
+/* Author: Mike Constabel */
+
+$labels = array();
+$labels['createfilter'] = 'Erstelle Filter...';
+$labels['createfilterbased'] = 'Erstelle einen auf dieser Nachricht basierenden Filter';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/quickrules/localization/de_DE.inc b/plugins/quickrules/localization/de_DE.inc
new file mode 100644
index 000000000..f1fe8e579
--- /dev/null
+++ b/plugins/quickrules/localization/de_DE.inc
@@ -0,0 +1,10 @@
+<?php
+/* Author: Mike Constabel */
+
+$labels = array();
+$labels['createfilter'] = 'Erstelle Filter...';
+$labels['createfilterbased'] = 'Erstelle einen auf dieser Nachricht basierenden Filter';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/quickrules/localization/en_GB.inc b/plugins/quickrules/localization/en_GB.inc
new file mode 100644
index 000000000..74b4dcdc5
--- /dev/null
+++ b/plugins/quickrules/localization/en_GB.inc
@@ -0,0 +1,10 @@
+<?php
+/* Author: Philip Weir */
+
+$labels = array();
+$labels['createfilter'] = 'Create filter';
+$labels['createfilterbased'] = 'Create a filter based on this message';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/quickrules/localization/en_US.inc b/plugins/quickrules/localization/en_US.inc
new file mode 100644
index 000000000..74b4dcdc5
--- /dev/null
+++ b/plugins/quickrules/localization/en_US.inc
@@ -0,0 +1,10 @@
+<?php
+/* Author: Philip Weir */
+
+$labels = array();
+$labels['createfilter'] = 'Create filter';
+$labels['createfilterbased'] = 'Create a filter based on this message';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/quickrules/localization/hu_HU.inc b/plugins/quickrules/localization/hu_HU.inc
new file mode 100644
index 000000000..8d3eeefb8
--- /dev/null
+++ b/plugins/quickrules/localization/hu_HU.inc
@@ -0,0 +1,9 @@
+<?php
+/* Author: Norbert Wellinger */
+
+$labels = array();
+$labels['createfilter'] = 'Szűrő létrehozása..';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/quickrules/localization/it_IT.inc b/plugins/quickrules/localization/it_IT.inc
new file mode 100644
index 000000000..5201faedc
--- /dev/null
+++ b/plugins/quickrules/localization/it_IT.inc
@@ -0,0 +1,10 @@
+<?php
+/* Author: Alessio Cecchi */
+
+$labels = array();
+$labels['createfilter'] = 'Crea filtro...';
+$labels['createfilterbased'] = 'Crea un filtro basato su questo messaggio';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/quickrules/localization/pl_PL.inc b/plugins/quickrules/localization/pl_PL.inc
new file mode 100644
index 000000000..5d14121b2
--- /dev/null
+++ b/plugins/quickrules/localization/pl_PL.inc
@@ -0,0 +1,9 @@
+<?php
+/* Author: DZIOBAK */
+
+$labels = array();
+$labels['createfilter'] = 'Utwórz filtr...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/quickrules/localization/pt_BR.inc b/plugins/quickrules/localization/pt_BR.inc
new file mode 100644
index 000000000..d0b4aa838
--- /dev/null
+++ b/plugins/quickrules/localization/pt_BR.inc
@@ -0,0 +1,9 @@
+<?php
+/* Author: Pedro Padron */
+
+$labels = array();
+$labels['createfilter'] = 'Criar filtro...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/quickrules/localization/pt_PT.inc b/plugins/quickrules/localization/pt_PT.inc
new file mode 100644
index 000000000..d0b4aa838
--- /dev/null
+++ b/plugins/quickrules/localization/pt_PT.inc
@@ -0,0 +1,9 @@
+<?php
+/* Author: Pedro Padron */
+
+$labels = array();
+$labels['createfilter'] = 'Criar filtro...';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/quickrules/package.xml b/plugins/quickrules/package.xml
new file mode 100644
index 000000000..3fa80454a
--- /dev/null
+++ b/plugins/quickrules/package.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<package xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" packagerversion="1.9.0" version="2.0" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0
+ http://pear.php.net/dtd/tasks-1.0.xsd
+ http://pear.php.net/dtd/package-2.0
+ http://pear.php.net/dtd/package-2.0.xsd">
+ <name>quickrules</name>
+ <uri>http://github.com/JohnDoh/Roundcube-Plugin-QuickRules/</uri>
+ <summary>Adds a button to the message list to allow the quick creation of rules in the SieveRules plugin</summary>
+ <description>Adds a button to the message list to allow the quick creation of rules in the SieveRules plugin. Infomration from selected emails is used to prefile the new rule form.</description>
+ <lead>
+ <name>Philip Weir</name>
+ <user>JohnDoh</user>
+ <email>roundcube@tehinterweb.co.uk</email>
+ <active>yes</active>
+ </lead>
+ <date>2013-02-24</date>
+ <time>10:16:53</time>
+ <version>
+ <release>1.4</release>
+ <api>1.4</api>
+ </version>
+ <stability>
+ <release>stable</release>
+ <api>stable</api>
+ </stability>
+ <license uri="http://www.gnu.org/licenses/gpl.html">GNU GPLv3+</license>
+ <notes>-</notes>
+ <contents>
+ <dir baseinstalldir="/" name="/">
+ <file name="quickrules.php" role="php">
+ <tasks:replace from="@name@" to="name" type="package-info"/>
+ <tasks:replace from="@package_version@" to="version" type="package-info"/>
+ </file>
+ <file name="quickrules.js" role="data">
+ <tasks:replace from="@name@" to="name" type="package-info"/>
+ <tasks:replace from="@package_version@" to="version" type="package-info"/>
+ </file>
+ <file name="CHANGELOG" role="data"/>
+ <file name="README.md" role="data"/>
+ <file name="localization/cs_CZ.inc" role="data"/>
+ <file name="localization/de_CH.inc" role="data"/>
+ <file name="localization/de_DE.inc" role="data"/>
+ <file name="localization/en_GB.inc" role="data"/>
+ <file name="localization/en_US.inc" role="data"/>
+ <file name="localization/hu_HU.inc" role="data"/>
+ <file name="localization/it_IT.inc" role="data"/>
+ <file name="localization/pl_PL.inc" role="data"/>
+ <file name="localization/pt_BR.inc" role="data"/>
+ <file name="localization/pt_PT.inc" role="data"/>
+ <file name="skins/classic/ie6hacks.css" role="data"/>
+ <file name="skins/classic/mail_toolbar.gif" role="data"/>
+ <file name="skins/classic/mail_toolbar.png" role="data"/>
+ <file name="skins/classic/messageactions.gif" role="data"/>
+ <file name="skins/classic/messageactions.png" role="data"/>
+ <file name="skins/classic/quickrules.css" role="data"/>
+ <file name="skins/larry/ie6hacks.css" role="data"/>
+ <file name="skins/larry/mail_toolbar.png" role="data"/>
+ <file name="skins/larry/messageactions.png" role="data"/>
+ <file name="skins/larry/quickrules.css" role="data"/>
+ </dir>
+ <!-- / -->
+ </contents>
+ <dependencies>
+ <required>
+ <php>
+ <min>5.2.1</min>
+ </php>
+ <pearinstaller>
+ <min>1.7.0</min>
+ </pearinstaller>
+ <package>
+ <name>sieverules</name>
+ <uri>http://github.com/JohnDoh/Roundcube-Plugin-SieveRules-Managesieve/</uri>
+ <min>1.15</min>
+ </package>
+ </required>
+ </dependencies>
+ <phprelease/>
+</package>
diff --git a/plugins/quickrules/quickrules.js b/plugins/quickrules/quickrules.js
new file mode 100644
index 000000000..7b8702330
--- /dev/null
+++ b/plugins/quickrules/quickrules.js
@@ -0,0 +1,169 @@
+/**
+ * QuickRules plugin script
+ */
+
+function rcmail_quickrules() {
+ if (!rcmail.env.uid && (!rcmail.message_list || !rcmail.message_list.get_selection().length))
+ return;
+
+ var uids = rcmail.env.uid ? rcmail.env.uid : rcmail.message_list.get_selection().join(',');
+
+ var lock = rcmail.set_busy(true, 'loading');
+ rcmail.http_post('plugin.quickrules.add', '_uid='+uids+'&_mbox='+urlencode(rcmail.env.mailbox), lock);
+}
+
+function quickrules_add_filter() {
+ rcmail.command('plugin.sieverules.add');
+}
+
+function quickrules_setup_rules() {
+ var rulesTable = rcube_find_object('rules-table');
+ var actsTable = rcube_find_object('actions-table');
+
+ if (rcmail_quickrules_rules.length < 1)
+ return;
+
+ for (i = 1; i < rcmail_quickrules_rules.length; i++)
+ rcmail.command('plugin.sieverules.add_rule','', rulesTable.tBodies[0].rows[0]);
+
+ var headers = document.getElementsByName('_selheader[]');
+ var ops = document.getElementsByName('_operator[]');
+ var targets = document.getElementsByName('_target[]');
+ var otherHeaders = document.getElementsByName('_header[]');
+ var headerParts = "";
+
+ for (var i = 1; i < headers.length; i++) {
+ $(headers[i]).val(rcmail_quickrules_rules[i-1].header);
+ $(ops[i]).val(rcmail_quickrules_rules[i-1].op);
+ headerParts = "";
+
+ // other headers
+ if (rcmail_quickrules_rules[i-1].header.indexOf('other') == 0) {
+ headerParts = rcmail_quickrules_rules[i-1].header.split('::');
+ rcmail_quickrules_rules[i-1].header = 'header::other'
+ $(headers[i]).val(rcmail_quickrules_rules[i-1].header);
+ }
+
+ // check values set ok before adding rule
+ if ($(headers[i]).val() == rcmail_quickrules_rules[i-1].header && $(ops[i]).val() == rcmail_quickrules_rules[i-1].op) {
+ rcmail.sieverules_header_select(headers[i]);
+
+ if (headerParts)
+ $(otherHeaders[i]).val(headerParts[1]);
+
+ // set the op again (header onchange resets it)
+ $(ops[i]).val(rcmail_quickrules_rules[i-1].op);
+ rcmail.sieverules_rule_op_select(ops[i]);
+
+ targets[i].value = rcmail_quickrules_rules[i-1].target;
+ }
+ else {
+ headers[i].selectedIndex = 0;
+ ops[i].selectedIndex = 0;
+ }
+ }
+
+ if (rcmail_quickrules_actions.length < 1)
+ return;
+
+ for (i = 1; i < rcmail_quickrules_actions.length; i++)
+ rcmail.command('plugin.sieverules.add_action','', actsTable.tBodies[0].rows[0]);
+
+ var acts = document.getElementsByName('_act[]');
+ var folders = document.getElementsByName('_folder[]');
+ var flags = document.getElementsByName('_imapflags[]');
+
+ for (var i = 1; i < acts.length; i++) {
+ $(acts[i]).val(rcmail_quickrules_actions[i-1].act);
+
+ // check for imap4flags
+ if (rcmail_quickrules_actions[i-1].act == 'imapflags') {
+ if ($(acts[i]).val() != rcmail_quickrules_actions[i-1].act)
+ $(acts[i]).val('imap4flags');
+
+ // check values set ok before adding action
+ if ($(acts[i]).val() == rcmail_quickrules_actions[i-1].act) {
+ rcmail.sieverules_action_select(acts[i]);
+ $(flags[i]).val(rcmail_quickrules_actions[i-1].props);
+ }
+ else {
+ acts[i].selectedIndex = 0;
+ }
+ }
+ else {
+ // check values set ok before adding action
+ if ($(acts[i]).val() == rcmail_quickrules_actions[i-1].act) {
+ rcmail.sieverules_action_select(acts[i]);
+ $(folders[i]).val(rcmail_quickrules_actions[i-1].props);
+ }
+ else {
+ acts[i].selectedIndex = 0;
+ }
+ }
+ }
+}
+
+function rcmail_quickrules_status(command) {
+ switch (command) {
+ case 'beforedelete':
+ if (!rcmail.env.flag_for_deletion && rcmail.env.trash_mailbox &&
+ rcmail.env.mailbox != rcmail.env.trash_mailbox &&
+ (rcmail.message_list && !rcmail.message_list.shiftkey))
+ rcmail.enable_command('plugin.quickrules.create', false);
+
+ break;
+ case 'beforemove':
+ case 'beforemoveto':
+ rcmail.enable_command('plugin.quickrules.create', false);
+ break;
+ case 'aftermove':
+ case 'aftermoveto':
+ if (rcmail.env.action == 'show')
+ rcmail.enable_command('plugin.quickrules.create', true);
+
+ break;
+ case 'afterpurge':
+ case 'afterexpunge':
+ if (!rcmail.env.messagecount && rcmail.task == 'mail')
+ rcmail.enable_command('plugin.quickrules.create', false);
+
+ break;
+ }
+}
+
+function rcmail_quickrules_init() {
+ if (rcmail.env.action == 'plugin.sieverules')
+ quickrules_add_filter();
+
+ if (rcmail.env.action == 'plugin.sieverules.add')
+ quickrules_setup_rules();
+
+ if (window.rcm_contextmenu_register_command)
+ rcm_contextmenu_register_command('quickrules', 'rcmail_quickrules', rcmail.gettext('quickrules.createfilter'), 'moveto', 'after', false);
+}
+
+$(document).ready(function() {
+ if (window.rcmail) {
+ rcmail.addEventListener('init', function(evt) {
+ // register command (directly enable in message view mode)
+ rcmail.register_command('plugin.quickrules.create', rcmail_quickrules, rcmail.env.uid);
+
+ if (rcmail.message_list && rcmail.env.junk_mailbox) {
+ rcmail.message_list.addEventListener('select', function(list) {
+ rcmail.enable_command('plugin.quickrules.create', list.get_single_selection() != null);
+ });
+ }
+ });
+
+ rcmail.add_onload('rcmail_quickrules_init()');
+
+ // update button activation after external events
+ rcmail.addEventListener('beforedelete', function(props) { rcmail_quickrules_status('beforedelete'); } );
+ rcmail.addEventListener('beforemove', function(props) { rcmail_quickrules_status('beforemove'); } );
+ rcmail.addEventListener('beforemoveto', function(props) { rcmail_quickrules_status('beforemoveto'); } );
+ rcmail.addEventListener('aftermove', function(props) { rcmail_quickrules_status('aftermove'); } );
+ rcmail.addEventListener('aftermoveto', function(props) { rcmail_quickrules_status('aftermoveto'); } );
+ rcmail.addEventListener('afterpurge', function(props) { rcmail_quickrules_status('afterpurge'); } );
+ rcmail.addEventListener('afterexpunge', function(props) { rcmail_quickrules_status('afterexpunge'); } );
+ }
+}); \ No newline at end of file
diff --git a/plugins/quickrules/quickrules.php b/plugins/quickrules/quickrules.php
new file mode 100644
index 000000000..575dd5724
--- /dev/null
+++ b/plugins/quickrules/quickrules.php
@@ -0,0 +1,137 @@
+<?php
+
+/**
+ * QuickRules
+ *
+ * Plugin to allow the user to quickly create filters from the message list
+ *
+ * @version @package_version@
+ * @requires SieveRules plugin
+ * @author Philip Weir
+ */
+class quickrules extends rcube_plugin
+{
+ public $task = 'mail|settings';
+
+ // default values: label => value
+ private $headers = array('subject' => 'header::Subject',
+ 'from' => 'address::From',
+ 'to' => 'address::To',
+ 'cc' => 'address::Cc',
+ 'bcc' => 'address::Bcc',
+ 'envelopeto' => 'envelope::To',
+ 'envelopefrom' => 'envelope::From'
+ );
+
+ private $operators = array('filtercontains' => 'contains',
+ 'filternotcontains' => 'notcontains',
+ 'filteris' => 'is',
+ 'filterisnot' => 'notis',
+ 'filterexists' => 'exists',
+ 'filternotexists' => 'notexists'
+ );
+
+ private $flags = array('flagread' => '\\Seen',
+ 'flagdeleted' => '\\Deleted',
+ 'flaganswered' => '\\Answered',
+ 'flagdraft' => '\\Draft',
+ 'flagflagged' => '\\\\Flagged'
+ );
+
+ private $additional_headers = array('List-Id');
+
+ function init()
+ {
+ // load required plugin
+ $this->require_plugin('sieverules');
+
+ $rcmail = rcube::get_instance();
+ $this->register_action('plugin.quickrules.add', array($this, 'init_rule'));
+
+ if ($rcmail->task == 'mail' && ($rcmail->action == '' || $rcmail->action == 'show')) {
+ $this->add_texts('localization', true);
+ $this->include_script('quickrules.js');
+ $this->include_stylesheet($this->local_skin_path() .'/quickrules.css');
+ if ($rcmail->output->browser->ie && $rcmail->output->browser->ver == 6)
+ $this->include_stylesheet($this->local_skin_path() . '/ie6hacks.css');
+
+ $this->add_button(array('command' => 'plugin.quickrules.create', 'type' => 'link', 'class' => 'button buttonPas quickrules disabled', 'classact' => 'button quickrules', 'classsel' => 'button quickrulesSel', 'title' => 'quickrules.createfilterbased', 'label' => 'quickrules.createfilter'), 'toolbar');
+ }
+
+ if ($_SESSION['plugin.quickrules']) {
+ $this->add_hook('storage_init', array($this, 'fetch_headers'));
+ $this->_create_rule();
+ }
+ }
+
+ function init_rule()
+ {
+ $_SESSION['plugin.quickrules'] = true;
+ $_SESSION['plugin.quickrules.uids'] = rcube_utils::get_input_value('_uid', rcube_utils::INPUT_POST);
+ $_SESSION['plugin.quickrules.mbox'] = rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_POST);
+
+ rcube::get_instance()->output->redirect(array('task' => 'settings', 'action' => 'plugin.sieverules'));
+ }
+
+ function fetch_headers($attr)
+ {
+ $attr['fetch_headers'] .= trim($attr['fetch_headers'] . join(' ', $this->additional_headers));
+ return($attr);
+ }
+
+ private function _create_rule()
+ {
+ $rcmail = rcube::get_instance();
+ if ($rcmail->action == 'plugin.sieverules' || $rcmail->action == 'plugin.sieverules.add') {
+ $this->include_script('quickrules.js');
+
+ if ($rcmail->action == 'plugin.sieverules.add') {
+ $uids = $_SESSION['plugin.quickrules.uids'];
+ $mbox = $_SESSION['plugin.quickrules.mbox'];
+ $rcmail->storage_init();
+
+ $rules = array();
+ $actions = array();
+ foreach (explode(",", $uids) as $uid) {
+ $message = new rcube_message($uid);
+ $rules[] = rcube_output::json_serialize(array('header' => $this->headers['from'], 'op' => $this->operators['filteris'], 'target' => $message->sender['mailto']));
+
+ $recipients = array();
+ $recipients_array = rcube_mime::decode_address_list($message->headers->to);
+ foreach ($recipients_array as $recipient)
+ $recipients[] = $recipient['mailto'];
+
+ $identity = $rcmail->user->get_identity();
+ $recipient_str = join(', ', $recipients);
+ if ($recipient_str != $identity['email'])
+ $rules[] = rcube_output::json_serialize(array('header' => $this->headers['to'], 'op' => $this->operators['filteris'], 'target' => $recipient_str));
+
+ if (strlen($message->subject) > 0)
+ $rules[] = rcube_output::json_serialize(array('header' => $this->headers['subject'], 'op' => $this->operators['filtercontains'], 'target' => $message->subject));
+
+ foreach ($this->additional_headers as $header) {
+ if (strlen($message->headers->others[strtolower($header)]) > 0)
+ $rules[] = rcube_output::json_serialize(array('header' => 'other::' . $header, 'op' => $this->operators['filteris'], 'target' => $message->headers->others[strtolower($header)]));
+ }
+
+ if ($mbox != 'INBOX')
+ $actions[] = rcube_output::json_serialize(array('act' => 'fileinto', 'props' => $mbox));
+
+ foreach ($message->headers->flags as $flag) {
+ if ($flag == 'Flagged')
+ $actions[] = rcube_output::json_serialize(array('act' => 'imapflags', 'props' => $this->flags['flagflagged']));
+ }
+ }
+
+ $this->api->output->add_script(rcmail_output::JS_OBJECT_NAME . "_quickrules_rules = [" . implode(',', $rules) . "];");
+ $this->api->output->add_script(rcmail_output::JS_OBJECT_NAME . "_quickrules_actions = [" . implode(',', $actions) . "];");
+
+ $_SESSION['plugin.quickrules'] = false;
+ $_SESSION['plugin.quickrules.uids'] = '';
+ $_SESSION['plugin.quickrules.mbox'] = '';
+ }
+ }
+ }
+}
+
+?> \ No newline at end of file
diff --git a/plugins/quickrules/skins/classic/ie6hacks.css b/plugins/quickrules/skins/classic/ie6hacks.css
new file mode 100644
index 000000000..2a3b57506
--- /dev/null
+++ b/plugins/quickrules/skins/classic/ie6hacks.css
@@ -0,0 +1,14 @@
+/**
+ * QuickRules plugin styles (IE6 hacks)
+ */
+
+#messagetoolbar a.quickrules,
+#messagetoolbar a.quickrulesSel
+{
+ background-image: url(mail_toolbar.gif);
+}
+
+#rcmContextMenu .quickrules a
+{
+ background-image: url(messageactions.gif);
+} \ No newline at end of file
diff --git a/plugins/quickrules/skins/classic/mail_toolbar.gif b/plugins/quickrules/skins/classic/mail_toolbar.gif
new file mode 100644
index 000000000..96945bee8
--- /dev/null
+++ b/plugins/quickrules/skins/classic/mail_toolbar.gif
Binary files differ
diff --git a/plugins/quickrules/skins/classic/mail_toolbar.png b/plugins/quickrules/skins/classic/mail_toolbar.png
new file mode 100644
index 000000000..9a6397482
--- /dev/null
+++ b/plugins/quickrules/skins/classic/mail_toolbar.png
Binary files differ
diff --git a/plugins/quickrules/skins/classic/messageactions.gif b/plugins/quickrules/skins/classic/messageactions.gif
new file mode 100644
index 000000000..bdfa8e142
--- /dev/null
+++ b/plugins/quickrules/skins/classic/messageactions.gif
Binary files differ
diff --git a/plugins/quickrules/skins/classic/messageactions.png b/plugins/quickrules/skins/classic/messageactions.png
new file mode 100644
index 000000000..492565fda
--- /dev/null
+++ b/plugins/quickrules/skins/classic/messageactions.png
Binary files differ
diff --git a/plugins/quickrules/skins/classic/quickrules.css b/plugins/quickrules/skins/classic/quickrules.css
new file mode 100644
index 000000000..1ff5a33b2
--- /dev/null
+++ b/plugins/quickrules/skins/classic/quickrules.css
@@ -0,0 +1,26 @@
+/**
+ * QuickRules plugin styles
+ */
+
+#messagetoolbar a.quickrules,
+#messagetoolbar a.quickrulesSel
+{
+ text-indent: -5000px;
+ background-image: url(mail_toolbar.png);
+}
+
+#messagetoolbar a.quickrules
+{
+ background-position: 0 0;
+}
+
+#messagetoolbar a.quickrulesSel
+{
+ background-position: 0 -32px;
+}
+
+#rcmContextMenu .quickrules a
+{
+ background-image: url(messageactions.png);
+ background-position: 7px 0px;
+} \ No newline at end of file
diff --git a/plugins/quickrules/skins/larry/ie6hacks.css b/plugins/quickrules/skins/larry/ie6hacks.css
new file mode 100644
index 000000000..f5e8ac794
--- /dev/null
+++ b/plugins/quickrules/skins/larry/ie6hacks.css
@@ -0,0 +1,3 @@
+/**
+ * QuickRules plugin styles (IE6 hacks)
+ */
diff --git a/plugins/quickrules/skins/larry/mail_toolbar.png b/plugins/quickrules/skins/larry/mail_toolbar.png
new file mode 100644
index 000000000..f5738f0f5
--- /dev/null
+++ b/plugins/quickrules/skins/larry/mail_toolbar.png
Binary files differ
diff --git a/plugins/quickrules/skins/larry/messageactions.png b/plugins/quickrules/skins/larry/messageactions.png
new file mode 100644
index 000000000..f7a431d10
--- /dev/null
+++ b/plugins/quickrules/skins/larry/messageactions.png
Binary files differ
diff --git a/plugins/quickrules/skins/larry/quickrules.css b/plugins/quickrules/skins/larry/quickrules.css
new file mode 100644
index 000000000..64f146b0c
--- /dev/null
+++ b/plugins/quickrules/skins/larry/quickrules.css
@@ -0,0 +1,21 @@
+/**
+ * QuickRules plugin styles
+ */
+
+#messagetoolbar a.quickrules,
+#messagetoolbar a.quickrulesSel
+{
+ background-image: url(mail_toolbar.png);
+}
+
+#messagetoolbar a.quickrules,
+#messagetoolbar a.quickrulesSel
+{
+ background-position: center -16px;
+}
+
+#rcmContextMenu .quickrules a span
+{
+ background-image: url(messageactions.png);
+ background-position: 5px 6px;
+} \ No newline at end of file
diff --git a/plugins/sauserprefs/config.inc.php.dist b/plugins/sauserprefs/config.inc.php.dist
new file mode 100644
index 000000000..81b85507f
--- /dev/null
+++ b/plugins/sauserprefs/config.inc.php.dist
@@ -0,0 +1,160 @@
+<?php
+
+/**
+ * SAUserPrefs configuration file
+ */
+
+// spamassassin database settings
+$rcmail_config['sauserprefs_db_dsnw'] = 'mysql://username:password@localhost/database';
+
+// PEAR database DSN for read only operations (if empty write database will be used)
+// useful for database replication
+$rcmail_config['sauserprefs_db_dsnr'] = '';
+
+// use persistent db-connections
+// beware this will not "always" work as expected
+// see: http://www.php.net/manual/en/features.persistent-connections.php
+$rcmail_config['sauserprefs_db_persistent'] = FALSE;
+
+// table that holds user prefs
+$rcmail_config['sauserprefs_sql_table_name'] = "userpref";
+
+// name of the username field in the user prefs table
+$rcmail_config['sauserprefs_sql_username_field'] = "username";
+
+// name of the preference field in the user prefs table, holds the name of the preference
+$rcmail_config['sauserprefs_sql_preference_field'] = "preference";
+
+// name of the value field in the user prefs table, holds the value of the preference
+$rcmail_config['sauserprefs_sql_value_field'] = "value";
+
+// username of the current user in the database, normaly %u (username from the session info)
+// %u is replaced with the username (from the session info)
+// %l is replaced with the local part of the username (if the username is an email address)
+// %d is replaced with the domain part of the username (if the username is an email address or default mail domain if not)
+// %i is replaced with the email address from the user's default identity
+$rcmail_config['sauserprefs_userid'] = "%u";
+
+// username of the "global" or default settings user in the database, normaly $GLOBAL or @GLOBAL
+$rcmail_config['sauserprefs_global_userid'] = "\$GLOBAL";
+
+// enable the whitelists synchronisation, check README for more information
+$rcmail_config['sauserprefs_whitelist_sync'] = FALSE;
+
+// id of the address book to synchronise the whitelist with, null for default Roundcube address book
+$rcmail_config['sauserprefs_whitelist_abook_id'] = null;
+
+// don't allow these settings to be overriden by the user
+// eg. $rcmail_config['sauserprefs_dont_override'] = array('required_score','rewrite_header Subject');
+// to disable entire sections enter the secion name surrounded by braces. Sections are: general,tests,bayes,headers,report,addresses
+// eg. $rcmail_config['sauserprefs_dont_override'] = array('{tests}');
+$rcmail_config['sauserprefs_dont_override'] = array();
+
+// default settings
+// these are overridden by $GLOBAL and user settings from the database
+$rcmail_config['sauserprefs_default_prefs'] = array(
+ "required_score" => "5",
+ "rewrite_header Subject" => "*****SPAM*****",
+ "ok_languages" => "all",
+ "ok_locales" => "all",
+ "fold_headers" => "1",
+ "add_header all Level" => "_STARS(*)_",
+ "use_razor1" => "0",
+ "use_razor2" => "1",
+ "use_pyzor" => "1",
+ "use_dcc" => "1",
+ "use_bayes" => "1",
+ "skip_rbl_checks" => "0",
+ "report_safe" => "1",
+ "bayes_auto_learn" => "1",
+ "bayes_auto_learn_threshold_nonspam" => "0.1",
+ "bayes_auto_learn_threshold_spam" => "12.0",
+ "use_bayes_rules" => "1"
+ );
+
+// spam score increment - increment values in the the score threshold drop down by this, from 0 to 10
+$rcmail_config['sauserprefs_score_inc'] = 1;
+
+// allow the user to delete bayesian data
+// please also see sauserprefs_bayes_delete_query option
+$rcmail_config['sauserprefs_bayes_delete'] = false;
+
+// delete user bayesian data stored in database
+// the query can contain the following macros that will be expanded as follows:
+// %u is replaced with the username from the sauserprefs_userid setting above
+// use an array to run multiple queries
+// eg. $rcmail_config['sauserprefs_bayes_delete_query'] = array(
+// 'DELETE FROM bayes_seen WHERE id IN (SELECT id FROM bayes_vars WHERE username = %u);',
+// 'DELETE FROM bayes_token WHERE id IN (SELECT id FROM bayes_vars WHERE username = %u);',
+// 'DELETE FROM bayes_vars WHERE username = %u;',
+// );
+$rcmail_config['sauserprefs_bayes_delete_query'] = '';
+
+// define languages
+$rcmail_config['sauserprefs_languages'] = array(
+ "af" => "Afrikaans",
+ "sq" => "Albanian",
+ "am" => "Amharic",
+ "ar" => "Arabic",
+ "hy" => "Armenian",
+ "eu" => "Basque",
+ "bs" => "Bosnian",
+ "bg" => "Bulgarian",
+ "be" => "Byelorussian",
+ "ca" => "Catalan",
+ "zh" => "Chinese",
+ "hr" => "Croatian",
+ "cs" => "Czech",
+ "da" => "Danish",
+ "nl" => "Dutch",
+ "en" => "English",
+ "eo" => "Esperanto",
+ "et" => "Estonian",
+ "fi" => "Finnish",
+ "fr" => "French",
+ "fy" => "Frisian",
+ "ka" => "Georgian",
+ "de" => "German",
+ "el" => "Greek",
+ "he" => "Hebrew",
+ "hi" => "Hindi",
+ "hu" => "Hungarian",
+ "is" => "Icelandic",
+ "id" => "Indonesian",
+ "ga" => "Irish Gaelic",
+ "it" => "Italian",
+ "ja" => "Japanese",
+ "ko" => "Korean",
+ "la" => "Latin",
+ "lv" => "Latvian",
+ "lt" => "Lithuanian",
+ "ms" => "Malay",
+ "mr" => "Marathi",
+ "ne" => "Nepali",
+ "no" => "Norwegian",
+ "fa" => "Persian",
+ "pl" => "Polish",
+ "pt" => "Portuguese",
+ "qu" => "Quechua",
+ "rm" => "Rhaeto-Romance",
+ "ro" => "Romanian",
+ "ru" => "Russian",
+ "sa" => "Sanskrit",
+ "sco" => "Scots",
+ "gd" => "Scottish Gaelic",
+ "sr" => "Serbian",
+ "sk" => "Slovak",
+ "sl" => "Slovenian",
+ "es" => "Spanish",
+ "sw" => "Swahili",
+ "sv" => "Swedish",
+ "tl" => "Tagalog",
+ "ta" => "Tamil",
+ "th" => "Thai",
+ "tr" => "Turkish",
+ "uk" => "Ukrainian",
+ "vi" => "Vietnamese",
+ "cy" => "Welsh",
+ "yi" => "Yiddish"
+ );
+?> \ No newline at end of file
diff --git a/plugins/sauserprefs/include/rcube_sauserprefs_storage.php b/plugins/sauserprefs/include/rcube_sauserprefs_storage.php
new file mode 100644
index 000000000..0819d5cf4
--- /dev/null
+++ b/plugins/sauserprefs/include/rcube_sauserprefs_storage.php
@@ -0,0 +1,268 @@
+<?php
+
+/**
+ * SAUserPrefs storage class
+ *
+ * Class to handle the SQL work for SAUserPrefs
+ *
+ * @author Philip Weir
+ */
+class rcube_sauserprefs_storage
+{
+ private $db;
+ private $db_dsnw;
+ private $db_dsnr;
+ private $db_persistent;
+ private $sa_user;
+ private $table_name;
+ private $username_field;
+ private $preference_field;
+ private $value_field;
+ private $bayes_delete_query;
+
+ function __construct($db_dsnw, $db_dsnr, $db_persistent, $sa_user, $table_name, $username_field, $preference_field, $value_field, $bayes_delete_query)
+ {
+ $this->db_dsnw = $db_dsnw;
+ $this->db_dsnr = $db_dsnr;
+ $this->db_persistent = $db_persistent;
+ $this->sa_user = $sa_user;
+ $this->table_name = $table_name;
+ $this->username_field = $username_field;
+ $this->preference_field = $preference_field;
+ $this->value_field = $value_field;
+ $this->bayes_delete_query = $bayes_delete_query;
+ }
+
+ function load_prefs($user)
+ {
+ $this->_db_connect('r');
+ $prefs = array();
+
+ $sql_result = $this->db->query(
+ "SELECT ". $this->preference_field.
+ ", ". $this->value_field.
+ " FROM ". $this->table_name.
+ " WHERE ". $this->username_field ." = ?;",
+ $user);
+
+ while ($sql_result && ($sql_arr = $this->db->fetch_assoc($sql_result))) {
+ $pref_name = $sql_arr[$this->preference_field];
+ $pref_name = sauserprefs::map_pref_name($pref_name, true);
+ $pref_value = $sql_arr[$this->value_field];
+
+ if ($pref_name == 'whitelist_from' || $pref_name == 'blacklist_from' || $pref_name == 'whitelist_to')
+ $prefs['addresses'][] = array('field' => $pref_name, 'value' => $pref_value);
+ else
+ $prefs[$pref_name] = $pref_value;
+
+ // update deprecated prefs in db
+ if ($sql_arr[$this->preference_field] != sauserprefs::map_pref_name($pref_name)) {
+ $this->_db_connect('w');
+
+ $this->db->query(
+ "UPDATE ". $this->table_name.
+ " SET ". $this->preference_field ." = ?".
+ " WHERE ". $this->username_field ." = ?".
+ " AND ". $this->preference_field ." = ?;",
+ sauserprefs::map_pref_name($pref_name),
+ $user,
+ $sql_arr[$this->preference_field]);
+ }
+ }
+
+ return $prefs;
+ }
+
+ function save_prefs($new_prefs, $cur_prefs, $global_prefs)
+ {
+ $this->_db_connect('w');
+ $result = true;
+
+ // save prefs
+ foreach ($new_prefs as $preference => $value) {
+ if ($preference == 'addresses') {
+ foreach ($value as $address) {
+ if ($address['action'] == "DELETE") {
+ $result = false;
+
+ $this->db->query(
+ "DELETE FROM ". $this->table_name.
+ " WHERE ". $this->username_field ." = ?".
+ " AND ". $this->preference_field ." = ?".
+ " AND ". $this->value_field ." = ?;",
+ $this->sa_user,
+ sauserprefs::map_pref_name($address['field']),
+ $address['value']);
+
+ $result = $this->db->affected_rows();
+
+ if (!$result) {
+ rcube::write_log('errors', 'sauserprefs error: cannot delete "' . sauserprefs::map_pref_name($prefs[$idx]) . '" = "' . $vals[$idx] . '" for ' . $this->sa_user);
+ break;
+ }
+ }
+ elseif ($address['action'] == "INSERT") {
+ $result = false;
+
+ $this->db->query(
+ "INSERT INTO ". $this->table_name.
+ " (". $this->username_field.
+ ", ". $this->preference_field.
+ ", ". $this->value_field.
+ ") VALUES (?, ?, ?);",
+ $this->sa_user,
+ sauserprefs::map_pref_name($address['field']),
+ $address['value']);
+
+ $result = $this->db->affected_rows();
+
+ if (!$result) {
+ rcube::write_log('errors', 'sauserprefs error: cannot insert "' . sauserprefs::map_pref_name($prefs[$idx]) . '" = "' . $vals[$idx] . '" for ' . $this->sa_user);
+ break;
+ }
+ }
+ }
+ }
+ elseif (array_key_exists($preference, $cur_prefs) && ($value == "" || $value == $global_prefs[$preference])) {
+ $result = false;
+
+ $this->db->query(
+ "DELETE FROM ". $this->table_name.
+ " WHERE ". $this->username_field ." = ?".
+ " AND ". $this->preference_field ." = ?;",
+ $this->sa_user,
+ sauserprefs::map_pref_name($preference));
+
+ $result = $this->db->affected_rows();
+
+ if (!$result) {
+ rcube::write_log('errors', 'sauserprefs error: cannot delete "' . sauserprefs::map_pref_name($preference) . '" for "' . $this->sa_user);
+ break;
+ }
+ }
+ elseif (array_key_exists($preference, $cur_prefs) && $value != $cur_prefs[$preference]) {
+ $result = false;
+
+ $this->db->query(
+ "UPDATE ". $this->table_name.
+ " SET ". $this->value_field ." = ?".
+ " WHERE ". $this->username_field ." = ?".
+ " AND ". $this->preference_field ." = ?;",
+ $value,
+ $this->sa_user,
+ sauserprefs::map_pref_name($preference));
+
+ $result = $this->db->affected_rows();
+
+ if (!$result) {
+ rcube::write_log('errors', 'sauserprefs error: cannot update "' . sauserprefs::map_pref_name($preference) . '" = "' . $value . '" for ' . $this->sa_user);
+ break;
+ }
+ }
+ elseif (!array_key_exists($preference, $cur_prefs) && $value != $global_prefs[$preference]) {
+ $result = false;
+
+ $this->db->query(
+ "INSERT INTO ". $this->table_name.
+ " (". $this->username_field.
+ ", ". $this->preference_field.
+ ", ". $this->value_field.
+ ") VALUES (?, ?, ?);",
+ $this->sa_user,
+ sauserprefs::map_pref_name($preference),
+ $value);
+
+ $result = $this->db->affected_rows();
+
+ if (!$result) {
+ rcube::write_log('errors', 'sauserprefs error: cannot insert "' . sauserprefs::map_pref_name($preference) . '" = "' . $value . '" for ' . $this->sa_user);
+ break;
+ }
+ }
+ }
+
+ return $result;
+ }
+
+ function whitelist_add($emails)
+ {
+ $this->_db_connect('w');
+
+ foreach ($emails as $email) {
+ // check address is not already whitelisted
+ $sql_result = $this->db->query(
+ "SELECT ". $this->value_field.
+ " FROM ". $this->table_name.
+ " WHERE ". $this->username_field ." = ?".
+ " AND ". $this->preference_field ." = ?".
+ " AND ". $this->value_field ." = ?;",
+ $this->sa_user,
+ sauserprefs::map_pref_name('whitelist_from'),
+ $email);
+
+ if (!$this->db->fetch_array($sql_result))
+ $this->db->query(
+ "INSERT INTO ". $this->table_name.
+ " (". $this->username_field.
+ ", ". $this->preference_field.
+ ", ". $this->value_field.
+ ") VALUES (?, ?, ?);",
+ $this->sa_user,
+ sauserprefs::map_pref_name('whitelist_from'),
+ $email);
+ }
+ }
+
+ function whitelist_delete($emails)
+ {
+ $this->_db_connect('w');
+
+ foreach ($emails as $email)
+ $this->db->query(
+ "DELETE FROM ". $this->table_name.
+ " WHERE ". $this->username_field ." = ?".
+ " AND ". $this->preference_field ." = ?".
+ " AND ". $this->value_field ." = ?;",
+ $this->sa_user,
+ sauserprefs::map_pref_name('whitelist_from'),
+ $email);
+
+ }
+
+ function purge_bayes()
+ {
+ $this->_db_connect('w');
+ $queries = !is_array($this->bayes_delete_query) ? array($this->bayes_delete_query) : $this->bayes_delete_query;
+
+ foreach ($queries as $sql) {
+ $sql = str_replace('%u', $this->db->quote($this->sa_user, 'text'), $sql);
+ $this->db->query($sql);
+
+ if ($this->db->is_error())
+ break;
+ }
+
+ if (!$this->db->is_error())
+ return true;
+ else
+ return false;
+ }
+
+ private function _db_connect($mode)
+ {
+ if (!$this->db)
+ $this->db = rcube_db::factory($this->db_dsnw, $this->db_dsnr, $this->db_persistent);
+
+ $this->db->db_connect($mode);
+
+ // check DB connections and exit on failure
+ if ($err_str = $this->db->is_error()) {
+ raise_error(array(
+ 'code' => 603,
+ 'type' => 'db',
+ 'message' => $err_str), false, true);
+ }
+ }
+}
+
+?> \ No newline at end of file
diff --git a/plugins/sauserprefs/localization/cs_CZ.inc b/plugins/sauserprefs/localization/cs_CZ.inc
new file mode 100644
index 000000000..53be0e691
--- /dev/null
+++ b/plugins/sauserprefs/localization/cs_CZ.inc
@@ -0,0 +1,86 @@
+<?php
+/* Author: Tomáš Bezděk */
+
+$labels = array();
+$labels['sauserprefs'] = 'Spam';
+$labels['managespam'] = 'Spravovat nastavení detekce spamu';
+$labels['sauserprefssettings'] = 'Nastavení Spam-u';
+$labels['spamgeneralsettings'] = 'Všeobecné nastavení';
+$labels['spamthres'] = 'Hranice skóre';
+$labels['spamsubject'] = 'Značka v předmětu';
+$labels['spamsubjectblank'] = '(nechajte prázdne pre žádnou)';
+$labels['spamlang'] = 'Jazyky zprávy';
+$labels['enabled'] = 'Povoleno';
+$labels['disabled'] = 'Zakázáno';
+$labels['headers'] = 'Hlavičky zpráv';
+$labels['foldheaders'] = 'Povolit víceřádkové v hlavičky';
+$labels['spamlevelstars'] = 'Pouzít \'Spam Level\' hlavičku (úroveň spamu)';
+$labels['spamlevelchar'] = 'Znak úrovně spamu';
+$labels['spamtests'] = 'Internetové spam testy';
+$labels['userazor1'] = 'Použít Razor v1';
+$labels['userazor2'] = 'Použít Razor v2';
+$labels['usepyzor'] = 'Použít Pyzor';
+$labels['usebayes'] = 'Použít Bayesiánský klasifikátor';
+$labels['usedcc'] = 'Použít DCC';
+$labels['skiprblchecks'] = 'Použít RBL';
+$labels['spamreportsettings'] = 'Nastavení reportu';
+$labels['spamreport0'] = 'Zahrnout oznámení do hlavičky originální zprávy';
+$labels['spamreport1'] = 'Zahrnout originál jako MIME přílohu k oznámení';
+$labels['spamreport2'] = 'Zahrnout originál jako textovou přílohu k oznámení';
+$labels['spamaddressrules'] = 'Pravidla adres';
+$labels['whitelist_from'] = 'Příjmout zprávu od';
+$labels['blacklist_from'] = 'Odmítnout zprávu od';
+$labels['whitelist_to'] = 'Příjmat zprávy zaslané pro';
+$labels['addrule'] = 'Přidat';
+$labels['rule'] = 'Pravidlo';
+$labels['importfromaddressbook'] = 'Importovat adresy z adresáře';
+$labels['deleteall'] = 'Odstranit vše';
+$labels['autoscore'] = 'Auto';
+$labels['defaultscore'] = 'Výchozí hodnocení';
+$labels['otherscore'] = 'Ostatní (%s)';
+$labels['usedefault'] = 'Obnovit výchozí nastavení';
+$labels['langoptions'] = 'Jazyková nastavení';
+$labels['bayes'] = 'Nastaveni Bayes filtru';
+$labels['purgingbayes'] = 'Odstraňuji Bayesiánské data';
+$labels['purgebayes'] = 'Odstranit vlastní Bayesiánské data';
+$labels['bayesautolearn'] = 'Použít automatické učení Bayesiánského filtru';
+$labels['bayesautooptions'] = 'Nastavení automatického učení';
+$labels['bayesnonspam'] = 'Hranice pro be-spam';
+$labels['bayesspam'] = 'Hranice pro spam';
+$labels['bayesrules'] = 'Použít Bayesiánská pravidla';
+$labels['help'] = 'Nápověda';
+
+$messages = array();
+$messages['sauserprefchanged'] = 'Nastavení spamu bylo úspěšně změněno';
+$messages['sauserpreffailed'] = 'Chyba: Nastavení spamu se nepodařilo změnit';
+$messages['spamthresexp'] = 'Všechny maily se skóre vyšším, jako určená hranice budou označeny jako spam. Zvýšením této hranice sa zvýší počet nerozpoznaných spamů, na druhé straně sa sníží počet mailův chybně označených jako spam.';
+$messages['spamlangexp'] = 'Vyberte všechny jazyky ve kterých předpokladáte příjem e-mailů. Všetky přijaté zprávy napsané v jiných jazycích budou brány jako pravděpodobný spam.';
+$messages['headersexp'] = 'SpamAssassin přidává do kontrolovaných e-mailů hlavičky s informacemi o výsledcích kontroly. Použijte nasledující volby na jejich přizpůsobení.';
+$messages['spamtestssexp'] = 'Některé testy pri detekci spamu používají externí služby na internetu. Vyberte ty, které chcete využívat:';
+$messages['spamreport'] = 'Pokud je e-mail identifikovaný jako spam, vytvoří se report o všech testech a jejich dosáhnutém skóre...';
+$messages['autowhitelist'] = 'E-mailové adresy ve vašem Addresáři jsou automaticky přidány do listu "Příjmout zprávu od".';
+$messages['whitelistexp'] = 'V e-mailových adresách může byť použitý zástupný znak hvězdička (*). Např.: *@domena.cz or *@*.domena.cz.';
+$messages['spamaddressexists'] = 'Previdlo pro tuto adresu již existuje';
+$messages['spamenteraddress'] = 'Prosím zadajte adresu, kterou chcete přidat';
+$messages['spamaddresserror'] = 'Chyba: Adresa se jeví neplatná';
+$messages['spamaddressdelete'] = 'Jste si jisti, že chcete vymazat toto pravidlo?';
+$messages['spamaddressdeleteall'] = 'Jste si jisti, že chcete vymazae všechny pravidla?';
+$messages['noaddressrules'] = 'Nebyly nalezeny žádné pravidla adries.';
+$messages['importingaddresses'] = 'Importuji adresy ....';
+$messages['usedefaultconfirm'] = 'Jste si jisti, že chcete doopravdy obnovit předvolené nastavení? To vymaže všechny Vaše nastavení, včetně pravidel adres.';
+$messages['purgebayesexp'] = 'Vymaže osobní Bayesiánskou databázi vytvořenou z Vašich e-mailoů';
+$messages['bayesnonspamexp'] = 'E-maily s nižším skóre jak uvedená hranice budou použité na zlepšení detekce (naučení) nespamových zpráv.';
+$messages['bayesspamexp'] = 'E-maily s vyšším skóre jak uvedená hranice budou použité na zlepšení detekce (naučení) nespamových zpráv.';
+$messages['bayesautohelp'] = 'Pokud je automatické učení zapnuto, systém použije zprávy které s velkou jistotou prohlásí za spam/nespam na zlepšení detekčných filtrů.';
+$messages['bayeshelp'] = 'Bayesianský klasifikátor se snaží identifikovat spam podle slov, alebo shluku znaků, které sa obvykle vyskytují v spamových, alebo nespamových e-mailech.';
+$messages['rblhelp'] = 'IP adresy serverů v hlavičkách, nebo v odkazech v e-mailu budou vyhledané na něktorých blacklistech. Blacklisty jsou seznamy známých adres spammerů, které se aktualizují v reálném čase.';
+$messages['dcchelp'] = 'DCC, aneb distribuované výměnné centrum kontrolních součtů, je systém serverů sbírajících a vypočítavajících kontrolní součty (či podpisy) milionů e-mailů denně. Podle podobnosti kontrolního součtu příchozí zprávy vůči seznamu evidovaných se určuje pravděpodobnost spamu.';
+$messages['pyzhelp'] = 'Pyzor je síťový systém na detekci a blokování spamu pomocí přehledu zpráv. Přehledy sa vypočítavají několika způsoby tak, aby dokázaly tolerovat malou změnu v obsahu zprávy.';
+$messages['raz2help'] = 'Vipul\'s Razor je distribuovaná spolupracující síť na detekci a blokování spamu, pracující na základě užívateli zaslaných spamových vzorků. Tyto vzorky jsou zohledňovány podle reputace užívatele, který je poskytl. Detekcie se tvoří pomocí charakteristik, které efektívně zachytávají i měníací se obsah spamu.';
+$messages['raz1help'] = 'Vipul\'s Razor je distribuovaná spolupracující síť na detekci a blokování spamu, pracující na základě uživateľ zaslaných spamových vzorků. Tyto vzorky jsou zohledňovány podle reputace uživatele, který je poskytl. Detekcie sa tvoří pomocí charakteristík, které efektivně zachytávají i měnící se obsah spamu. Verzie 1 byla nahrzena verzí 2 a není už nadále podporována.';
+$messages['levelhelp'] = 'Hlavička \'Spam Level\' zobrazuje opakovaním znaku (např. hvezdičky) skóre, které kontrolovaný e-mail získal. To může být užitečné při dalším zpracování e-mailu.';
+$messages['foldhelp'] = 'Mohou být hlavičky přidané do e-mailu SpamAssassinem rozdělené na víc řádků, namísto toho, aby byly na jednom velmi dlouhém řádku? Pokud je řádek rozdělený, jeho pokračování je označeno odsazením.';
+$messages['bayesruleshlp'] = 'Předtím, než může byt Bayesovský klasifikátor efektívně použit, musí se natrénovat správně rozeznávat spam od nespamu. Vypnutím Bayesiánskych pravidel umožníte systému učit se z přicházejícich e-mailů, ale nebude se používat na detekci spamu..';
+$messages['purgebayesconfirm'] = 'Jste si jisti, že chcete doopravdy vymazat celou Vaši Bayesiánskou databázi?';
+
+?> \ No newline at end of file
diff --git a/plugins/sauserprefs/localization/de_CH.inc b/plugins/sauserprefs/localization/de_CH.inc
new file mode 100644
index 000000000..00cd54ffb
--- /dev/null
+++ b/plugins/sauserprefs/localization/de_CH.inc
@@ -0,0 +1,86 @@
+<?php
+/* Author: Simon Tauber */
+
+$labels = array();
+$labels['sauserprefs'] = 'Spam';
+$labels['managespam'] = 'Verwalten der Spamfilter-Einstellungen';
+$labels['sauserprefssettings'] = 'Spam Einstellungen';
+$labels['spamgeneralsettings'] = 'Generelle Einstellugen';
+$labels['spamthres'] = 'Schwellenwert';
+$labels['spamsubject'] = 'Spam Betreff';
+$labels['spamsubjectblank'] = '(Leer lassen um zu deaktivieren)';
+$labels['spamlang'] = 'Mitteilungssprache';
+$labels['enabled'] = 'Aktiviert';
+$labels['disabled'] = 'Deaktiviert';
+$labels['headers'] = 'Mitteilungsheaders';
+$labels['foldheaders'] = 'Mehrzeilige Header erlauben';
+$labels['spamlevelstars'] = '\'Spam Level\' Header verwenden';
+$labels['spamlevelchar'] = 'Spam Level Symbol';
+$labels['spamtests'] = 'Internet basierter Spam Test';
+$labels['userazor1'] = 'Razor v1 verwenden';
+$labels['userazor2'] = 'Razor v2 verwenden';
+$labels['usepyzor'] = 'Pyzor verwenden';
+$labels['usebayes'] = 'Naive Bayesische Stil Klassifizierung';
+$labels['usedcc'] = 'DCC verwenden';
+$labels['skiprblchecks'] = 'Echtzeit Blackhole Liste verwenden';
+$labels['spamreportsettings'] = 'Berichtseinstellungen';
+$labels['spamreport0'] = 'Bericht in den Header der Orginalnachricht einfügen';
+$labels['spamreport1'] = 'Orginalmeldung dem Bericht als MIME Anhang hinzufügen';
+$labels['spamreport2'] = 'Orginalmeldung dem Bericht als Text Anhang hinzufügen';
+$labels['spamaddressrules'] = 'Addressregeln';
+$labels['whitelist_from'] = 'Mails akzeptieren von';
+$labels['blacklist_from'] = 'Mails ablehnen von';
+$labels['whitelist_to'] = 'Akzeptiere Mails gesendet an';
+$labels['addrule'] = 'Regel hinzufügen';
+$labels['rule'] = 'Regel';
+$labels['importfromaddressbook'] = 'Adressen aus dem Adressbuch importieren';
+$labels['deleteall'] = 'Alle löschen';
+$labels['autoscore'] = 'Automatisch';
+$labels['defaultscore'] = 'Standardscore';
+$labels['otherscore'] = 'Andere (%s)';
+$labels['usedefault'] = 'Standardscore wiederherstellen';
+$labels['langoptions'] = 'Sprachoptionen';
+$labels['bayes'] = 'Bayes Einstellungen';
+$labels['purgingbayes'] = 'Lösche bayesische Daten...';
+$labels['purgebayes'] = 'Lösche persönliche bayesische Daten';
+$labels['bayesautolearn'] = 'Bayes auto-lernen verwenden';
+$labels['bayesautooptions'] = 'Auto-lernen Optionen';
+$labels['bayesnonspam'] = '"Kein Spam" Schwellenwert';
+$labels['bayesspam'] = '"Spam" Schwellenwert';
+$labels['bayesrules'] = 'Bayesische Regeln verwenden';
+$labels['help'] = 'Hilfe';
+
+$messages = array();
+$messages['sauserprefchanged'] = 'Spam Einstellungen erfolgreich geändert';
+$messages['sauserpreffailed'] = 'Fehler: Spam-Einstellungen konnten nicht geändert werden';
+$messages['spamthresexp'] = 'Alles über dem Schwellenwert wird als Spam markiert. Erhöhen des Schwellenwerts minimiert die verpassten Meldungen, aber erhöht die Möglichkeit der falschen Einstufung.';
+$messages['spamlangexp'] = 'Wählen Sie alle Sprachen in denen Mails empfangen werden sollen. Alle nicht ausgewählten Sprachen werden als möglicher Spam markiert.';
+$messages['headersexp'] = 'SpamAssassin fügt den verarbeiteten Mitteilungen Header mit Informationen über das Ergebnis zu. Verwende folgende Optionen um diese Header zu konfigurieren.';
+$messages['spamtestssexp'] = 'Einige Checks verwenden Internet-baiserte Dienste um Spam besser identifizieren zu können. Wählen Sie, welche verwendet werden sollen:';
+$messages['spamreport'] = 'Wird eine Mail als Spam identifiziert werden Berichte aller zugewiesenen Tests und Scores hinzugefügt...';
+$messages['autowhitelist'] = 'Email Adressen aus dem Adressbuch werden automatisch zu der "Whitelist" hinzugefügt.';
+$messages['whitelistexp'] = 'Ein (*) kann als Wildcard verwendet werden. Zum Beispiel: *@example.com oder *@*.example.com.';
+$messages['spamaddressexists'] = 'Es existiert bereits eine Regel für diese Adresse';
+$messages['spamenteraddress'] = 'Bitte eine hinzuzufügende Adresse eingeben';
+$messages['spamaddresserror'] = 'Fehler: Die Adresse scheint ungültig zu sein';
+$messages['spamaddressdelete'] = 'Sind Sie sicher, dass Sie diese Regel löschen möchten?';
+$messages['spamaddressdeleteall'] = 'Sind Sie sicher, dass Sie alle Adressregeln löschen möchten?';
+$messages['noaddressrules'] = 'Keine Adressregel gefunden.';
+$messages['importingaddresses'] = 'Adressen werden importiert...';
+$messages['usedefaultconfirm'] = 'Sind Sie sicher, dass Sie die Standardeinstellungen wiederherstellen möchten? Alle Einstellungen inklusive Adressregeln werden gelöscht.';
+$messages['purgebayesexp'] = 'Gesammelte persönliche Bayesische Daten Ihrer Mails löschen.';
+$messages['bayesnonspamexp'] = 'Mittelungen, deren Score unter diesem Schwellenwert liegen, werden verwendet um die "Ham" Erkennung zu verbessern.';
+$messages['bayesspamexp'] = 'Mittelungen, deren Score über diesem Schwellenwert liegen, werden verwendet um die Spam-Erkennung zu verbessern.';
+$messages['bayesautohelp'] = 'Wenn Bayes auto-lernen aktiviert ist, verwendet das System Mitteilungen die höchstwarscheinlich Spam/Ham sind um die Erkennungsfilter zu verbessern..';
+$messages['bayeshelp'] = 'Die bayesische Klassifizierung versucht Spam anhand bekannter Wortfolgen zu identifizieren, die in Spam/Ham Mitteilungen gefunden wurde.';
+$messages['rblhelp'] = 'Die Serveradressen der hypertext links einer Mitteilung werden mit Blacklists oder Listen bekannter Spamquellen verglichen.';
+$messages['dcchelp'] = 'DCC (Distributed Checksum Clearinghouse) ist ein System aus Servern die Cheksummen von millionen von Mails sammeln und zählen. Dies Werte können verwendet werden um Spam zu erkennen.';
+$messages['pyzhelp'] = 'Pyzor ist ein kollaboratives, vernetztes System, um Spam anhand eines Auszugs einer Mitteilung zu erkennen und zu blocken.';
+$messages['raz2help'] = 'Vipul\'s Razor ist ein Prüfsummen-basiertes, verteiltes, gemeinschaftliches E-Mail-Spam-Erkennungs- und -Filter-Netzwerk. Razor basiert auf einem verteilten Spam-Katalog, der durch Benutzerrückmeldungen ständig aktualisiert wird. E-Mail-Clients und -Server können so bekannten Spam filtern. Die Erkennung erfolgt über statistische und randomisierte Signaturen.';
+$messages['raz1help'] = 'Vipul\'s Razor ist ein Prüfsummen-basiertes, verteiltes, gemeinschaftliches E-Mail-Spam-Erkennungs- und -Filter-Netzwerk. Razor basiert auf einem verteilten Spam-Katalog, der durch Benutzerrückmeldungen ständig aktualisiert wird. E-Mail-Clients und -Server können so bekannten Spam filtern. Die Erkennung erfolgt über statistische und randomisierte Signaturen.';
+$messages['levelhelp'] = 'Der \'Spam Level\' Header kann Mitteilungen anhand von Zeichen, die sich eine bestimmte Anzahl mal wiederhohlen, hinzugefügt werden.';
+$messages['foldhelp'] = 'Standardmäßig werden Header, die von SpamAssasin hinzugefügt werden, "whitespace foled". In anderen Worten: Sie werden auf mehrere Zeilen verteilt anstelle von einer sehr langen Zeile. Jeder andere Zeile wird ein Tabulator vorgesetzt um es als eine weiterführende Zeile der Vorhergehenden zu markieren.';
+$messages['bayesruleshlp'] = 'Es empfiehlt sich, die "naive bayesische Stil Klassifizierung" zu verwenden. Damit können auch die Regeln deaktiviert werden auch wenn das automatisch und manuelle Lernen aktiviert ist.';
+$messages['purgebayesconfirm'] = 'Sind Sie sicher, dass Sie alle bayesischen Daten löschen möchten?';
+
+?> \ No newline at end of file
diff --git a/plugins/sauserprefs/localization/de_DE.inc b/plugins/sauserprefs/localization/de_DE.inc
new file mode 100644
index 000000000..00cd54ffb
--- /dev/null
+++ b/plugins/sauserprefs/localization/de_DE.inc
@@ -0,0 +1,86 @@
+<?php
+/* Author: Simon Tauber */
+
+$labels = array();
+$labels['sauserprefs'] = 'Spam';
+$labels['managespam'] = 'Verwalten der Spamfilter-Einstellungen';
+$labels['sauserprefssettings'] = 'Spam Einstellungen';
+$labels['spamgeneralsettings'] = 'Generelle Einstellugen';
+$labels['spamthres'] = 'Schwellenwert';
+$labels['spamsubject'] = 'Spam Betreff';
+$labels['spamsubjectblank'] = '(Leer lassen um zu deaktivieren)';
+$labels['spamlang'] = 'Mitteilungssprache';
+$labels['enabled'] = 'Aktiviert';
+$labels['disabled'] = 'Deaktiviert';
+$labels['headers'] = 'Mitteilungsheaders';
+$labels['foldheaders'] = 'Mehrzeilige Header erlauben';
+$labels['spamlevelstars'] = '\'Spam Level\' Header verwenden';
+$labels['spamlevelchar'] = 'Spam Level Symbol';
+$labels['spamtests'] = 'Internet basierter Spam Test';
+$labels['userazor1'] = 'Razor v1 verwenden';
+$labels['userazor2'] = 'Razor v2 verwenden';
+$labels['usepyzor'] = 'Pyzor verwenden';
+$labels['usebayes'] = 'Naive Bayesische Stil Klassifizierung';
+$labels['usedcc'] = 'DCC verwenden';
+$labels['skiprblchecks'] = 'Echtzeit Blackhole Liste verwenden';
+$labels['spamreportsettings'] = 'Berichtseinstellungen';
+$labels['spamreport0'] = 'Bericht in den Header der Orginalnachricht einfügen';
+$labels['spamreport1'] = 'Orginalmeldung dem Bericht als MIME Anhang hinzufügen';
+$labels['spamreport2'] = 'Orginalmeldung dem Bericht als Text Anhang hinzufügen';
+$labels['spamaddressrules'] = 'Addressregeln';
+$labels['whitelist_from'] = 'Mails akzeptieren von';
+$labels['blacklist_from'] = 'Mails ablehnen von';
+$labels['whitelist_to'] = 'Akzeptiere Mails gesendet an';
+$labels['addrule'] = 'Regel hinzufügen';
+$labels['rule'] = 'Regel';
+$labels['importfromaddressbook'] = 'Adressen aus dem Adressbuch importieren';
+$labels['deleteall'] = 'Alle löschen';
+$labels['autoscore'] = 'Automatisch';
+$labels['defaultscore'] = 'Standardscore';
+$labels['otherscore'] = 'Andere (%s)';
+$labels['usedefault'] = 'Standardscore wiederherstellen';
+$labels['langoptions'] = 'Sprachoptionen';
+$labels['bayes'] = 'Bayes Einstellungen';
+$labels['purgingbayes'] = 'Lösche bayesische Daten...';
+$labels['purgebayes'] = 'Lösche persönliche bayesische Daten';
+$labels['bayesautolearn'] = 'Bayes auto-lernen verwenden';
+$labels['bayesautooptions'] = 'Auto-lernen Optionen';
+$labels['bayesnonspam'] = '"Kein Spam" Schwellenwert';
+$labels['bayesspam'] = '"Spam" Schwellenwert';
+$labels['bayesrules'] = 'Bayesische Regeln verwenden';
+$labels['help'] = 'Hilfe';
+
+$messages = array();
+$messages['sauserprefchanged'] = 'Spam Einstellungen erfolgreich geändert';
+$messages['sauserpreffailed'] = 'Fehler: Spam-Einstellungen konnten nicht geändert werden';
+$messages['spamthresexp'] = 'Alles über dem Schwellenwert wird als Spam markiert. Erhöhen des Schwellenwerts minimiert die verpassten Meldungen, aber erhöht die Möglichkeit der falschen Einstufung.';
+$messages['spamlangexp'] = 'Wählen Sie alle Sprachen in denen Mails empfangen werden sollen. Alle nicht ausgewählten Sprachen werden als möglicher Spam markiert.';
+$messages['headersexp'] = 'SpamAssassin fügt den verarbeiteten Mitteilungen Header mit Informationen über das Ergebnis zu. Verwende folgende Optionen um diese Header zu konfigurieren.';
+$messages['spamtestssexp'] = 'Einige Checks verwenden Internet-baiserte Dienste um Spam besser identifizieren zu können. Wählen Sie, welche verwendet werden sollen:';
+$messages['spamreport'] = 'Wird eine Mail als Spam identifiziert werden Berichte aller zugewiesenen Tests und Scores hinzugefügt...';
+$messages['autowhitelist'] = 'Email Adressen aus dem Adressbuch werden automatisch zu der "Whitelist" hinzugefügt.';
+$messages['whitelistexp'] = 'Ein (*) kann als Wildcard verwendet werden. Zum Beispiel: *@example.com oder *@*.example.com.';
+$messages['spamaddressexists'] = 'Es existiert bereits eine Regel für diese Adresse';
+$messages['spamenteraddress'] = 'Bitte eine hinzuzufügende Adresse eingeben';
+$messages['spamaddresserror'] = 'Fehler: Die Adresse scheint ungültig zu sein';
+$messages['spamaddressdelete'] = 'Sind Sie sicher, dass Sie diese Regel löschen möchten?';
+$messages['spamaddressdeleteall'] = 'Sind Sie sicher, dass Sie alle Adressregeln löschen möchten?';
+$messages['noaddressrules'] = 'Keine Adressregel gefunden.';
+$messages['importingaddresses'] = 'Adressen werden importiert...';
+$messages['usedefaultconfirm'] = 'Sind Sie sicher, dass Sie die Standardeinstellungen wiederherstellen möchten? Alle Einstellungen inklusive Adressregeln werden gelöscht.';
+$messages['purgebayesexp'] = 'Gesammelte persönliche Bayesische Daten Ihrer Mails löschen.';
+$messages['bayesnonspamexp'] = 'Mittelungen, deren Score unter diesem Schwellenwert liegen, werden verwendet um die "Ham" Erkennung zu verbessern.';
+$messages['bayesspamexp'] = 'Mittelungen, deren Score über diesem Schwellenwert liegen, werden verwendet um die Spam-Erkennung zu verbessern.';
+$messages['bayesautohelp'] = 'Wenn Bayes auto-lernen aktiviert ist, verwendet das System Mitteilungen die höchstwarscheinlich Spam/Ham sind um die Erkennungsfilter zu verbessern..';
+$messages['bayeshelp'] = 'Die bayesische Klassifizierung versucht Spam anhand bekannter Wortfolgen zu identifizieren, die in Spam/Ham Mitteilungen gefunden wurde.';
+$messages['rblhelp'] = 'Die Serveradressen der hypertext links einer Mitteilung werden mit Blacklists oder Listen bekannter Spamquellen verglichen.';
+$messages['dcchelp'] = 'DCC (Distributed Checksum Clearinghouse) ist ein System aus Servern die Cheksummen von millionen von Mails sammeln und zählen. Dies Werte können verwendet werden um Spam zu erkennen.';
+$messages['pyzhelp'] = 'Pyzor ist ein kollaboratives, vernetztes System, um Spam anhand eines Auszugs einer Mitteilung zu erkennen und zu blocken.';
+$messages['raz2help'] = 'Vipul\'s Razor ist ein Prüfsummen-basiertes, verteiltes, gemeinschaftliches E-Mail-Spam-Erkennungs- und -Filter-Netzwerk. Razor basiert auf einem verteilten Spam-Katalog, der durch Benutzerrückmeldungen ständig aktualisiert wird. E-Mail-Clients und -Server können so bekannten Spam filtern. Die Erkennung erfolgt über statistische und randomisierte Signaturen.';
+$messages['raz1help'] = 'Vipul\'s Razor ist ein Prüfsummen-basiertes, verteiltes, gemeinschaftliches E-Mail-Spam-Erkennungs- und -Filter-Netzwerk. Razor basiert auf einem verteilten Spam-Katalog, der durch Benutzerrückmeldungen ständig aktualisiert wird. E-Mail-Clients und -Server können so bekannten Spam filtern. Die Erkennung erfolgt über statistische und randomisierte Signaturen.';
+$messages['levelhelp'] = 'Der \'Spam Level\' Header kann Mitteilungen anhand von Zeichen, die sich eine bestimmte Anzahl mal wiederhohlen, hinzugefügt werden.';
+$messages['foldhelp'] = 'Standardmäßig werden Header, die von SpamAssasin hinzugefügt werden, "whitespace foled". In anderen Worten: Sie werden auf mehrere Zeilen verteilt anstelle von einer sehr langen Zeile. Jeder andere Zeile wird ein Tabulator vorgesetzt um es als eine weiterführende Zeile der Vorhergehenden zu markieren.';
+$messages['bayesruleshlp'] = 'Es empfiehlt sich, die "naive bayesische Stil Klassifizierung" zu verwenden. Damit können auch die Regeln deaktiviert werden auch wenn das automatisch und manuelle Lernen aktiviert ist.';
+$messages['purgebayesconfirm'] = 'Sind Sie sicher, dass Sie alle bayesischen Daten löschen möchten?';
+
+?> \ No newline at end of file
diff --git a/plugins/sauserprefs/localization/en_GB.inc b/plugins/sauserprefs/localization/en_GB.inc
new file mode 100644
index 000000000..6c500af9f
--- /dev/null
+++ b/plugins/sauserprefs/localization/en_GB.inc
@@ -0,0 +1,86 @@
+<?php
+/* Author: Philip Weir */
+
+$labels = array();
+$labels['sauserprefs'] = 'Spam';
+$labels['managespam'] = 'Manage spam detection settings';
+$labels['sauserprefssettings'] = 'Spam settings';
+$labels['spamgeneralsettings'] = 'General Settings';
+$labels['spamthres'] = 'Score threshold';
+$labels['spamsubject'] = 'Subject tag';
+$labels['spamsubjectblank'] = '(leave blank for none)';
+$labels['spamlang'] = 'Message languages';
+$labels['enabled'] = 'Enabled';
+$labels['disabled'] = 'Disabled';
+$labels['headers'] = 'Message Headers';
+$labels['foldheaders'] = 'Allow multiple lines in headers';
+$labels['spamlevelstars'] = 'Use \'Spam Level\' header';
+$labels['spamlevelchar'] = 'Spam level character';
+$labels['spamtests'] = 'Internet Based Spam Tests';
+$labels['userazor1'] = 'Use Razor v1';
+$labels['userazor2'] = 'Use Razor v2';
+$labels['usepyzor'] = 'Use Pyzor';
+$labels['usebayes'] = 'Use Bayesian style classifier';
+$labels['usedcc'] = 'Use DCC';
+$labels['skiprblchecks'] = 'Use Realtime Blackhole List';
+$labels['spamreportsettings'] = 'Report Settings';
+$labels['spamreport0'] = 'Include report in headers of original message';
+$labels['spamreport1'] = 'Include original as MIME attachment to report';
+$labels['spamreport2'] = 'Include original as text-only attachment to report';
+$labels['spamaddressrules'] = 'Address Rules';
+$labels['whitelist_from'] = 'Accept Mail From';
+$labels['blacklist_from'] = 'Reject Mail From';
+$labels['whitelist_to'] = 'Accept Mail Sent To';
+$labels['addrule'] = 'Add Rule';
+$labels['rule'] = 'Rule';
+$labels['importfromaddressbook'] = 'Import addresses from Address Book';
+$labels['deleteall'] = 'Delete All';
+$labels['autoscore'] = 'Auto';
+$labels['defaultscore'] = 'Default Score';
+$labels['otherscore'] = 'Other (%s)';
+$labels['usedefault'] = 'Restore Default Settings';
+$labels['langoptions'] = 'Language Options';
+$labels['bayes'] = 'Bayes Settings';
+$labels['purgingbayes'] = 'Deleting Bayesian data...';
+$labels['purgebayes'] = 'Delete personal Bayesian data';
+$labels['bayesautolearn'] = 'Use Bayes auto learn';
+$labels['bayesautooptions'] = 'Auto learn options';
+$labels['bayesnonspam'] = 'Non spam threshold';
+$labels['bayesspam'] = 'Spam threshold';
+$labels['bayesrules'] = 'Use Baysian rules';
+$labels['help'] = 'Help';
+
+$messages = array();
+$messages['sauserprefchanged'] = 'Successfully changed spam settings';
+$messages['sauserpreffailed'] = 'Error: Cannot change spam settings';
+$messages['spamthresexp'] = 'Anything above the threshold is marked as spam. Increasing this threshold will increase the amount of spam missed, but will reduce the risk of false positives.';
+$messages['spamlangexp'] = 'Select all the languages you expect to receive e-mail in. Any messages received that are written in non selected languages will be treated as possible spam.';
+$messages['headersexp'] = 'SpamAssassin adds headers to processed messages providing information about the results. Use the options below to configure these headers.';
+$messages['spamtestssexp'] = 'Some checks use internet based services to help identify spam. Select the ones you wish to use:';
+$messages['spamreport'] = 'When a message is identified as spam a report of all tests and scores assigned is created...';
+$messages['autowhitelist'] = 'Email addresses in your Address Book are automatically added to the \'Accept Mail From\' list.';
+$messages['whitelistexp'] = 'An asterisk (*) can be used as a wild card for greater flexibility. For example: *@example.com or *@*.example.com.';
+$messages['spamaddressexists'] = 'A rule already exists for this address';
+$messages['spamenteraddress'] = 'Please enter an address to add';
+$messages['spamaddresserror'] = 'Error: Address appears invalid';
+$messages['spamaddressdelete'] = 'Are you sure you want to delete this rule?';
+$messages['spamaddressdeleteall'] = 'Are you sure you want to delete all address rules?';
+$messages['noaddressrules'] = 'No address rules found.';
+$messages['importingaddresses'] = 'Importing addresses...';
+$messages['usedefaultconfirm'] = 'Are you sure you want to restore the default settings? This will delete all your settings, including your address rules.';
+$messages['purgebayesexp'] = 'Delete personal Bayesian data collected from your email';
+$messages['bayesnonspamexp'] = 'Messages which score below this threshold will be used to improve the systems detection of non spam messages.';
+$messages['bayesspamexp'] = 'Messages which score above this threshold will be used to improve the systems detection of spam messages.';
+$messages['bayesautohelp'] = 'When Bayes auto learn is enabled the system will automatically process messages which are very likely to be spam/non spam and use the information from those to improve the detection filters.';
+$messages['bayeshelp'] = 'The Bayesian classifier tries to identify spam by looking at words or short character sequences that are commonly found in spam or non spam messages.';
+$messages['rblhelp'] = 'Server addresses found in hypertext links in a message will be checked against several \'blacklists\' or lists of known spam sources.';
+$messages['dcchelp'] = 'The DCC or Distributed Checksum Clearinghouse is a system of servers collecting and counting checksums (or signatures) of millions of mail messages every day. The greater the similarity the checksum of an incoming message has to the list the more likely it is to be spam.';
+$messages['pyzhelp'] = 'Pyzor is a collaborative, networked system to detect and block spam using identifying digests of messages. The digests are generated in a number of different ways to allow for small differences in the content of the message.';
+$messages['raz2help'] = 'Vipul\'s Razor is a distributed, collaborative, spam detection and filtering network based on user submissions of spam. Detection is done with signatures that efficiently spot mutating spam content. The spam reports are validated through reputation assignments given to each reporter.';
+$messages['raz1help'] = 'Vipul\'s Razor is a distributed, collaborative, spam detection and filtering network based on user submissions of spam. Detection is done with signatures that efficiently spot mutating spam content. The spam reports are validated through reputation assignments given to each reporter. Version 1 has now been replaced by version 2 and is no longer supported.';
+$messages['levelhelp'] = 'The \'Spam Level\' header can be added to a message to indicate the score given to a message by repeating the character specified that many times. This may be useful for further processing of the message.';
+$messages['foldhelp'] = 'Should headers added by SpamAssassin will be wrapped? In other words, should they be broken up into multiple lines instead of one very long one. When a line is broken it will be indented to mark it as a continuation of the preceding one.';
+$messages['bayesruleshlp'] = 'Before the Bayesian-style classifier can be used effectively it must be "trained" to properly detect spam/non spam messages. Disabling the Bayesian rules allows the system to continue to learn both automatically and manually from incoming mail but it will not be used to detect spam.';
+$messages['purgebayesconfirm'] = 'Are you sure delete all your Bayesian data?';
+
+?> \ No newline at end of file
diff --git a/plugins/sauserprefs/localization/en_US.inc b/plugins/sauserprefs/localization/en_US.inc
new file mode 100644
index 000000000..6c500af9f
--- /dev/null
+++ b/plugins/sauserprefs/localization/en_US.inc
@@ -0,0 +1,86 @@
+<?php
+/* Author: Philip Weir */
+
+$labels = array();
+$labels['sauserprefs'] = 'Spam';
+$labels['managespam'] = 'Manage spam detection settings';
+$labels['sauserprefssettings'] = 'Spam settings';
+$labels['spamgeneralsettings'] = 'General Settings';
+$labels['spamthres'] = 'Score threshold';
+$labels['spamsubject'] = 'Subject tag';
+$labels['spamsubjectblank'] = '(leave blank for none)';
+$labels['spamlang'] = 'Message languages';
+$labels['enabled'] = 'Enabled';
+$labels['disabled'] = 'Disabled';
+$labels['headers'] = 'Message Headers';
+$labels['foldheaders'] = 'Allow multiple lines in headers';
+$labels['spamlevelstars'] = 'Use \'Spam Level\' header';
+$labels['spamlevelchar'] = 'Spam level character';
+$labels['spamtests'] = 'Internet Based Spam Tests';
+$labels['userazor1'] = 'Use Razor v1';
+$labels['userazor2'] = 'Use Razor v2';
+$labels['usepyzor'] = 'Use Pyzor';
+$labels['usebayes'] = 'Use Bayesian style classifier';
+$labels['usedcc'] = 'Use DCC';
+$labels['skiprblchecks'] = 'Use Realtime Blackhole List';
+$labels['spamreportsettings'] = 'Report Settings';
+$labels['spamreport0'] = 'Include report in headers of original message';
+$labels['spamreport1'] = 'Include original as MIME attachment to report';
+$labels['spamreport2'] = 'Include original as text-only attachment to report';
+$labels['spamaddressrules'] = 'Address Rules';
+$labels['whitelist_from'] = 'Accept Mail From';
+$labels['blacklist_from'] = 'Reject Mail From';
+$labels['whitelist_to'] = 'Accept Mail Sent To';
+$labels['addrule'] = 'Add Rule';
+$labels['rule'] = 'Rule';
+$labels['importfromaddressbook'] = 'Import addresses from Address Book';
+$labels['deleteall'] = 'Delete All';
+$labels['autoscore'] = 'Auto';
+$labels['defaultscore'] = 'Default Score';
+$labels['otherscore'] = 'Other (%s)';
+$labels['usedefault'] = 'Restore Default Settings';
+$labels['langoptions'] = 'Language Options';
+$labels['bayes'] = 'Bayes Settings';
+$labels['purgingbayes'] = 'Deleting Bayesian data...';
+$labels['purgebayes'] = 'Delete personal Bayesian data';
+$labels['bayesautolearn'] = 'Use Bayes auto learn';
+$labels['bayesautooptions'] = 'Auto learn options';
+$labels['bayesnonspam'] = 'Non spam threshold';
+$labels['bayesspam'] = 'Spam threshold';
+$labels['bayesrules'] = 'Use Baysian rules';
+$labels['help'] = 'Help';
+
+$messages = array();
+$messages['sauserprefchanged'] = 'Successfully changed spam settings';
+$messages['sauserpreffailed'] = 'Error: Cannot change spam settings';
+$messages['spamthresexp'] = 'Anything above the threshold is marked as spam. Increasing this threshold will increase the amount of spam missed, but will reduce the risk of false positives.';
+$messages['spamlangexp'] = 'Select all the languages you expect to receive e-mail in. Any messages received that are written in non selected languages will be treated as possible spam.';
+$messages['headersexp'] = 'SpamAssassin adds headers to processed messages providing information about the results. Use the options below to configure these headers.';
+$messages['spamtestssexp'] = 'Some checks use internet based services to help identify spam. Select the ones you wish to use:';
+$messages['spamreport'] = 'When a message is identified as spam a report of all tests and scores assigned is created...';
+$messages['autowhitelist'] = 'Email addresses in your Address Book are automatically added to the \'Accept Mail From\' list.';
+$messages['whitelistexp'] = 'An asterisk (*) can be used as a wild card for greater flexibility. For example: *@example.com or *@*.example.com.';
+$messages['spamaddressexists'] = 'A rule already exists for this address';
+$messages['spamenteraddress'] = 'Please enter an address to add';
+$messages['spamaddresserror'] = 'Error: Address appears invalid';
+$messages['spamaddressdelete'] = 'Are you sure you want to delete this rule?';
+$messages['spamaddressdeleteall'] = 'Are you sure you want to delete all address rules?';
+$messages['noaddressrules'] = 'No address rules found.';
+$messages['importingaddresses'] = 'Importing addresses...';
+$messages['usedefaultconfirm'] = 'Are you sure you want to restore the default settings? This will delete all your settings, including your address rules.';
+$messages['purgebayesexp'] = 'Delete personal Bayesian data collected from your email';
+$messages['bayesnonspamexp'] = 'Messages which score below this threshold will be used to improve the systems detection of non spam messages.';
+$messages['bayesspamexp'] = 'Messages which score above this threshold will be used to improve the systems detection of spam messages.';
+$messages['bayesautohelp'] = 'When Bayes auto learn is enabled the system will automatically process messages which are very likely to be spam/non spam and use the information from those to improve the detection filters.';
+$messages['bayeshelp'] = 'The Bayesian classifier tries to identify spam by looking at words or short character sequences that are commonly found in spam or non spam messages.';
+$messages['rblhelp'] = 'Server addresses found in hypertext links in a message will be checked against several \'blacklists\' or lists of known spam sources.';
+$messages['dcchelp'] = 'The DCC or Distributed Checksum Clearinghouse is a system of servers collecting and counting checksums (or signatures) of millions of mail messages every day. The greater the similarity the checksum of an incoming message has to the list the more likely it is to be spam.';
+$messages['pyzhelp'] = 'Pyzor is a collaborative, networked system to detect and block spam using identifying digests of messages. The digests are generated in a number of different ways to allow for small differences in the content of the message.';
+$messages['raz2help'] = 'Vipul\'s Razor is a distributed, collaborative, spam detection and filtering network based on user submissions of spam. Detection is done with signatures that efficiently spot mutating spam content. The spam reports are validated through reputation assignments given to each reporter.';
+$messages['raz1help'] = 'Vipul\'s Razor is a distributed, collaborative, spam detection and filtering network based on user submissions of spam. Detection is done with signatures that efficiently spot mutating spam content. The spam reports are validated through reputation assignments given to each reporter. Version 1 has now been replaced by version 2 and is no longer supported.';
+$messages['levelhelp'] = 'The \'Spam Level\' header can be added to a message to indicate the score given to a message by repeating the character specified that many times. This may be useful for further processing of the message.';
+$messages['foldhelp'] = 'Should headers added by SpamAssassin will be wrapped? In other words, should they be broken up into multiple lines instead of one very long one. When a line is broken it will be indented to mark it as a continuation of the preceding one.';
+$messages['bayesruleshlp'] = 'Before the Bayesian-style classifier can be used effectively it must be "trained" to properly detect spam/non spam messages. Disabling the Bayesian rules allows the system to continue to learn both automatically and manually from incoming mail but it will not be used to detect spam.';
+$messages['purgebayesconfirm'] = 'Are you sure delete all your Bayesian data?';
+
+?> \ No newline at end of file
diff --git a/plugins/sauserprefs/localization/es_ES.inc b/plugins/sauserprefs/localization/es_ES.inc
new file mode 100644
index 000000000..26dcb63d1
--- /dev/null
+++ b/plugins/sauserprefs/localization/es_ES.inc
@@ -0,0 +1,85 @@
+<?php
+/* Author: Joan Riera Pol */
+
+$labels = array();
+$labels['sauserprefs'] = 'Spam';
+$labels['sauserprefssettings'] = 'Preferencias de Spam';
+$labels['spamgeneralsettings'] = 'Preferencias Generales';
+$labels['spamthres'] = 'Margen de puntuación';
+$labels['spamsubject'] = 'Etiqueta del asunto';
+$labels['spamsubjectblank'] = '(dejar en blanco para ninguna)';
+$labels['spamlang'] = 'Idiomas de mensaje';
+$labels['enabled'] = 'Habilitado';
+$labels['disabled'] = 'Deshabilitado';
+$labels['headers'] = 'Cabecera de mensajes';
+$labels['foldheaders'] = 'Permitir múltiples líneas en cabecera';
+$labels['spamlevelstars'] = 'Usar \'nivel de spam\' en cabecera';
+$labels['spamlevelchar'] = 'Caracter para el nivel de spam';
+$labels['spamtests'] = 'Pruebas de Spam basadas en Internet';
+$labels['userazor1'] = 'Usar Razor v1';
+$labels['userazor2'] = 'Usar Razor v2';
+$labels['usepyzor'] = 'Usar Pyzor';
+$labels['usebayes'] = 'Usar clasificador de estilo Bayesian';
+$labels['usedcc'] = 'Usar DCC';
+$labels['skiprblchecks'] = 'Usar lista negra en tiempo real';
+$labels['spamreportsettings'] = 'Preferencias de informes';
+$labels['spamreport0'] = 'Incluir informe en la cabecera del mensaje original';
+$labels['spamreport1'] = 'Incluir original como adjunto MIME al informe';
+$labels['spamreport2'] = 'Incluir al informe el original como adjunto de sólo texto';
+$labels['spamaddressrules'] = 'Reglas de direcciones';
+$labels['whitelist_from'] = 'Aceptar correos de';
+$labels['blacklist_from'] = 'Rechazar correos de';
+$labels['whitelist_to'] = 'Aceptar correos mandados a';
+$labels['addrule'] = 'Añadir regla';
+$labels['rule'] = 'Regla';
+$labels['importfromaddressbook'] = 'Importar direcciones desde el la lista de contactos';
+$labels['deleteall'] = 'Eliminar todos';
+$labels['autoscore'] = 'Auto';
+$labels['defaultscore'] = 'Puntuación por defecto';
+$labels['otherscore'] = 'Otro (%s)';
+$labels['usedefault'] = 'Restaurar preferencias por defecto';
+$labels['langoptions'] = 'Opciones de idioma';
+$labels['bayes'] = 'Preferencias Bayesianas';
+$labels['purgingbayes'] = 'Eliminando datos Bayesianos...';
+$labels['purgebayes'] = 'Eliminar datos personales Bayesianos';
+$labels['bayesautolearn'] = 'Utilizar autoaprendizaje Bayes';
+$labels['bayesautooptions'] = 'Opciones de autoaprendizaje';
+$labels['bayesnonspam'] = 'Sin umbral de spam';
+$labels['bayesspam'] = 'Umbral de Spam';
+$labels['bayesrules'] = 'Usar reglas Bayesianas';
+$labels['help'] = 'Ayuda';
+
+$messages = array();
+$messages['sauserprefchanged'] = 'Preferencias de spam modificadas';
+$messages['sauserpreffailed'] = 'Error: No se han podido modificar las preferencias de spam';
+$messages['spamthresexp'] = 'Cualquier correo por encima del umbral será marcado como spam. Ampliando este umbral se incrementará la cantidad de spam no filtrado, pero reducirá el riesgo de falsos positivos.';
+$messages['spamlangexp'] = 'Selecciona los idiomas en los que esperas recibir los correos. Cualquier mensaje recibido escrito en cualquiera de los idiomas no seleccionados será tratado como posible spam.';
+$messages['headersexp'] = 'SpamAssassin añade cabeceras a mensajes procesados proporcionando información sobre los resultados. Usar las opciones inferiores para configurar estas cabeceras.';
+$messages['spamtestssexp'] = 'Algunas comprobaciones utilizan servicios en red para ayudar a identificar spam. Selecciona los que deseas utilizar:';
+$messages['spamreport'] = 'Cuando un mensaje es identificado como spam se creará un reporte de las pruebas y las puntuaciones asignadas...';
+$messages['autowhitelist'] = 'Las cuentas de correo en tu lista de contactos son añadidas de forma automática a la lista \'Aceptar correos de\'.';
+$messages['whitelistexp'] = 'Un asterisco (*) puede ser utilizado como wildcard para mayor flexibilidad. Por ejemplo: *@ejemplo.com o *@*.ejemplo.com.';
+$messages['spamaddressexists'] = 'Ya existe una regla para esta dirección';
+$messages['spamenteraddress'] = 'Por favor, introduce una dirección a añadir';
+$messages['spamaddresserror'] = 'Error: La dirección parece errónea';
+$messages['spamaddressdelete'] = '¿Estás seguro de eliminar esta regla?';
+$messages['spamaddressdeleteall'] = '¿Estás seguro de eliminar todas las reglas?';
+$messages['noaddressrules'] = 'No se han encontrado reglas.';
+$messages['importingaddresses'] = 'Importando direcciones...';
+$messages['usedefaultconfirm'] = '¿Estás seguro de querer restaurar las preferencias por defecto? Esto eliminará todas tus preferencias, incluyendo tus reglas de direcciones.';
+$messages['purgebayesexp'] = 'Eliminar datos Bayesianos personales recolectados de tu correo';
+$messages['bayesnonspamexp'] = 'Mensajes con puntuación menor al umbral será utilizado para mejorar los sistemas de detección de correos que no son spam.';
+$messages['bayesspamexp'] = 'Mensajes con puntuación superior al umbral serán utilizados para mejorar los sistemas de detección de correos no deseados.';
+$messages['bayesautohelp'] = 'Cuando se activa el autoaprendizaje Bayesiano el sistema precesará automáticamente los mensajes que posiblemente sean spam/no spam y usará su información para mejorar los filtros de detección.';
+$messages['bayeshelp'] = 'El clasificador Bayesiano trata de identificar spam buscando palabras o combinaciones cortas de letras que se encuentran comunmente en mensajes de spam.';
+$messages['rblhelp'] = 'Los servidores encontrados en los enlaces en los correos recibidos serán comprobadas en varias \'listas negras\' o listas de fuentes de spam conocidas.';
+$messages['dcchelp'] = 'El DCC o Distributed Checksum Clearinghouse es un sistema de servidores coleccionando y contando checksums (o firmas) de millones de correos electrónicos cada día. Cuanto más parecido es el checksum de un mensaje entrante a la lista es más probable que sea spam.';
+$messages['pyzhelp'] = 'Pyzor es un sistema en red colaborativo para detectar y bloquear spam utilizando trozos de mensajes. Estos trozos son generados en varias formas distintas para buscar pequeñas diferencias en el contenido del mensaje.';
+$messages['raz2help'] = 'Vipul\'s Razor es una red distribuida, colaborativa para la detección y filtrado de spam basada en envíos de usuarios. La detección es llevada a cabo con firmas que encuentran de forma eficiente el contenido spam. Los reportes de spam son validados mediante reputación dada a cada reportante.';
+$messages['raz1help'] = 'Vipul\'s Razor es una red distribuida, colaborativa para la detección y filtrado de spam basada en envíos de usuarios. La detección es llevada a cabo con firmas que encuentran de forma eficiente el contenido spam. Los reportes de spam son validados mediante reputación dada a cada reportante. Versión 1 ha sido modificado ahora por version 2 y ya no es soportada.';
+$messages['levelhelp'] = 'La cabecera de \'Nivel de Spam\' puede ser añadida a un mensaje para indicar la puntuación dada a un mensaje repitiendo determinadas veces el caracter especificado. Esto puede ser útil para el procesamiento posterior del mensaje.';
+$messages['foldhelp'] = '¿Debe la cabecera añadida por SpamAssassin ser cortada? En otras palabras, ¿debe ser partida en varias líneas la cabecera en vez de una muy larga? Cuando una linea es partida está indicada para marcarla como la continuacióon de la siguiente.';
+$messages['bayesruleshlp'] = 'Antes de que el clasificador de estilo Bayesiano pueda ser usado de forma efectiva tiene que ser "entrenado" para detectar correctamente los mensajes de spam/no spam. Deshabilitando las reglas Bayesianas permitirá continuar aprendiendo de forma automática y manual de correo entrante pero no será usado para filtrarlo.';
+$messages['purgebayesconfirm'] = '¿Estás seguro de querer eliminar todos tus datos Bayesianos?';
+
+?> \ No newline at end of file
diff --git a/plugins/sauserprefs/localization/fr_FR.inc b/plugins/sauserprefs/localization/fr_FR.inc
new file mode 100644
index 000000000..c8ce746b1
--- /dev/null
+++ b/plugins/sauserprefs/localization/fr_FR.inc
@@ -0,0 +1,86 @@
+<?php
+/* Author: Jérémy Bobbio based on previous translation by magik_cypress */
+
+$labels = array();
+$labels['sauserprefs'] = 'Spam';
+$labels['managespam'] = 'Gérer les paramètres de détection des spams';
+$labels['sauserprefssettings'] = 'Préférences liées au spams';
+$labels['spamgeneralsettings'] = 'Préférences principales';
+$labels['spamthres'] = 'Seuil';
+$labels['spamsubject'] = 'Étiqueter le sujet';
+$labels['spamsubjectblank'] = '(laisser vide pour ne pas mettre d\'étiquette)';
+$labels['spamlang'] = 'Langues des messages';
+$labels['enabled'] = 'Actif';
+$labels['disabled'] = 'Inactif';
+$labels['headers'] = 'En-têtes du message';
+$labels['foldheaders'] = 'Autoriser plusieurs lignes dans les en-têtes';
+$labels['spamlevelstars'] = 'Utiliser l\'en-tête "Spam Level"';
+$labels['spamlevelchar'] = 'Symbole représentant le niveau de spam';
+$labels['spamtests'] = 'Services externes de détection';
+$labels['userazor1'] = 'Utiliser Razor v1';
+$labels['userazor2'] = 'Utiliser Razor v2';
+$labels['usepyzor'] = 'Utiliser Pyzor';
+$labels['usebayes'] = 'Utiliser le filtre bayésien';
+$labels['usedcc'] = 'Utiliser DCC';
+$labels['skiprblchecks'] = 'Utiliser les listes noires (RBL)';
+$labels['spamreportsettings'] = 'Préférences du rapport';
+$labels['spamreport0'] = 'Inclure le rapport dans les en-têtes du message original';
+$labels['spamreport1'] = 'Inclure tout le message original en pièce-jointe du rapport';
+$labels['spamreport2'] = 'Inclure le texte du message original en pièce-jointe du rapport';
+$labels['spamaddressrules'] = 'Adresses particulières';
+$labels['whitelist_from'] = 'Accepter les messages de';
+$labels['blacklist_from'] = 'Rejeter les messages de';
+$labels['whitelist_to'] = 'Accepter les messages envoyé à';
+$labels['addrule'] = 'Ajouter';
+$labels['rule'] = 'Règle';
+$labels['importfromaddressbook'] = 'Importer le carnet d\'adresses';
+$labels['deleteall'] = 'Tout supprimer';
+$labels['autoscore'] = 'Auto';
+$labels['defaultscore'] = 'Score par défaut';
+$labels['otherscore'] = 'Autre (%s)';
+$labels['usedefault'] = 'Rétablir les préférences par défaut';
+$labels['langoptions'] = 'Options de langues';
+$labels['bayes'] = 'Préférences du filtre bayésien';
+$labels['purgingbayes'] = 'Suppression des données du filtre bayésien...';
+$labels['purgebayes'] = 'Supprimer les données personnelles du filtre bayésien';
+$labels['bayesautolearn'] = 'Activer l\'apprentissage automatique du filtre bayésien';
+$labels['bayesautooptions'] = 'Options de l\'apprentissage automatique';
+$labels['bayesnonspam'] = 'Seuil des messages légitimes';
+$labels['bayesspam'] = 'Seuil des spams';
+$labels['bayesrules'] = 'Utiliser le filtre bayésien pour la détection';
+$labels['help'] = 'Aide';
+
+$messages = array();
+$messages['sauserprefchanged'] = 'Préférences modifiées avec succès';
+$messages['sauserpreffailed'] = 'Erreur : impossible de modifier les préférences';
+$messages['spamthresexp'] = 'Tout ce qui se trouve au dessus du seuil sera considéré comme spam. Augmenter le seuil va donc augmenter le nombre de spams qui ne seront pas détectés, mais réduira les risques de faux positifs.';
+$messages['spamlangexp'] = 'Choisir toutes les langues dans lesquelles seront écrits les messages reçus. Tous les messages reçus qui seront écrits dans une langue qui n\'aura pas été choisie sera traité comme un spam possible.';
+$messages['headersexp'] = 'SpamAssassin ajoute des en-têtes contenant des informations sur les traitements effectués. Les options suivantes permettent de configurer ces en-têtes.';
+$messages['spamtestssexp'] = 'Certains tests utilisent des services Internet externes pour aider à identifier les spams. Choisir ceux qui doivent êtres utilisés :';
+$messages['spamreport'] = 'Quand un message est identifié comme spam, un rapport avec tous les tests et scores est créé...';
+$messages['autowhitelist'] = 'Les adresses qui se trouvent dans le carnet d\'adresses sont automatiquement ajoutées dans la liste des exceptions.';
+$messages['whitelistexp'] = 'Une astérisque (*) peut être utilisé comme joker pour les traitements généraux. Par exemple : *example.com ou *@*.example.com.';
+$messages['spamaddressexists'] = 'Une règle existe déjà pour cette addresse';
+$messages['spamenteraddress'] = 'Entrer une adresse à ajouter';
+$messages['spamaddresserror'] = 'Erreur : l\'adresse semble invalide';
+$messages['spamaddressdelete'] = 'Faut-il vraiment supprimer cette règle ?';
+$messages['spamaddressdeleteall'] = 'Faut-il vraiment supprimer toutes les règles ?';
+$messages['noaddressrules'] = 'Aucune règle n\'a été trouvé.';
+$messages['importingaddresses'] = 'Importation des adresses en cours...';
+$messages['usedefaultconfirm'] = 'Faut-il vraiment rétablir les préférences par défaut ? Cela supprimera tous les changements, dont les réglages spécifiques.';
+$messages['purgebayesexp'] = 'Supprimer les données personnelles du filtre bayésien apprises de vos courriels';
+$messages['bayesnonspamexp'] = 'Les messages classés en-dessous de ce seuil seront utilisés pour améliorer la détection des messages légitimes.';
+$messages['bayesspamexp'] = 'Les messages classés au-dessus de ce seuil seront utilisés pour améliorer la détection des spams.';
+$messages['bayesautohelp'] = 'Quand l\'apprentissage automatique du filtre bayésien est activé, le système traitera les messages qui sembleront être ou ne pas être des spams afin d\'améliorer la détection de futurs messages.';
+$messages['bayeshelp'] = 'Le filtre bayésien essaye d\'identifier les spams à partir des mots ou des séquences de caractères qui se trouvent dans les messages qui sont ou ne sont pas des spams.';
+$messages['rblhelp'] = 'Les adresses des serveurs qui se trouvent dans les liens hypertextes d\'un message seront vérifiés à partir de plusieurs "listes noires" ou listes de sources connues de spam.';
+$messages['dcchelp'] = 'Le DCC ou le "Distributed Checksum Clearinghouse" est un système de serveurs collectant et contant les signatures de millions de courriels chaque jour. Plus la signature d\'un message reçu est similaire à celle de la liste, plus il a de chances d\'être un spam.';
+$messages['pyzhelp'] = 'Pyzor est un réseau collaboratif de systèmes visant à détecter et bloquer les spams à partir de condensé de messages. Ces condensés sont générés de plusieurs manières différentes afin d\'autoriser de petites différences dans le contenu des messages.';
+$messages['raz2help'] = 'Vipul\'s Razor est un réseau collaboratif et distribué de détection et de filtrage de spam se basant sur des envois de spams par les utilisateurs. La détection est faite à partir de signatures qui détectent efficacement le contenu changeant des spams. Les rapports sont validés grâce à une réputation associée à chaque rapporteur.';
+$messages['raz1help'] = 'Vipul\'s Razor est un réseau collaboratif et distribué de détection et de filtrage de spam se basant sur des envois de spams par les utilisateurs. La détection est faite à partir de signatures qui détectent efficacement le contenu changeant des spams. Les rapports sont validés grâce à une réputation associée à chaque rapporteur. La version 1 a été remplacé par la version 2 et n\'est donc plus supportée.';
+$messages['levelhelp'] = 'L\'en-tête "Spam Level" peut être ajouté à un message pour indiquer le score de ce dernier en répetant un symbole plusieurs fois. Cela peut être utile pour le traitement ultérieur du message.';
+$messages['foldhelp'] = 'Est-ce que les en-têtes ajoutés par SpamAssassin doivent revenir à la ligne ? En d\'autres termes, est-ce qu\'ils doivent êtres répartis sur plusieurs lignes au lieu de n\'être que sur seule ligne très longue. Lorsqu\'il y a un retour à la ligne, la suivante sera indenté afin de marquer la continuité avec la précédente.';
+$messages['bayesruleshlp'] = 'Avant que le filtre bayésien puisse être utilisé, il doit effectivement être "entrainé" pour pouvoir correctement détecter les spams. Désactiver le filtre bayésien permet au système de continuer à apprendre automatiquement et manuellement des messages reçus, mais il ne sera pas utilisé pour la détection des spams en eux-mêmes.';
+$messages['purgebayesconfirm'] = 'Faut-il vraiment supprimer toutes les données personnelles du filtre bayésien ?';
+
+?> \ No newline at end of file
diff --git a/plugins/sauserprefs/localization/gl_ES.inc b/plugins/sauserprefs/localization/gl_ES.inc
new file mode 100644
index 000000000..e7dfe159a
--- /dev/null
+++ b/plugins/sauserprefs/localization/gl_ES.inc
@@ -0,0 +1,85 @@
+<?php
+/* Author: David Garabana Barro */
+
+$labels = array();
+$labels['sauserprefs'] = 'Correo lixo';
+$labels['sauserprefssettings'] = 'Axustes de correo lixo';
+$labels['spamgeneralsettings'] = 'Axustes xerais';
+$labels['spamthres'] = 'Umbral de puntuación';
+$labels['spamsubject'] = 'Etiqueta do asunto';
+$labels['spamsubjectblank'] = '(deixar en branco para ningún)';
+$labels['spamlang'] = 'Idiomas da mensaxe';
+$labels['enabled'] = 'Activado';
+$labels['disabled'] = 'Desactivado';
+$labels['headers'] = 'Cabeceiras da mensaxe';
+$labels['foldheaders'] = 'Permitir cabecerias de máis dunha liña';
+$labels['spamlevelstars'] = 'Utilizar a cabeceira \'Spam Level\'';
+$labels['spamlevelchar'] = 'Caracter de nivel de correo lixo';
+$labels['spamtests'] = 'Probas de correo lixo en Internet';
+$labels['userazor1'] = 'Utilizar Razor v1';
+$labels['userazor2'] = 'Utilizar Razor v2';
+$labels['usepyzor'] = 'Utilizar Pyzor';
+$labels['usebayes'] = 'Utilizar o clasificador de tipo Bayesian';
+$labels['usedcc'] = 'Utilizar DCC';
+$labels['skiprblchecks'] = 'Utilizar a \'Realtime Blackhole List\' (RBL)';
+$labels['spamreportsettings'] = 'Axustes de informes ';
+$labels['spamreport0'] = 'Incluir informe nas cabeceiras da mensaxe orixinal';
+$labels['spamreport1'] = 'Incluir a mensaxe orixinal coma anexo MIME ao informe';
+$labels['spamreport2'] = 'Incluir a mensaxe orixinal coma anexo de texto ao informe';
+$labels['spamaddressrules'] = 'Regras de direccións';
+$labels['whitelist_from'] = 'Aceptar correo de';
+$labels['blacklist_from'] = 'Rexeitar correo de';
+$labels['whitelist_to'] = 'Aceptar correo enviado a';
+$labels['addrule'] = 'Engadir regra';
+$labels['rule'] = 'Regra';
+$labels['importfromaddressbook'] = 'Importar direccións dende a libreta de direccións';
+$labels['deleteall'] = 'Eliminar todo';
+$labels['autoscore'] = 'Auto';
+$labels['defaultscore'] = 'Puntuación por omisión';
+$labels['otherscore'] = 'Outro (%s)';
+$labels['usedefault'] = 'Restaurar os valores por omisión';
+$labels['langoptions'] = 'Opcións da linguaxe';
+$labels['bayes'] = 'Axustes de Bayes';
+$labels['purgingbayes'] = 'Eliminando os datos bayesianos';
+$labels['purgebayes'] = 'Eliminando os datos persoais bayesianos';
+$labels['bayesautolearn'] = 'Empregar autoaprendizaxe bayesiano';
+$labels['bayesautooptions'] = 'Opcións de autoaprendizaxe';
+$labels['bayesnonspam'] = 'Umbral de "non correo lixo"';
+$labels['bayesspam'] = 'Umbral de "correo lixo"';
+$labels['bayesrules'] = 'Empregar regras bayesianas';
+$labels['help'] = 'Axuda';
+
+$messages = array();
+$messages['sauserprefchanged'] = 'Modificáronse correctamente os axustes de correo lixo';
+$messages['sauserpreffailed'] = 'Produciuse un erro: Non se poden modificar os axustes de correo lixo';
+$messages['spamthresexp'] = 'Calquera puntuación por enbira desde umbral é marcado coma correo lixo. Se sube este umbral, aumentará a cantidade de correo lixo non detectado, pero tamén reducirá o risco de que se produzan falsos positivos.';
+$messages['spamlangexp'] = 'Escolla as linguaxes nas que espera recibir correo electrónico.Calquera mensaxe que reciba escrita nunha língua non seleccionada será tratada coma posible correo lixo.';
+$messages['headersexp'] = 'SpamAssassin engade cabeceiras ás mensaxes procesadas informando dos resultados. Empregue as opcións de embaixo para configurar estas cabeceiras.';
+$messages['spamtestssexp'] = 'Algunhas das probas utilizan servicios de Internet para axudar a identificar o correo lixo. Escolla as que lle gostaría empregar:';
+$messages['spamreport'] = 'Cando unha mensaxe se identifica coma correo lixo, créase un informe de tódalas probas probas e puntuacións asignadas...';
+$messages['autowhitelist'] = 'As direccións de correo electrónico na súa libreta de direccións engádense automáticamente á lista de \'Aceptar correo de\'';
+$messages['whitelistexp'] = 'Pódese usar un asterisco (*) coma comodín para ter máis flexibilidade. Por exemplo: *@exemplo.com ou *@*.exemplo.com.';
+$messages['spamaddressexists'] = 'Xa existe una regra para esta dirección';
+$messages['spamenteraddress'] = 'Por favor, introduza unha dirección para engadir';
+$messages['spamaddresserror'] = 'Produciuse un erro: A dirección semella inválida';
+$messages['spamaddressdelete'] = 'Está seguro de que quere borrar esta regra?';
+$messages['spamaddressdeleteall'] = 'Está seguro de que quere borrar tódalas regras de dirección?';
+$messages['noaddressrules'] = 'Non se atoparon regras de dirección';
+$messages['importingaddresses'] = 'Importando direccións...';
+$messages['usedefaultconfirm'] = 'Está seguro de que quere restaurar os valores po omisión?. Esto vai borrar tódolos seus axustes, incluso as regras de dirección.';
+$messages['purgebayesexp'] = 'Eliminar os datos bayesianos persoais do seu correo electrónico';
+$messages['bayesnonspamexp'] = 'As mensaxes con puntuación menor a este umbrar vanse usar para mellorar os sistemas de detección de mensaxes non lixo';
+$messages['bayesspamexp'] = 'As mensaxes con puntuación maior a este umbrar vanse usar para mellorar os sistemas de detección de mensaxes lixo';
+$messages['bayesautohelp'] = 'Cando está activado o autoaprendizaxe bayesiano, o sistema vai procesar automáticamente as mensaxes que semellan correo lixo/non lixo, e usará a información destes para mellorar os filtros de detección.';
+$messages['bayeshelp'] = 'O clasificador bayesiano tenta identificar o correo lixo buscando por verbas ou secuencias cortas de caracteres que adoitan atoparse en mensaxes lixo e non lixo.';
+$messages['rblhelp'] = 'As direccións de servidores atopadas en ligazóns nunha mensaxe hanse comprobar en diversas "listas negras" ou listas de orixes coñecidos de correo lixo.';
+$messages['dcchelp'] = 'O "Distributed Checksum Clearinghouse" é un sistema de servidores que colleitan e contan sumas de comprobación (ou sinaturas) de millóns de mensaxes de correo cada día. Canto máis se pareza una suma dunha mensaxe entrante a unha da lista, máis probable é que sea corre lixo.';
+$messages['pyzhelp'] = 'Pyzor é un sistema colaborativo en rede para detectar e bloquear correo lixo utilizando resumos que identifican mensaxes. Os resumos xenéranse de varias maneiras distintas, para atopar pequenas diferencias no contido da mensaxe.';
+$messages['raz2help'] = 'Vipul\'s Razor é unha rede distribuida e colaborativa de detección e filtrado de correo lixo, que se basa en envíos de correo lixo por parte de usuarios. A detección faise por medio de sinaturas que paran de manera eficiente a mutación dos contidos do correo lixo. Os envíos de correo lixo valídanse a través de asignacións de reputación que se lle otorga a cada usuario.';
+$messages['raz1help'] = 'Vipul\'s Razor é unha rede distribuida e colaborativa de detección e filtrado de correo lixo, que se basa en envíos de correo lixo por parte de usuarios. A detección faise por medio de sinaturas que paran de manera eficiente a mutación dos contidos do correo lixo. Os envíos de correo lixo valídanse a través de asignacións de reputación que se lle otorga a cada usuario. A versión 1 foi trocada pola 2, e xa non está soportada.';
+$messages['levelhelp'] = 'Pódese engadir a cabeceria "Spam Level" á mensaxe para indicar a puntuación dada repetindo o carácter especificad tantas veces coma puntos teña a mensaxe. Pode ser útil para procesamiento posterior da menxase.';
+$messages['foldhelp'] = 'Deberíanse cortar as cabeceiras engadidas por SpamAssassin? Ou, dito doutro xeito, deberíanse dividir en varias liñas no canto de deixala nuna soa liña moi longa?. Cando se divide unha liña sángrase para indicar que é continuación da anterior.';
+$messages['bayesruleshlp'] = 'Antes de poder usar o clasificador tipo bayesiano, é necesario "entranalo" para que detecte eficientemente correos lixo/non lixo. Se se desactivan as regras bayesianas, permítese que o sistema continue a aprender automáticamente e manualmente das mensaxes entrantes, pero non se vai usar para detectar correo lixo.';
+$messages['purgebayesconfirm'] = 'Está seguro de que quere borrar os seus datos bayesianos?';
+
+?> \ No newline at end of file
diff --git a/plugins/sauserprefs/localization/hu_HU.inc b/plugins/sauserprefs/localization/hu_HU.inc
new file mode 100644
index 000000000..952f3f1cf
--- /dev/null
+++ b/plugins/sauserprefs/localization/hu_HU.inc
@@ -0,0 +1,61 @@
+<?php
+/* Author: Zoltan Nagy */
+
+$labels = array();
+$labels['sauserprefs'] = 'Spam';
+$labels['sauserprefssettings'] = 'Spam beállítás';
+$labels['spamgeneralsettings'] = 'Általános beállítás';
+$labels['spamthres'] = 'Küszöb szám';
+$labels['spamsubject'] = 'Tárgy cimke';
+$labels['spamsubjectblank'] = '(hagyja üressen ha egyik sem)';
+$labels['spamlang'] = 'Üzenetek nyelve';
+$labels['enabled'] = 'Bekapcsolva';
+$labels['disabled'] = 'Kikapcsolva';
+$labels['headers'] = 'Üzenet fejléc';
+$labels['foldheaders'] = 'Több sor engedélyezése a fejlécben';
+$labels['spamlevelstars'] = '\'Spam szint\' fejléc használata';
+$labels['spamlevelchar'] = 'Spam szint karakter';
+$labels['spamtests'] = 'Inernet Alapu Spam Tesztek';
+$labels['userazor1'] = 'Razor v1 használata';
+$labels['userazor2'] = 'Razor v2 használata';
+$labels['usepyzor'] = 'Pyzor használata';
+$labels['usebayes'] = 'Nyílt (naiv) Bayesian stílusú besorolás használata';
+$labels['usedcc'] = 'DCC használata';
+$labels['skiprblchecks'] = 'Valós idejű Feketelyuk Lista használata';
+$labels['spamreportsettings'] = 'Beállítások jelentése';
+$labels['spamreport0'] = 'A riport beágyazása az eredeti fejlécbe';
+$labels['spamreport1'] = 'az eredeti MIME-ként csatolása a ripothoz';
+$labels['spamreport2'] = 'az eredeti csak szöveg-ként csatolása a ripothoz';
+$labels['spamaddressrules'] = 'Cím szabályok';
+$labels['whitelist_from'] = 'Mailek elfogadása küldőtől';
+$labels['blacklist_from'] = 'Mailek visszautasítása küldőtől';
+$labels['whitelist_to'] = 'Címzettnek küldött mailek elfogadása';
+$labels['addrule'] = 'Szabály hozzáadása';
+$labels['rule'] = 'Szabály';
+$labels['importfromaddressbook'] = 'Címek importálása a Címjegyzékből';
+$labels['deleteall'] = 'Mindent törli';
+$labels['autoscore'] = 'Auto';
+$labels['defaultscore'] = 'Alapérték';
+$labels['otherscore'] = 'Egyéb (%s)';
+$labels['usedefault'] = 'Alabértékek visszaállítása';
+
+$messages = array();
+$messages['sauserprefchanged'] = 'Sikeresen megváltoztatta a spam beállításokat';
+$messages['sauserpreffailed'] = 'Hiba: nem sikerült a spam beállítások megváltoztatása';
+$messages['spamthresexp'] = 'Minden ami a küszöb alatti érték, spam-ként lesz jelölve. A küszöb értékének a növelése, növeli a bejutó spameket, de csökkenti a hamis spam jelölést';
+$messages['spamlangexp'] = 'Válassza ki a nyelveket amilyen nyelvü leveleket vár. Minden érkező levél amely a nem megjelölt nyelven íródott, lehetséges spamként lesz kezelve.';
+$messages['headersexp'] = 'A SpamAssassin fejlécet ad a levélhez mely információval szolgál az eredményről. Az alábbi beállításokkal konfigurálhatja ezeket a fejléceket.';
+$messages['spamtestssexp'] = 'Néhány beállítás internet alapu szolgáltatást használ a spamek azonosítására. Válassza ki a használni kivántakat.';
+$messages['spamreport'] = 'Mikor egy üzenet spamként kerül azonosításra, létrejön egy csatolt riport a tesztek és eredményeikből.';
+$messages['autowhitelist'] = 'A Címjegyzékben található e-mail címek automatikusan hozzáadódnak a \'Mail Elfogadás -tól\'';
+$messages['whitelistexp'] = 'A csillag karakter (*) használható helyettesítő karakterként a nagyobb rugalmasságért. pl. *@example.com vagy *@*.example.com';
+$messages['spamaddressexists'] = 'Ehhez a címhez már létezik szabály';
+$messages['spamenteraddress'] = 'Írja be a címet melyet szeretne hozzáadni';
+$messages['spamaddresserror'] = 'Hiba: a cím érvénytelen';
+$messages['spamaddressdelete'] = 'Biztosan törölni szeretné ezt a szabályt?';
+$messages['spamaddressdeleteall'] = 'Biztosan törölni szeretné az összes cím szabályt?';
+$messages['noaddressrules'] = 'Nem található cím szabály.';
+$messages['importingaddresses'] = 'Címek importálása...';
+$messages['usedefaultconfirm'] = 'Biztos, hogy vissza szeretné állítani az alapbeállítást? Ez törli az összes beállítást, ideértve a cím szabályokat is.';
+
+?> \ No newline at end of file
diff --git a/plugins/sauserprefs/localization/it_IT.inc b/plugins/sauserprefs/localization/it_IT.inc
new file mode 100644
index 000000000..67f4a99a0
--- /dev/null
+++ b/plugins/sauserprefs/localization/it_IT.inc
@@ -0,0 +1,86 @@
+<?php
+/* Author: Alessio Cecchi */
+
+$labels = array();
+$labels['sauserprefs'] = 'Spam';
+$labels['managespam'] = 'Gestisci le impostazioni di rilevamento dello Spam';
+$labels['sauserprefssettings'] = 'Impostazioni spam';
+$labels['spamgeneralsettings'] = 'Impostazioni generali';
+$labels['spamthres'] = 'Punteggio valutazione';
+$labels['spamsubject'] = 'Tag oggetto';
+$labels['spamsubjectblank'] = '(lasciare in bianco se niente)';
+$labels['spamlang'] = 'Lingue del messaggio';
+$labels['enabled'] = 'Abilitato';
+$labels['disabled'] = 'Disabilitato';
+$labels['headers'] = 'Intestazioni messaggio';
+$labels['foldheaders'] = 'Consenti più linee nell\'intestazione';
+$labels['spamlevelstars'] = 'Usa instazione \'Spam Level\'';
+$labels['spamlevelchar'] = 'carattere \'Spam level\'';
+$labels['spamtests'] = 'Test spam su internet';
+$labels['userazor1'] = 'Usa Razor v1';
+$labels['userazor2'] = 'Usa Razor v2';
+$labels['usepyzor'] = 'Usa Pyzor';
+$labels['usebayes'] = 'Usa stile classificazione ingenua Bayesiana';
+$labels['usedcc'] = 'Usa DCC';
+$labels['skiprblchecks'] = 'Usa RBL (Realtime Blackhole List)';
+$labels['spamreportsettings'] = 'Impostazioni dei rapporti';
+$labels['spamreport0'] = 'Includi report nelle intestazioni del messaggio originale';
+$labels['spamreport1'] = 'Includi il messaggio originale come allegato MIME al raporto';
+$labels['spamreport2'] = 'Includi il messeggio originale come allegato TXT al rapporto';
+$labels['spamaddressrules'] = 'Regole su indirizzi';
+$labels['whitelist_from'] = 'Consenti DA ( From: )';
+$labels['blacklist_from'] = 'Nega DA ( From: )';
+$labels['whitelist_to'] = 'Consenti destinatiari ( To: )';
+$labels['addrule'] = 'Aggiungi regola';
+$labels['rule'] = 'Regola';
+$labels['importfromaddressbook'] = 'Importa indirizzi dalla rubrica online';
+$labels['deleteall'] = 'Cancella tutto';
+$labels['autoscore'] = 'Automatico';
+$labels['defaultscore'] = 'Punteggio standard';
+$labels['otherscore'] = 'Altro (%s)';
+$labels['usedefault'] = 'Ripristina le impostazioni iniziali';
+$labels['langoptions'] = 'Opzioni Lingua';
+$labels['bayes'] = 'Impostazione filtri Bayesiani';
+$labels['purgingbayes'] = 'Cancellazione dei dati Bayesiani...';
+$labels['purgebayes'] = 'Elimina i dati personali Bayesiani';
+$labels['bayesautolearn'] = 'Utilizza l\'Apprendimento automatico Bayesiano';
+$labels['bayesautooptions'] = 'Impostazioni Apprendimento automatico';
+$labels['bayesnonspam'] = 'Soglia di Non Spam';
+$labels['bayesspam'] = 'Soglia di Spam';
+$labels['bayesrules'] = 'Utilizza i filtri Bayesiani';
+$labels['help'] = 'Aiuto';
+
+$messages = array();
+$messages['sauserprefchanged'] = 'Cambiamenti applicati con successo';
+$messages['sauserpreffailed'] = 'Errore: imposibile salvare i cambiamenti';
+$messages['spamthresexp'] = 'Tutto quello che oltre passa il punteggio verrà segnalato come spam. Aumentare il punteggio significa aumentare i messaggi di spam non segnalati, ma riduce il richio di falsi positivi.';
+$messages['spamlangexp'] = 'Selezionare tutte le lingue in cui ci si aspetta possa arrivare un messaggio. Tutti i messaggi che arriveranno in una lingua non selezionata saranno segnalati come spam.';
+$messages['headersexp'] = 'SpamAssassin aggiunge delle intestazioni al messaggioriguardante il risultato dell\'analisi. Usare questa opzione per configurare queste intestazioni.';
+$messages['spamtestssexp'] = 'Certi controlli utilizzano dei servizi internet per analizzare il messaggio. Selezionare quello che si vuole utilizzare:';
+$messages['spamreport'] = 'Quando un messaggio viene identificato come spam viene creato un rapporto dei test ed il punteggio questo rapporto viene creato...';
+$messages['autowhitelist'] = 'Gli indirizzi Email della Rubrica della Webmail vengono caricati automaticamente ed inseriti nella lista \'Consenti mail DA\'.';
+$messages['whitelistexp'] = 'Un asterisco (*) può essere usato come carattere \'jolly\' per aumentare la flessibilità della regola. Ad esempio: *@dominio.com o *@*.dominio.com.';
+$messages['spamaddressexists'] = 'Esiste già una regola per questo indirizzo';
+$messages['spamenteraddress'] = 'Inserire un indirizzo da aggiungere';
+$messages['spamaddresserror'] = 'Errore: Indirizzo invalido';
+$messages['spamaddressdelete'] = 'Sicuro di voler CANCELLARE questa regola?';
+$messages['spamaddressdeleteall'] = 'Sicuro di voler CANCELLARE TUTTI gli indirizzi della lista??';
+$messages['noaddressrules'] = 'Nessuna regola trovata.';
+$messages['importingaddresses'] = 'Importazione indirizzi...';
+$messages['usedefaultconfirm'] = 'Sicuro di voler ripristinare le impostazioni iniziali ? Questa operazione CANCELLERA TUTTE LE IMPOSTAZIONI, incluse le regole per i messaggi!.';
+$messages['purgebayesexp'] = 'Elimina i dati Bayesiani personali raccolti dal tuo indirizzo email';
+$messages['bayesnonspamexp'] = 'I messaggi con punteggio al di sotto di questa soglia verranno utilizzati per migliorare l\'individuazione dei messaggi non spam.';
+$messages['bayesspamexp'] = 'I messaggi con punteggio al di sopra di questa soglia verranno utilizzati per migliorare l\'individuazione dei messaggi di spam.';
+$messages['bayesautohelp'] = 'Quando l\'apprendimento automatico Bayesiano è abilitato il sistema analizza automaticamente i messaggi che con molta probabilità sono spam oppure no e utilizza le informazioni ricavate per migliorare il rilevamento.';
+$messages['bayeshelp'] = 'I filtri Bayesiaio provano ad identificare lo spam, cercando parole o brevi sequenze di caratteri che si trovano più di frequente nei messaggi di spam e non.';
+$messages['rblhelp'] = 'Gli indirizzi trovati nei collegamenti ipertestuali di un messaggio verranno controllati sulla base di diverse "liste nere" o liste di fonti di spam note.';
+$messages['dcchelp'] = 'DCC o Distributed Checksum Clearinghouse è un sistema centralizzato di raccolta e conteggio checksum (o firme) di milioni di messaggi di posta elettronica in transito ogni giorno. Quanto maggiore è la somiglianza del checksum di un messaggio in arrivo nel sistema DCC, più probabile è che quel messaggio possa essere spam.';
+$messages['pyzhelp'] = 'Pyzor è una network collaborativo per rilevare e bloccare lo spam utilizzando la raccolta ed il conteggio dei digest (o firme) dei messaggi. I digest sono generati in un numero di modi diversi per tollerare piccole differenze nel contenuto del messaggio.';
+$messages['raz2help'] = 'Vipul Razor è un network collaborativo per l\'individuazione dello spam. La rilevazione viene effettuata con le firme in modo efficiente al fine di individuare mutazione nei di spam. Le segnalazioni di spam sono convalidati mediante l\'assegnazione di reputazione dato a ogni contributore al network.';
+$messages['raz1help'] = 'Vipul Razor è un network collaborativo per l\'individuazione dello spam. La rilevazione viene effettuata con le firme in modo efficiente al fine di individuare mutazione nei di spam. Le segnalazioni di spam sono convalidati mediante l\'assegnazione di reputazione dato a ogni contributore al network. La versione 1 è stata sostituita dalla versione 2 e non è più utilizzata.';
+$messages['levelhelp'] = 'L\'intestazione \'Spam Level\' può essere aggiunto a un messaggio per indicare il punteggio assegnatoli ripetendo il carattere specificato molte volte. Ciò può essere utile per un ulteriore elaborazione del messaggio.';
+$messages['foldhelp'] = 'Gli header aggiunti da SpamAssassin devono essere suddivisi? In altre parole, essi dovrebbero essere suddivisi in più righe invece di una molto lunga. Quando una linea è interrotta apparirà rientrata per segnalare la continuazione della precedente.';
+$messages['bayesruleshlp'] = 'Prima che i filtri Bayesiani possano funzionare in modo efficace devono essere "addestrati" per rilevare correttamente i messaggi di spam e non. La disattivazione delle regole bayesiane permette al sistema di continuare l\'apprendimento sia automaticamente che manualmente sulla posta in arrivo, ma non saranno utilizzati per rilevare lo spam.';
+$messages['purgebayesconfirm'] = 'Sei sicuro di voler eliminare tutti i dati bayesiani?';
+
+?> \ No newline at end of file
diff --git a/plugins/sauserprefs/localization/pl_PL.inc b/plugins/sauserprefs/localization/pl_PL.inc
new file mode 100644
index 000000000..eaae55944
--- /dev/null
+++ b/plugins/sauserprefs/localization/pl_PL.inc
@@ -0,0 +1,86 @@
+<?php
+/* Author: Bartosz Mierzwiak */
+
+$labels = array();
+$labels['sauserprefs'] = 'Spam';
+$labels['managespam'] = 'Ustawienia wykrywania Spamu';
+$labels['sauserprefssettings'] = 'Ustawienia Spamu';
+$labels['spamgeneralsettings'] = 'Ustawienia Główne';
+$labels['spamthres'] = 'Próg punktowania';
+$labels['spamsubject'] = 'Znacznik w temacie';
+$labels['spamsubjectblank'] = '(zostaw puste jesli brak)';
+$labels['spamlang'] = 'Język wiadomości';
+$labels['enabled'] = 'Włączony';
+$labels['disabled'] = 'Wyłączony';
+$labels['headers'] = 'Nagłówki Wiadomości';
+$labels['foldheaders'] = 'Zezwalaj na wiele lini w nagłówku';
+$labels['spamlevelstars'] = 'Użyj \'Spam Level\' w nagłówku';
+$labels['spamlevelchar'] = 'Znacznik poziomu spamu';
+$labels['spamtests'] = 'Testy Spamu oparte o internet';
+$labels['userazor1'] = 'Użyj Razor v1';
+$labels['userazor2'] = 'Użyj Razor v2';
+$labels['usepyzor'] = 'Użyj Pyzor';
+$labels['usebayes'] = 'Użyj Bayesian style classifier';
+$labels['usedcc'] = 'Użyj DCC';
+$labels['skiprblchecks'] = 'Użyj Realtime Blackhole List';
+$labels['spamreportsettings'] = 'Opcje Raportu';
+$labels['spamreport0'] = 'Dołącz raport w nagłówku orginalnej wiadomości';
+$labels['spamreport1'] = 'Dołącz orginał jako MIME załącznik do raportu';
+$labels['spamreport2'] = 'Dołącz orginał jako załącznik textowy';
+$labels['spamaddressrules'] = 'Reguły Adresów';
+$labels['whitelist_from'] = 'Akceptuj wiadomości od';
+$labels['blacklist_from'] = 'Rejestruj wiadomości od';
+$labels['whitelist_to'] = 'Akceptuj wiadomości wysłane do';
+$labels['addrule'] = 'Dodaj regułe';
+$labels['rule'] = 'Reguła';
+$labels['importfromaddressbook'] = 'Importuj adresy z książki adresowej';
+$labels['deleteall'] = 'Usuń wszystko';
+$labels['autoscore'] = 'Automatycznie';
+$labels['defaultscore'] = 'Domyślny Wynik';
+$labels['otherscore'] = 'Inny (%s)';
+$labels['usedefault'] = 'Przywróć ustawienia domyślne';
+$labels['langoptions'] = 'Opcje Językowe';
+$labels['bayes'] = 'Ustawienia Bayes';
+$labels['purgingbayes'] = 'Usówanie danych Bayes';
+$labels['purgebayes'] = 'Usówanie osobistych danych Bayes';
+$labels['bayesautolearn'] = 'Użyj Bayes auto lern';
+$labels['bayesautooptions'] = 'Opcje automatycznej nauki';
+$labels['bayesnonspam'] = 'Próg nie spamu';
+$labels['bayesspam'] = 'Próg spamu';
+$labels['bayesrules'] = 'Użyj reguł Bayes';
+$labels['help'] = 'Pomoc';
+
+$messages = array();
+$messages['sauserprefchanged'] = 'Zmiany ustawień spamu zakończone sukcesem';
+$messages['sauserpreffailed'] = 'Error: Nie można zmienić ustawień spamu';
+$messages['spamthresexp'] = 'Wszystko powyżej progu jest oznaczone jako spam. Podnosząc ten próg wzrośnie ilość spamu nieodebranego, ale zmniejszy się ryzyko fałszywych alarmów.';
+$messages['spamlangexp'] = 'Wybierz wszystkie języki w jakich można oczekiwać, że otrzymasz wiadomości e-mail. Wszelkie wiadomości otrzymane, które są napisane w językach innych niż wybrane będą traktowane jako spam.';
+$messages['headersexp'] = 'SpamAssassin dodaje nagłówki przetworzonych wiadomości, dostarczające informacji o wynikach. Użyj poniższych opcji, aby skonfigurować te nagłówki.';
+$messages['spamtestssexp'] = 'Niektóre kontrole wykorzystania usług internetowych w celu identyfikowania spamu. Wybierz te, których chcesz używać:';
+$messages['spamreport'] = 'Gdy wiadomość jest klasyfikowana jako spam, tworzony jest raport z wszystkich testów.';
+$messages['autowhitelist'] = 'Adresy w Twojej książce adresowej są automatycznie dodawane do listy akceptowanych nadawców.';
+$messages['whitelistexp'] = 'Gwiazdka (*) zapewnia większą elastyczność. Na przykład: * @ example.com lub * @ *. example.com.';
+$messages['spamaddressexists'] = 'Reguła aktualnie istnieje dla tego adresu';
+$messages['spamenteraddress'] = 'Wpisz adres, który chcesz dodać';
+$messages['spamaddresserror'] = 'Error: Niewłąściwy adres';
+$messages['spamaddressdelete'] = 'Jesteś pewny(a) że chcesz usunąć tą regułe?';
+$messages['spamaddressdeleteall'] = 'Jestes pewny(a) że chcesz usunąć wszystkie reguły adresowe?';
+$messages['noaddressrules'] = 'Nie znaleziono reguły adresowej.';
+$messages['importingaddresses'] = 'Wczytywanie adresów...';
+$messages['usedefaultconfirm'] = 'Jesteś pewny(a) że chcesz przywrócić ustawienia domyślne? Usunie to wszystkie Twoje ustaawienia, łącznie z regułami adresacji.';
+$messages['purgebayesexp'] = 'Usuń osobiste dane Bayes zgromadzone z Twoich wiadomości';
+$messages['bayesnonspamexp'] = 'Wiadomości z wartością poniżej tego progu będą użyte do poprawienia systemowej detekcji nie-spamu.';
+$messages['bayesspamexp'] = 'Wiadomości z wartością powyżej tego progu będą użyte do poprawienia systemowej detekcji spamu.';
+$messages['bayesautohelp'] = 'Kiedy włączone jest auto-uczenie się filtra słownikowego Bayes, system automatycznie przetworzy wiadomość która prawdopodobnie jest spamem/nie spamem aby ulepszyć filtry skanujące.';
+$messages['bayeshelp'] = 'Klasyfikator Bayesa próbuje zidentyfikować spam patrząc na słowa lub krótkie sekwencje znaków, które są powszechnie spotykane w spamie lub wiadomościach niespamowych.';
+$messages['rblhelp'] = 'Znalezione adresy serwerów zamieszczonych w linkach w hipertekscie, będą sprawdzone z czarną listą serwerów i znanych źródeł spamu.';
+$messages['dcchelp'] = 'DCC inaczej Distributed Checksum Clearinghouse, to system serwerów zbierania i liczenia sum kontrolnych milionów wiadomości dziennie. Im większe podobieństwo kontrolne otrzymanej wiadomości jest na liście, tym bardziej prawdopodobne że jest to spam.';
+$messages['pyzhelp'] = 'Pyzor jest to sieciowym systemem wykrywania i blokowania spamu przy identyfikacji zarysu wiadomości. Zarysy są wytwarzane na wiele różnych sposobów, aby pozwolić na niewielkie różnice w treści wiadomości.';
+$messages['raz2help'] = 'Vipul\'s Razor to rozproszona, społecznościowa sieć wykrywająca i filtrująca spam na podstawie zgłoszeń użytkowników. Wykrywanie odbywa się na podstawie sygnatur którymi oznaczane są treści spamu. Znaczniki wiarygodności użytkowników pomagają uwiarygodniać zgłoszenia spamu.';
+$messages['raz1help'] = 'Vipul\'s Razor to rozproszona, społecznościowa sieć wykrywająca i filtrująca spam na podstawie zgłoszeń użytkowników. Wykrywanie odbywa się na podstawie sygnatur którymi oznaczane są treści spamu. Znaczniki wiarygodności użytkowników pomagają uwiarygodniać zgłoszenia spamu. Wersja 1 została zastąpiona przez wersję 2 i nie jest już wspierana.';
+$messages['levelhelp'] = 'Nagłówek \'Poziom Spamu\' może zostać dodany do wiadomości aby uwidocznić punktację jaka otrzymała wiadmość, Znacznik zostanie powtórzony tyle razy ile punktów otrzymała wiadomość. Może to być pomocne przy następnych przetwarzaniach wiadomości.';
+$messages['foldhelp'] = 'Czy zawijać nagłówki dodane przez SpamAssassina? Inaczej mówiąc czy mają być łamane w wielu liniach czy też pozostawione jako jedna długa linia. Kiedy linia jest dzielona zostaje oznaczona jako kontynuacja poprzedniej linii.';
+$messages['bayesruleshlp'] = 'Słownikowy filtr Bayesa przed efektywnym użyciem musi przejść proces "trenowania" aby poprawnie wykrywać spam/nie spam. Wyłączenie reguł filtra Bayesa pozwoli systemowi na "uczenie" się zarówno automatycznie jak i ręcznie z nadchodzących wiadomości, ale wyniki działania filtrów nie będą używane do wykrywania spamu.';
+$messages['purgebayesconfirm'] = 'Czy napewno usunąć wszystkie dane Bayes?';
+
+?> \ No newline at end of file
diff --git a/plugins/sauserprefs/localization/pt_BR.inc b/plugins/sauserprefs/localization/pt_BR.inc
new file mode 100644
index 000000000..f5eb14327
--- /dev/null
+++ b/plugins/sauserprefs/localization/pt_BR.inc
@@ -0,0 +1,85 @@
+<?php
+/* Author: Alexandre Correa */
+
+$labels = array();
+$labels['sauserprefs'] = 'Spam';
+$labels['sauserprefssettings'] = 'Configurações Spam';
+$labels['spamgeneralsettings'] = 'Configurações Gerais';
+$labels['spamthres'] = 'Pontuação Inicial';
+$labels['spamsubject'] = 'Marca do Assunto';
+$labels['spamsubjectblank'] = '(deixe em branco para nenhum)';
+$labels['spamlang'] = 'Linguagem das mensagens';
+$labels['enabled'] = 'Ligado';
+$labels['disabled'] = 'Desligado';
+$labels['headers'] = 'Cabeçalho';
+$labels['foldheaders'] = 'Permitir multiplas linhas no cabeçalho';
+$labels['spamlevelstars'] = 'Usar \'Nivel de Spam\' no cabeçalho';
+$labels['spamlevelchar'] = 'Marcador de nível';
+$labels['spamtests'] = 'Testes de spam ON-LINE';
+$labels['userazor1'] = 'Usar Lista Razor V1';
+$labels['userazor2'] = 'Usar Lista Razor V2';
+$labels['usepyzor'] = 'Usar Lista Pyzor';
+$labels['usebayes'] = 'Usar classificação \'Bayesian\'';
+$labels['usedcc'] = 'Usar DCC';
+$labels['skiprblchecks'] = 'Usar Lista-Negra em tempo real';
+$labels['spamreportsettings'] = 'Configurações de Notificação';
+$labels['spamreport0'] = 'Incluir notas nos cabeçalhos da mensagem original';
+$labels['spamreport1'] = 'Incluir mensagem como anexo MIME';
+$labels['spamreport2'] = 'Incluir mensagem como texto plano';
+$labels['spamaddressrules'] = 'Regras de Endereços';
+$labels['whitelist_from'] = 'Aceitar email de';
+$labels['blacklist_from'] = 'Rejeitar email de';
+$labels['whitelist_to'] = 'Aceitar email enviado para';
+$labels['addrule'] = 'Adicionar regra';
+$labels['rule'] = 'Regra';
+$labels['importfromaddressbook'] = 'Importar endereço do Livro de Endereços';
+$labels['deleteall'] = 'Apagar tudo';
+$labels['autoscore'] = 'Auto';
+$labels['defaultscore'] = 'Pontuação Padrão';
+$labels['otherscore'] = 'Outro (%s)';
+$labels['usedefault'] = 'Voltar configuração padrão';
+$labels['langoptions'] = 'Opções de linguagem';
+$labels['bayes'] = 'Configuração \'Bayes\'';
+$labels['purgingbayes'] = 'Apagar dados da \'Bayes\'';
+$labels['purgebayes'] = 'Apagar dados pessoais da \'Bayes\'';
+$labels['bayesautolearn'] = 'Usar auto-aprendizagem da \'Bayes\'';
+$labels['bayesautooptions'] = 'Opções de auto-aprendizagem';
+$labels['bayesnonspam'] = 'Pontuação de Não-Spam';
+$labels['bayesspam'] = 'Potuação de Spam';
+$labels['bayesrules'] = 'Usar regras \'Baysian\'';
+$labels['help'] = 'Ajuda';
+
+$messages = array();
+$messages['sauserprefchanged'] = 'Configurações de SPAM salvas';
+$messages['sauserpreffailed'] = 'Erro: Não foi possível alterar configurações de SPAM';
+$messages['spamthresexp'] = 'Qualquer valor acima da pontuação será marcado como SPAM. Aumentando a pontuação pode aumentar a quantidade de SPAM não detectado, mas evita que uma mensagem verdadeira seja marcada como SPAM.';
+$messages['spamlangexp'] = 'Selecione todos os idiomas que você espera receber mensagens. Qualquer mensagem recebida de idiomas não selecionados são marcadas como SPAM.';
+$messages['headersexp'] = 'SpamAssassin adiciona cabeçalhos nas mensagens processadas com informações sobre os resultados obtidos. Utilize as opções abaixo para configurar:';
+$messages['spamtestssexp'] = 'Algumas verificações fazem consultas on-line afim de ajudar a detectar SPAM. Selecione as opções que deseja utilizar:';
+$messages['spamreport'] = 'Quando uma mensagem é identificada como SPAM, uma notificação de todos os testes e pontuações obtidas é criada...';
+$messages['autowhitelist'] = 'Endereços de email cadastrados em sua agenda são automaticamente adicionados na lista de "Aceitar email de".';
+$messages['whitelistexp'] = 'Asterisco pode ser utilizado como curinga para uma maior flexibilidade. Exemplo: *@exemplo.com.br ou *@*.exemplo.com.br';
+$messages['spamaddressexists'] = 'Uma regra já existe para este endereço';
+$messages['spamenteraddress'] = 'Digite um endereço para adicionar';
+$messages['spamaddresserror'] = 'Erro: Endereço inválido';
+$messages['spamaddressdelete'] = 'Tem certeza que deseja excluir esta regra ?';
+$messages['spamaddressdeleteall'] = 'Tem certeza que deseja excluir TODAS as regras ?';
+$messages['noaddressrules'] = 'Regras de endereço não encontradas.';
+$messages['importingaddresses'] = 'Importando endereços...';
+$messages['usedefaultconfirm'] = 'Tem certeza que deseja restaurar para os padrões iniciais? Isto apaga todas as configurações, incluindo regras de endereços';
+$messages['purgebayesexp'] = 'Apagar configurações pessoais \'Bayes\' coletadas em seu email';
+$messages['bayesnonspamexp'] = 'Mensagens que tenham pontuação abaixo deste nível são utilizadas para aprimorar o sistema de detecção de menagens NÃO-SPAM.';
+$messages['bayesspamexp'] = 'Mensagens que tenham pontuação acima deste nível são utilizadas para aprimorar o sistema de detecção de mensagens SPAM.';
+$messages['bayesautohelp'] = 'Quando a auto-aprendizagem \'Bayes\' está ativada, o sistema utiliza as mensagens marcadas como SPAM/NÃO-SPAM para aprimorar o sistema de detecção.';
+$messages['bayeshelp'] = 'O sistema \'Bayes\' tenta identificar SPAM analisando as palavras ou textos curtos sequenciais que, em comum, são encontrados nas mensagems SPAM/NÃO-SPAM.';
+$messages['rblhelp'] = 'Endereço do servidor encontrado nos atalhos na mensagem são verificadas nas listas-negra ou listas de spam.';
+$messages['dcchelp'] = 'O DCC é um sistema composto por servidores que coletam e contabilizam as assinaturas digitais de milhões de mensagens. Estes contadores podem ser utilizados para detectar spam.';
+$messages['pyzhelp'] = 'Pyzor é um sistema colaborativo e interligado para detectar e bloquear mensagens identificadas pelo seu indice.';
+$messages['raz2help'] = '\'Vipuls Razor\' é um sistema baseado nas notificações feitas por vários usuários. A detecção é feita com base na assinatura digital da mensagem.';
+$messages['raz1help'] = '\'Vipuls Razor\' é um sistema baseado nas notificações feitas por vários usuários. A detecção é feita com base na assinatura digital da mensagem.';
+$messages['levelhelp'] = 'O cabeçalho \'Spam Level\' pode ser adicionado na mensagem repetindo o \'Marcado de nível\' de acordo com a pontuação obtida.';
+$messages['foldhelp'] = 'Por padrão, os cabeçalhos adicionados são separados por duplo espaço. Evitando uma linha muito longa, quebrando-a em várias linhas menores.';
+$messages['bayesruleshlp'] = 'Se usar as regras \'naive-Bayes-style\' como classificadores. Permite que desligue as regras mas, possibilitando deixar auto-aprendizagem automatica ou manual.';
+$messages['purgebayesconfirm'] = 'Tem certeza que deseja excluir os dados da \'Bayes\' ?';
+
+?> \ No newline at end of file
diff --git a/plugins/sauserprefs/localization/ro_RO.inc b/plugins/sauserprefs/localization/ro_RO.inc
new file mode 100644
index 000000000..dff15fd1f
--- /dev/null
+++ b/plugins/sauserprefs/localization/ro_RO.inc
@@ -0,0 +1,85 @@
+<?php
+/* Author: Ovidiu Bica */
+
+$labels = array();
+$labels['sauserprefs'] = 'Spam';
+$labels['sauserprefssettings'] = 'Setari spam';
+$labels['spamgeneralsettings'] = 'Setari generale';
+$labels['spamthres'] = 'Scor maxim';
+$labels['spamsubject'] = 'Cuvant cheie, ex. [SPAM]';
+$labels['spamsubjectblank'] = '(lasati gol pentru niciunul)';
+$labels['spamlang'] = 'Mesaje in limbile';
+$labels['enabled'] = 'Activat';
+$labels['disabled'] = 'Dezactivat';
+$labels['headers'] = 'Header mesaje';
+$labels['foldheaders'] = 'Permite linii multiple in header';
+$labels['spamlevelstars'] = 'Foloseste \'Nivel de spam\' in header';
+$labels['spamlevelchar'] = 'Caracter pentru nivel spam';
+$labels['spamtests'] = 'Teste spam de pe internet.';
+$labels['userazor1'] = 'Foloseste Razor v1';
+$labels['userazor2'] = 'Foloseste Razorv2';
+$labels['usepyzor'] = 'Foloseste Pyzor';
+$labels['usebayes'] = 'Foloseste stilul de clasificare Bayesian';
+$labels['usedcc'] = 'Foloseste DCC';
+$labels['skiprblchecks'] = 'Foloseste lista Blackhole in timp real';
+$labels['spamreportsettings'] = 'Setari raportari';
+$labels['spamreport0'] = 'Include raportul in headerul mesajului original';
+$labels['spamreport1'] = 'Include raportul original ca atasament MIME';
+$labels['spamreport2'] = 'Include raportul original ca atasament text';
+$labels['spamaddressrules'] = 'Reguli adrese';
+$labels['whitelist_from'] = 'Accepta mail de la';
+$labels['blacklist_from'] = 'Refuza mail de la';
+$labels['whitelist_to'] = 'Accepta mail trimis la';
+$labels['addrule'] = 'Adauga regula';
+$labels['rule'] = 'Regula';
+$labels['importfromaddressbook'] = 'Importa adresele din agenda';
+$labels['deleteall'] = 'Sterge tot';
+$labels['autoscore'] = 'Automat';
+$labels['defaultscore'] = 'Scor implicit';
+$labels['otherscore'] = 'Altele (%s)';
+$labels['usedefault'] = 'Restaureaza setarile implicite';
+$labels['langoptions'] = 'Optiuni lingvistice';
+$labels['bayes'] = 'Setari Bayes';
+$labels['purgingbayes'] = 'Sterg datele Bayesian';
+$labels['purgebayes'] = 'Sterg datele Bayesian personale';
+$labels['bayesautolearn'] = 'Foloseste instruirea automata a filtrului Bayes';
+$labels['bayesautooptions'] = 'Optiuni instruire automata';
+$labels['bayesnonspam'] = 'Prag limita non spam';
+$labels['bayesspam'] = 'Prag limita spam';
+$labels['bayesrules'] = 'Foloseste reguli Bayesian';
+$labels['help'] = 'Ajutor';
+
+$messages = array();
+$messages['sauserprefchanged'] = 'Setarile de SPAM au fost setate cu succes.';
+$messages['sauserpreffailed'] = 'Eroare: Nu pot actualiza setarile de spam.';
+$messages['spamthresexp'] = 'Orice mesaj mai mare de acest prag va fi marcat ca spam. Crescand acest prag va mari numarul de mesaje spam nedetectate insa va reduce numarul de mesaje interpretate gresit ca spam.';
+$messages['spamlangexp'] = 'Selecteaza toate limbile in care te astepti sa primesti mesaje. Orice mesaj receptionat intr-o alta limba va fi considerat spam.';
+$messages['headersexp'] = 'Spamassassin adauga headere la mesajele procesate furnizand informatii despre rezultate. Foloseste optiunile de mai jos pentru a configura aceste headere.';
+$messages['spamtestssexp'] = 'Unele verificari folosesc servicii de pe internet in vederea detectarii spamului. Selecteaza-le pe cele pe care doresti sa le folosesti.';
+$messages['spamreport'] = 'Cand un mesaj este identificat ca spam, este creat un raport al testelor si al scorurilor. ';
+$messages['autowhitelist'] = 'Adresele de email din agenda sunt adaugate automat in lista adreselor acceptate automat.';
+$messages['whitelistexp'] = 'O steluta (*) poate fi folosita ca inlocuitor global pentru o flexibilitate marita. De ex. *@exemplu.com sau *@*.exemplu.com';
+$messages['spamaddressexists'] = 'Exista deja o regula pentru aceasta adresa.';
+$messages['spamenteraddress'] = 'Te rog sa introduci o adresa pentru a o adauga.';
+$messages['spamaddresserror'] = 'Eroare: Adresa pare invalida.';
+$messages['spamaddressdelete'] = 'Esti sigur ca doresti sa stergi aceasta regula?';
+$messages['spamaddressdeleteall'] = 'Esti sigur ca doresti sa stergi toate regulile?';
+$messages['noaddressrules'] = 'Nu a fost gasita nici o regula.';
+$messages['importingaddresses'] = 'Import adresele ....';
+$messages['usedefaultconfirm'] = 'Esti sigur ca doresti sa revi la setarile initiale? Aceasta actiune va sterge toate setarile efectuate pana in prezent .';
+$messages['purgebayesexp'] = 'Sterge datele personale ale filtrului Bayesyan colectate de pe adresa ta.';
+$messages['bayesnonspamexp'] = 'mesajele care au un scor sub acest prag vor fi folosite pentru antrenarea filtrului non spam';
+$messages['bayesspamexp'] = 'Mesajele care au un scor peste acest prag vor fi folosite pentru detectarea mesajelor spam.';
+$messages['bayesautohelp'] = 'Atunci cand este activat filtrul Bayesian autodidact, acesta proceseaza automat mesajele care sunt foarte probabil spam/non spam si foloseste aceste informatii pentru a imbunatati filtrele de detectie.';
+$messages['bayeshelp'] = 'Filtrul Bayesian clasificator incearca sa identifice spam-ul uitandu-se la cuvinte sau secvente de caractere care sunt folosite frecvent in spam sau non spam.';
+$messages['rblhelp'] = 'Adresele web gasite in legaturile din mesaje vor fi verificate in cateva liste negre sau liste cu spamer cunoscuti deja.';
+$messages['dcchelp'] = 'The DCC or Distributed Checksum Clearinghouse is a system of servers collecting and counting checksums (or signatures) of millions of mail messages every day. The greater the similarity the checksum of an incoming message has to the list the more likely it is to be spam.';
+$messages['pyzhelp'] = 'Pyzor is a collaborative, networked system to detect and block spam using identifying digests of messages. The digests are generated in a number of different ways to allow for small differences in the content of the message.';
+$messages['raz2help'] = 'Vipul\'s Razor is a distributed, collaborative, spam detection and filtering network based on user submissions of spam. Detection is done with signatures that efficiently spot mutating spam content. The spam reports are validated through reputation assignments given to each reporter.';
+$messages['raz1help'] = 'ipul\'s Razor is a distributed, collaborative, spam detection and filtering network based on user submissions of spam. Detection is done with signatures that efficiently spot mutating spam content. The spam reports are validated through reputation assignments given to each reporter. Version 1 has now been replaced by version 2 and is no longer supported.';
+$messages['levelhelp'] = 'The \'Spam Level\' header can be added to a message to indicate the score given to a message by repeating the character specified that many times. This may be useful for further processing of the message.';
+$messages['foldhelp'] = 'Should headers added by SpamAssassin will be wrapped? In other words, should they be broken up into multiple lines instead of one very long one. When a line is broken it will be indented to mark it as a continuation of the preceding one.';
+$messages['bayesruleshlp'] = 'Before the Bayesian-style classifier can be used effectively it must be "trained" to properly detect spam/non spam messages. Disabling the Bayesian rules allows the system to continue to learn both automatically and manually from incoming mail but it will not be used to detect spam.';
+$messages['purgebayesconfirm'] = 'Esti sigur ca doresti sa stergi toate datele Bayesiane?';
+
+?> \ No newline at end of file
diff --git a/plugins/sauserprefs/localization/ru_RU.inc b/plugins/sauserprefs/localization/ru_RU.inc
new file mode 100644
index 000000000..3681836bb
--- /dev/null
+++ b/plugins/sauserprefs/localization/ru_RU.inc
@@ -0,0 +1,87 @@
+<?php
+/* Author: Sergey Khaliulov
+ Updates: Vladislav Bogdanov
+*/
+
+$labels = array();
+$labels['sauserprefs'] = 'Спам фильтр';
+$labels['sauserprefssettings'] = 'Настройки спам фильтра';
+$labels['spamgeneralsettings'] = 'Основные параметры';
+$labels['spamthres'] = 'Порог оценки';
+$labels['spamsubject'] = 'Метка спама в теме сообщения';
+$labels['spamsubjectblank'] = '(оставьте пустым, чтобы не менять тему сообщения)';
+$labels['spamlang'] = 'Языки сообщения';
+$labels['enabled'] = 'Включен';
+$labels['disabled'] = 'Отключен';
+$labels['headers'] = 'Заголовки сообщения';
+$labels['foldheaders'] = 'Разрешить многострочные записи в заголовках';
+$labels['spamlevelstars'] = 'Использовать заголовок \'Spam Level\'';
+$labels['spamlevelchar'] = 'Символ уровня спама';
+$labels['spamtests'] = 'Internet-проверки';
+$labels['userazor1'] = 'Использовать Razor v1';
+$labels['userazor2'] = 'Использовать Razor v2';
+$labels['usepyzor'] = 'Использовать Pyzor';
+$labels['usebayes'] = 'Включить "наивный" Байесовский классификатор';
+$labels['usedcc'] = 'Использовать DCC';
+$labels['skiprblchecks'] = 'Использовать Черные Списки адресов (RBL)';
+$labels['spamreportsettings'] = 'Параметры уведомления';
+$labels['spamreport0'] = 'Добавить отчет в заголовки оригинального сообщения';
+$labels['spamreport1'] = 'Добавить в отчет оригинал письма как MIME вложение';
+$labels['spamreport2'] = 'Добавить в отчет оригинал письма как текст';
+$labels['spamaddressrules'] = 'Фильтры по адресу';
+$labels['whitelist_from'] = 'Принимать письма от:';
+$labels['blacklist_from'] = 'Отбрасывать письма от:';
+$labels['whitelist_to'] = 'Принимать полученные для:';
+$labels['addrule'] = 'Добавить';
+$labels['rule'] = 'Правило';
+$labels['importfromaddressbook'] = 'Импортировать адреса из Адресной книги';
+$labels['deleteall'] = 'Удалить все';
+$labels['autoscore'] = 'Auto';
+$labels['defaultscore'] = 'По умолчанию';
+$labels['otherscore'] = 'Другой (%s)';
+$labels['usedefault'] = 'Восстановить настройки по умолчанию';
+$labels['langoptions'] = 'Языки';
+$labels['bayes'] = 'Байесовский фильтр';
+$labels['purgingbayes'] = 'Удаляется статистика Байесовского фильтра...';
+$labels['purgebayes'] = 'Удалить собранную статистику';
+$labels['bayesautolearn'] = 'Включить авто-обучение Байесовского фильтра';
+$labels['bayesautooptions'] = 'Параметры авто-обучения';
+$labels['bayesnonspam'] = 'Граница не-СПАМа';
+$labels['bayesspam'] = 'Граница СПАМа';
+$labels['bayesrules'] = 'Использовать Байесовский фильтр для оценки сообщений';
+$labels['help'] = 'Помощь';
+
+$messages = array();
+$messages['sauserprefchanged'] = 'Параметры фильтрации спама изменены';
+$messages['sauserpreffailed'] = 'Ошибка: Невозможно изменить параметры';
+$messages['spamthresexp'] = 'Система фильтрации спама использует числовые оценки для классификации сообщений. Используется большое количество тестов, каждый из которых возвращает определенное числовое значение при соответствии сообщения этому тесту. Результаты всех тестов суммируются для получения общей числовой оценки сообщения. При превышении полученной оценкой указанного порога - сообщение помечается как спам. Увеличение этого порога увеличит количество пропущенного спама, но и уменьшит риск ложных срабатываний. Общепринятым значением оценки, разделяющим СПАМ и не-СПАМ является число 5. Сообщения с оценкой более 8 практически в 100% случаев являются спамом.';
+$messages['spamlangexp'] = 'Любые полученные сообщения, которые написаны не на выбранном языке будут рассматриваться в качестве возможного спама.';
+$messages['headersexp'] = 'SpamAssassin добавляет в заголовки проверенных сообщений записи с информацией о результатах проверки. Укажите параметры добавляемых заголовков:';
+$messages['spamtestssexp'] = 'Некоторые алгоритмы проверки на спам используют интернет сервисы. Выберите те, которые Вы желаете использовать:';
+$messages['spamreport'] = 'Если сообщение идентифицировано как спам, сообщение должно быть сформировано следующим образом:';
+$messages['autowhitelist'] = 'Адреса электронной почты в Вашей Адресной книге могут быть автоматически добавлены к списку "Принимать письма от" (белый список).';
+$messages['whitelistexp'] = 'Звездочка (*) может использоваться как групповой символ для большей гибкости. Например: *@example.com или *@*.example.com. В общем случае не следует заносить много адресов в список "Отбрасывать письма от" (черный список), так как большинство адресов отправителей используются для рассылки спама только один раз. Этот список стоит использовать только в исключительных случаях, для блокирования писем от особо навязчивых нежелательных корреспондентов.';
+$messages['spamaddressexists'] = 'Правило уже существует для этого адреса';
+$messages['spamenteraddress'] = 'Введите адрес для добавления правила';
+$messages['spamaddresserror'] = 'Ошибка: Адрес указан неверно';
+$messages['spamaddressdelete'] = 'Вы дествительно хотите удалить это правило?';
+$messages['spamaddressdeleteall'] = 'Вы уверены что хотите удалить все правила фильтрации по адресу?';
+$messages['noaddressrules'] = 'Правил фильтрации по адресу не найдено.';
+$messages['importingaddresses'] = 'Импорт адресов...';
+$messages['usedefaultconfirm'] = 'Вы уверены, что Вы хотите восстановить настройки по умолчанию? Это удалит все Ваши настройки, включая правила проверки адреса.';
+$messages['purgebayesexp'] = 'Удалить все данные, собранные Байсовским фильтром из Ваших сообщений';
+$messages['bayesnonspamexp'] = 'Фильтр автоматически занесет сообщения, оценка которых НИЖЕ этого значения, в базу не-СПАМ сообщений.';
+$messages['bayesspamexp'] = 'Фильтр автоматически занесет сообщения, оценка которых ВЫШЕ этого значения, в базу СПАМ сообщений.';
+$messages['bayesautohelp'] = 'Позволяет автоматически заносить сообщения, с большой долей вероятности распознанные (при помощи других тестов) как СПАМ либо не-СПАМ, в соответствующие базы данных Байесовского фильтра.';
+$messages['bayeshelp'] = 'Байесовский фильтр (также известен как "наивный" Байесовский классификатор) - это обучаемая система, собирающая статистику вхождения слов либо коротких последовательностей символов в СПАМ и не-СПАМ сообщения. При большом объеме данных (более 200 достаточно свежих сообщений каждого типа) Байесовский фильтр позволяет достаточно точно классифицировать последующие сообщения как СПАМ либо не-СПАМ.';
+$messages['rblhelp'] = 'Адреса серверов, указанные в гипертекстовых ссылках, найденных в тексте сообщения, будут проверены в \'Черных Списках\', содержащих известные источники спама.';
+$messages['dcchelp'] = 'DCC (Distributed Checksum Clearinghouse, Распределенный Центр Контрольных сумм) - это система, подсчитывающая количество похожих сообщений, принятых пользователями Internet по всему миру. Ежедневно обрабатывается более 300 миллионов сообщений. Чем больше количество похожих друг на друга сообщений - тем больше вероятность, что это спам. Внимание: сообщения популярных списков рассылки могут быть распознаны как спам с точки зрения DCC. Поэтому рекомендуется отфильтровывать такие сообщения до Спам-фильтра (например при помощи SIEVE-фильтров или Procmail-фильтров, если они поддерживаются сервером).';
+$messages['pyzhelp'] = 'Pyzor is a collaborative, networked system to detect and block spam using identifying digests of messages.';
+$messages['raz2help'] = 'Серверы системы Razor хранят большое количество контрольных сумм сообщений, зарегистрированных как спам многочисленными пользователями системы. Очень малое количество ложных срабатываний обеспечивается механизмом "репутации" пользователя.';
+$messages['raz1help'] = 'Устаревшая и неподдерживаемая версия системы Razor. Используйте Razor v2.';
+$messages['levelhelp'] = 'The \'Spam Level\' header can be added to a message to indicate the score given to a message by repeating a character a certain number of times.';
+$messages['foldhelp'] = 'By default, headers added by SpamAssassin will be whitespace folded. In other words, they will be broken up into multiple lines instead of one very long one and each other line will have a tabulator prepended to mark it as a continuation of the preceding one.';
+$messages['bayesruleshlp'] = 'Позволяет использовать данные, собранные при помощи автоматического и ручного методов обучения Байесовского фильтра, для классификации последующих сообщений. Внимание: для классификации требуется большая предварительно собранная база (по 200 свежих сообщений каждого типа). В противном случае фильтр не работает даже если эта опция включена.';
+$messages['purgebayesconfirm'] = 'Вы уверены, что хотите удалить всю собранную статистику Байесовского фильтра?';
+
+?> \ No newline at end of file
diff --git a/plugins/sauserprefs/localization/sk_SK.inc b/plugins/sauserprefs/localization/sk_SK.inc
new file mode 100644
index 000000000..4cefe9928
--- /dev/null
+++ b/plugins/sauserprefs/localization/sk_SK.inc
@@ -0,0 +1,86 @@
+<?php
+/* Author: Michal Michalac */
+
+$labels = array();
+$labels['sauserprefs'] = 'Spam';
+$labels['sauserprefssettings'] = 'Nastavenia Spam-u';
+$labels['spamgeneralsettings'] = 'Všeobecné nastavenia';
+$labels['spamthres'] = 'Hranica skóre';
+$labels['spamsubject'] = 'Značka v predmete';
+$labels['spamsubjectblank'] = '(nechajte prázdne pre žiadnu)';
+$labels['spamlang'] = 'Jazyk správ';
+$labels['enabled'] = 'Povolený';
+$labels['disabled'] = 'Zakázaný';
+$labels['headers'] = 'Hlavičky správ';
+$labels['foldheaders'] = 'Povoliť viacriadkové hlavičky';
+$labels['spamlevelstars'] = 'Vytvárať hlavičku \'Spam Level\' (úroveň spamu)';
+$labels['spamlevelchar'] = 'Znak úrovne spamu';
+$labels['spamtests'] = 'Internetové spam testy';
+$labels['userazor1'] = 'Používať Razor v1';
+$labels['userazor2'] = 'Používať Razor v2';
+$labels['usepyzor'] = 'Používať Pyzor';
+$labels['usebayes'] = 'Používať Bayesovský klasifikátor';
+$labels['usedcc'] = 'Používať DCC';
+$labels['skiprblchecks'] = 'Používať RBL';
+$labels['spamreportsettings'] = 'Nastavenia reportu';
+$labels['spamreport0'] = 'Vkladať informácie len do hlavičiek pôvodného e-mailu';
+$labels['spamreport1'] = 'Vkladať pôvodný e-mail ako MIME prílohu reportu';
+$labels['spamreport2'] = 'Vkladať pôvodný e-mail ako textovú prílohu reportu';
+$labels['spamaddressrules'] = 'Pravidlá adries';
+$labels['whitelist_from'] = 'Prijímať e-maily od';
+$labels['blacklist_from'] = 'Odmietať e-maily od';
+$labels['whitelist_to'] = 'Prijímať e-maily zaslané komu';
+$labels['addrule'] = 'Pridať';
+$labels['rule'] = 'Pravidlo';
+$labels['importfromaddressbook'] = 'Importovať adresy z adresára';
+$labels['deleteall'] = 'Vymazať všetky';
+$labels['autoscore'] = 'Auto';
+$labels['defaultscore'] = 'Predvolená';
+$labels['otherscore'] = 'Iná (%s)';
+$labels['usedefault'] = 'Obnoviť predvolené nastavenia';
+$labels['langoptions'] = 'Jazykové voľby';
+$labels['bayes'] = 'Nastavenia Bayesu';
+$labels['purgingbayes'] = 'Vymazávam Bayesiánsku databázu...';
+$labels['purgebayes'] = 'Vymazať vlastnú Bayesiánsku databázu';
+$labels['bayesautolearn'] = 'Použiť automatické učenie Bayes';
+$labels['bayesautooptions'] = 'Voľby automatického učenia';
+$labels['bayesnonspam'] = 'Hranica pre nespam';
+$labels['bayesspam'] = 'Hranica pre spam';
+$labels['bayesrules'] = 'Využívať Baysiánske pravidlá';
+$labels['help'] = 'Pomoc';
+
+$messages = array();
+$messages['sauserprefchanged'] = 'Nastavenia spamu úspešne zmenené';
+$messages['sauserpreffailed'] = 'Chyba: Nastavenia spamu sa nepodarilo zmeniť';
+$messages['spamthresexp'] = "Všetky maily so skóre vyšším, ako určená hranica, budú označené ako spam.
+Zvýšením tejto hranice sa zväčší počet nerozpoznaných spamov, na druhej strane sa ale zníži počet mailov chybne označených ako spam.";
+$messages['spamlangexp'] = "Vyberte všetky jazyky v ktorých predpokladáte príjem e-mailov. Všetky prijaté správy napísané v iných jazykoch budú brané ako pravdepodobný spam.";
+$messages['headersexp'] = "SpamAssassin pridáva do kontrolovaných e-mailov hlavičky s infomráciami o výsledkoch kontroly. Použite nasledujúce voľby na ich prispôsobenie.";
+$messages['spamtestssexp'] = 'Niektoré testy pri detekcii spamu používajú externé služby na internete. Vyberte tie, ktoré chcete využívať:';
+$messages['spamreport'] = 'Keď je e-mail identifikovaný ako spam, vytvorí sa report o všetkých testoch a ich dosiahnutom skóre...';
+$messages['autowhitelist'] = 'Email addresses in your Address Book are automatically added to the \'Accept Mail From\' list.';
+$messages['whitelistexp'] = "V e-mailových adresách môže byť použitý zástupný znak hviezdička (*). Napr.: *@domena.sk or *@*.domena.sk.";
+$messages['spamaddressexists'] = 'Previdlo pre túto adresu už existuje';
+$messages['spamenteraddress'] = 'Prosím zadajte adresu, ktorú chcete pridať';
+$messages['spamaddresserror'] = 'Chyba: Adresa vyzará neplatná';
+$messages['spamaddressdelete'] = 'Ste si istí, že chcete naozaj vymazať toto pravidlo?';
+$messages['spamaddressdeleteall'] = 'Ste si istí, že chcete naozaj vymazať všetky pravidlá adries?';
+$messages['noaddressrules'] = 'Neboli nájdené žiadne pravidlá adries.';
+$messages['importingaddresses'] = 'Importujem adresy...';
+$messages['usedefaultconfirm'] = 'Ste si istí, že chcete naozaj obnoviť predvolené nastavenia? To vymaže všetky Vaše nastavenia, vrátane pravidiel adries.';
+$messages['purgebayesexp'] = 'Vymaže osobnú Bayesiánsku databázu vytvorenú z Vašich e-mailov';
+$messages['bayesnonspamexp'] = 'E-maily s nižším skóre ako uvedená hranica budú použité na zlepšenie detekcie (naučenie) nespamových správ.';
+$messages['bayesspamexp'] = 'E-maily s vyšším skóre ako uvedená hranica budú použité na zlepšenie detekcie (naučenie) spamových správ.';
+$messages['bayesautohelp'] = 'Keď je automatické učenie zapnuté, systém použije správy ktoré s veľkou istotou prehlási za spam/nespam na zlepšenie detekčných filtrov.';
+$messages['bayeshelp'] = 'Bayesovský klasifikátor sa snaží identifikovať spam podľa slov, alebo zhluku znakov, ktoré sa obvykle vyskytujú v spamových, alebo nespamových e-mailoch.';
+$messages['rblhelp'] = 'IP adresy serverov v hlavičkách, alebo v odkazoch v e-maili budú vyhľadané na niektorých blacklistoch. Blacklisty sú zoznamy známych adries spammerov, ktoré sa aktualizujú v reálnom čase.';
+$messages['dcchelp'] = 'DCC, alebo distribuované výmenné centrum kontrolných súčtov, je systém serverov zbierajúcich a vypočítavajúcich kontrolné súčty (či podpisy) miliónov e-mailov denne. Podľa podobnosti kontrolného súčtu príchodzej správy voči zoznamu evidovaných sa určuje pravdepodobnosť spamu.';
+$messages['pyzhelp'] = 'Pyzor je sieťový systém na detekciu a blokovanie spamu pomocou digestu správ. Digesty sa vypočítavajú niekoľkými spôsobmi tak, aby dokázali tolerovať malú zmenu v obsahu správy.';
+$messages['raz2help'] = 'Vipul\'s Razor je distribuovaná spolupracujúca sieť na detekciu a blokovanie spamu, pracujúca na základe užívateľmi zaslaných spamových vzoriek. Tieto vzorky sú zohľadňované podľa reputácie užívateľa, ktorý ich poskytol. Detekcia sa robí pomocou charakteristík, ktoré efektívne zachytávajú aj meniaci sa obsah spamu.';
+$messages['raz1help'] = 'Vipul\'s Razor je distribuovaná spolupracujúca sieť na detekciu a blokovanie spamu, pracujúca na základe užívateľmi zaslaných spamových vzoriek. Tieto vzorky sú zohľadňované podľa reputácie užívateľa, ktorý ich poskytol. Detekcia sa robí pomocou charakteristík, ktoré efektívne zachytávajú aj meniaci sa obsah spamu. Verzia 1 bola nahradená verziou 2 a nie je už naďalej podporovaná.';
+$messages['levelhelp'] = 'Hlavička \'Spam Level\' zobrazuje opakovaním znaku (napr. hviezdičky) skóre, ktoré kontrolovaný e-mail získal. To môže byť užitočné pri ďalšom spracovaní e-mailu.';
+$messages['foldhelp'] = 'Môžu byť hlavičky pridané do e-mailu SpamAssassinom rozdelené na viac riadkov, namiesto toho, aby boli na jednom veľmi dlhom riadku? Keď je riadok rozdelený, jeho pokračovanie je označené odsadením.';
+$messages['bayesruleshlp'] = 'Predtým, ako môže byt Bayesovský klasifikátor efektívne použitý, musí sa natrénovať správne rozoznávať spam od nespamu. Vypnutím Bayesiánskych pravidiel umožníte systému učiť sa z prichádzajúcich e-mailov, ale nebude sa používať na detekciu spamu..';
+$messages['purgebayesconfirm'] = 'Ste si istí, že chcete naozaj vymazať celú Vašu Bayesiánsku databázu?';
+
+?> \ No newline at end of file
diff --git a/plugins/sauserprefs/localization/sv_SE.inc b/plugins/sauserprefs/localization/sv_SE.inc
new file mode 100644
index 000000000..029ee86a5
--- /dev/null
+++ b/plugins/sauserprefs/localization/sv_SE.inc
@@ -0,0 +1,84 @@
+<?php
+/* Author: Reino Wallin */
+
+$labels = array();
+$labels['sauserprefs'] = 'Skräppost';
+$labels['sauserprefssettings'] = 'Inställningar för skräppost';
+$labels['spamgeneralsettings'] = 'Allmänna inställningar';
+$labels['spamthres'] = 'Tröskelvärde';
+$labels['spamsubject'] = 'Rubrikmärkning';
+$labels['spamsubjectblank'] = '(lämna tom om du inte vill lägga till någon text till rubriken)';
+$labels['spamlang'] = 'Brevets språk';
+$labels['enabled'] = 'Aktiverad';
+$labels['disabled'] = 'Ej aktiverad';
+$labels['headers'] = 'Brevhuvud';
+$labels['foldheaders'] = 'Tillåt flera rader i brevhuvudet';
+$labels['spamlevelstars'] = 'Använd \'Spam Level\' i brevhuvudet';
+$labels['spamlevelchar'] = 'Tecken för \'Spam Level\'';
+$labels['spamtests'] = 'Internetbaserade tester av skräppost';
+$labels['userazor1'] = 'Använd Razor v1';
+$labels['userazor2'] = 'Använd Razor v2';
+$labels['usepyzor'] = 'Använd Pyzor';
+$labels['usebayes'] = 'Använd bayesklassificering';
+$labels['usedcc'] = 'Använd DCC';
+$labels['skiprblchecks'] = 'Använd svartlistor i realtid';
+$labels['spamreportsettings'] = 'Rapportinställningar';
+$labels['spamreport0'] = 'Lägg till rapporten till originalbrevets brevhuvud';
+$labels['spamreport1'] = 'Sänd rapporten med originalbrevet som en MIME-bilaga';
+$labels['spamreport2'] = 'Sänd rapporten med originalbrevet som en text-bilaga';
+$labels['spamaddressrules'] = 'Adressregler';
+$labels['whitelist_from'] = 'Acceptera brev från';
+$labels['blacklist_from'] = 'Avvisa brev från';
+$labels['whitelist_to'] = 'Acceptera brev till';
+$labels['addrule'] = 'Lägg till';
+$labels['rule'] = 'Regel';
+$labels['importfromaddressbook'] = 'Importera adresser från adressboken';
+$labels['deleteall'] = 'Radera alla';
+$labels['autoscore'] = 'Auto';
+$labels['defaultscore'] = 'Använd grundinställningar';
+$labels['otherscore'] = 'Annan (%s)';
+$labels['usedefault'] = 'Återställ grundinställningar';
+$labels['langoptions'] = 'Språkinställningar';
+$labels['bayes'] = 'Bayesinställningar';
+$labels['purgingbayes'] = 'Raderar bayesdata...';
+$labels['purgebayes'] = 'Radera personliga bayesdata';
+$labels['bayesautolearn'] = 'Använd bayesinlärning';
+$labels['bayesautooptions'] = 'Inställningar för inlärning';
+$labels['bayesnonspam'] = 'Tröskelvärde för vanliga brev';
+$labels['bayesspam'] = 'Tröskelvärde för skräppost';
+$labels['bayesrules'] = 'Använd bayesregler';
+$labels['help'] = 'Hjälp';
+
+$messages = array();
+$messages['sauserprefchanged'] = 'Dina inställningar för skräppost har sparats';
+$messages['sauserpreffailed'] = 'Fel: Det går inte att spara dina inställningar för skräppost';
+$messages['spamthresexp'] = 'Alla brev som vid granskningen av SpamAssassin får ett värde som överstiger tröskelvärdet för skräppost blir märkta som skräppost. Ökar man tröskelvärdet innebär det att viss skräppost inte blir märkt som skräppost, men man reducerar också risken att vanliga brev blir märkta som skräppost.';
+$messages['spamlangexp'] = 'Välj de språk du förväntar dig att mottagna brev är skrivna på. Brev som är skrivna på andra språk än de du inte valt kommer att bli betrakade som möjlig skräppost';
+$messages['headersexp'] = 'SpamAssassin lägger till information i brevhuvudet på brev som granskats av SpamAssassin. Informationen beskriver resultatet av granskningen. Använd inställningarna nedan för att konfigurera dessa brevhuvuden.';
+$messages['spamtestssexp'] = 'Vissa kontroller som SpamAssassin utför för att karaktärisera ett brev, baseras på tjänster på Internet. Välj de tjänster du önskar använda dig av:';
+$messages['spamreport'] = 'När ett brev karaktäriseras som skräppost skapas en rapport med alla resulten från granskningen som SpamAssassin gör...';
+$messages['autowhitelist'] = 'Lägg per automatik till adresserna i din adressbok till \'Acceptera brev från\' listan.';
+$messages['whitelistexp'] = 'Du kan använda en asterisk (*) för att skapa ett mer flexibelt regelverk, exempelvis: *@example.com eller *@*.example.com.';
+$messages['spamaddressexists'] = 'En regel finns redan för denna adressen';
+$messages['spamenteraddress'] = 'Ange en adress att lägga till';
+$messages['spamaddresserror'] = 'Fel: Ogiltlig adress';
+$messages['spamaddressdelete'] = 'Är du säker på att du vill radera denna adressregel?';
+$messages['spamaddressdeleteall'] = 'Är du säker på att du vill radera alla adressregler?';
+$messages['noaddressrules'] = 'Det existerar inga adressregler.';
+$messages['importingaddresses'] = 'Importerar adresser...';
+$messages['usedefaultconfirm'] = 'Är du säker på att du vill återställa grundinställninganra? Om så sker raderar du dina nuvarande inställningar, som exempelvis dina adressregler.';
+$messages['purgebayesexp'] = 'Radera personliga bayesdata som samlats in från dina brev';
+$messages['bayesnonspamexp'] = 'Brev som erhåller ett skräppostvärde under detta tröskelvärde kommer att användas för att förbättra skräppostsystemets förmåga att identifiera brev som inte är skräppost.';
+$messages['bayesspamexp'] = 'Brev som erhåller ett skräppostvärde över detta tröskelvärde kommer att användas för att förbättra skräppostsystemets förmåga att identifiera skräppost.';
+$messages['bayesautohelp'] = 'Om bayesinlärning är aktiverat kommer skräppostsystemet att vid granskningen av brev, som med stor sannolikhet är spräppost eller med stor sannolikhet är vanliga brev, att automatiskt uppdatera sin databas och förbättra sin förmåga att detektera skräppost. Brev som är mer svårbedömda kommer inte att användas vid inlärningen';
+$messages['bayeshelp'] = 'Vid klassificering av brev baserat på Bayes försöker man identifiera spräppost med hjälp av ord, eller korta bokstavssekvenser, som är vanligt förekommande i vanliga brev respektive skräppost.';
+$messages['rblhelp'] = 'Serveradresser som finns i länkar infogade i brev kommer att kontrolleras mot ett flertal \'svartlistor\' och listor över välkända källor för skräppost.';
+$messages['dcchelp'] = 'DCC (Distributed Checksum Clearinghouse) är en internettjänst baserad på ett antal sevrar som dagligen samlar in och beräknar checksumman för miljontals brev. Checksumman för inkommande brev jämförs med data i databasen och desto större likhet som råder desto större sannolikhet är det att brevet är att betrakta som skräppost.';
+$messages['pyzhelp'] = 'Pyzor är en distribuerad internettjänst för att detektera skräppost. Den baseras på att man beräknar en checksumma av brevet som kontrolleras mot nätverksbaserade databaser för att se om andra har klassificerat brevtexten som skräppost.';
+$messages['raz2help'] = 'Vipul\'s Razor är en distribuerad internettjänst för att detektera skräppost. Den baseras på att man beräknar en checksumma av brevet som kontrolleras mot nätverksbaserade databaser för att se om andra har klassificerat brevtexten som skräppost. Razor är effektivt även när det gäller så kallade muterade brevtexter.';
+$messages['levelhelp'] = 'Brevhuvudet benämnt \'Spam Level\', som visar hur brevet klassificerats, kan läggas till breven och underlätta för vidare behandling.';
+$messages['foldhelp'] = 'Skall de brevhuvud som SpamAssassin lägger till brevet struktureras som en lång rad eller ett flertal separata brevhuvud.';
+$messages['bayesruleshlp'] = 'Innan bayesklassificering kan göras effektivt måste en inlärning av vad som är spräppost respektive vanliga brev ske. Om man inte väljer att använda bayesklassificering kommer skräppostsystemet att öka sin förmåga att detektera skräppost genom både manuellt och automatiskt inlärning, men klassificering kommer inte att ske.';
+$messages['purgebayesconfirm'] = 'Är du säker på att du vill radera alla dina bayesdata?';
+
+?> \ No newline at end of file
diff --git a/plugins/sauserprefs/package.xml b/plugins/sauserprefs/package.xml
new file mode 100644
index 000000000..e6845a1dc
--- /dev/null
+++ b/plugins/sauserprefs/package.xml
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<package xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" packagerversion="1.9.0" version="2.0" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0
+ http://pear.php.net/dtd/tasks-1.0.xsd
+ http://pear.php.net/dtd/package-2.0
+ http://pear.php.net/dtd/package-2.0.xsd">
+ <name>sauserprefs</name>
+ <uri>http://github.com/JohnDoh/Roundcube-Plugin-SpamAssassin-User-Prefs-SQL/</uri>
+ <summary>Control SpamAssassin settings from within Roundcube</summary>
+ <description>Adds a 'Spam' tab to the 'Personal Settings' to allow the user to change their SpamAssassin preferences. Preferences must be stored in a SQL database. Default preferences are used when no user preference is found.</description>
+ <lead>
+ <name>Philip Weir</name>
+ <user>JohnDoh</user>
+ <email>roundcube@tehinterweb.co.uk</email>
+ <active>yes</active>
+ </lead>
+ <date>2013-02-24</date>
+ <time>10:16:53</time>
+ <version>
+ <release>1.10</release>
+ <api>1.10</api>
+ </version>
+ <stability>
+ <release>stable</release>
+ <api>stable</api>
+ </stability>
+ <license uri="http://www.gnu.org/licenses/gpl.html">GNU GPLv3+</license>
+ <notes>-</notes>
+ <contents>
+ <dir baseinstalldir="/" name="/">
+ <file name="sauserprefs.php" role="php">
+ <tasks:replace from="@name@" to="name" type="package-info"/>
+ <tasks:replace from="@package_version@" to="version" type="package-info"/>
+ </file>
+ <file name="sauserprefs.js" role="data">
+ <tasks:replace from="@name@" to="name" type="package-info"/>
+ <tasks:replace from="@package_version@" to="version" type="package-info"/>
+ </file>
+ <file name="config.inc.php.dist" role="data"/>
+ <file name="CHANGELOG" role="data"/>
+ <file name="README.md" role="data"/>
+ <file name="include/rcube_sauserprefs_storage.php" role="php"/>
+ <file name="localization/cs_CZ.inc" role="data"/>
+ <file name="localization/de_CH.inc" role="data"/>
+ <file name="localization/de_DE.inc" role="data"/>
+ <file name="localization/en_GB.inc" role="data"/>
+ <file name="localization/en_US.inc" role="data"/>
+ <file name="localization/es_ES.inc" role="data"/>
+ <file name="localization/fr_FR.inc" role="data"/>
+ <file name="localization/gl_ES.inc" role="data"/>
+ <file name="localization/hu_HU.inc" role="data"/>
+ <file name="localization/it_IT.inc" role="data"/>
+ <file name="localization/pl_PL.inc" role="data"/>
+ <file name="localization/pt_BR.inc" role="data"/>
+ <file name="localization/ro_RO.inc" role="data"/>
+ <file name="localization/ru_RU.inc" role="data"/>
+ <file name="localization/sk_SK.inc" role="data"/>
+ <file name="localization/sv_SE.inc" role="data"/>
+ <file name="skins/classic/help.gif" role="data"/>
+ <file name="skins/classic/icons.gif" role="data"/>
+ <file name="skins/classic/icons.png" role="data"/>
+ <file name="skins/classic/ie6hacks.css" role="data"/>
+ <file name="skins/classic/iehacks.css" role="data"/>
+ <file name="skins/classic/safari.css" role="data"/>
+ <file name="skins/classic/sauserprefs.css" role="data"/>
+ <file name="skins/classic/tabstyles.css" role="data"/>
+ <file name="skins/classic/templates/sauserprefs.html" role="data"/>
+ <file name="skins/classic/templates/settingsedit.html" role="data"/>
+ <file name="skins/larry/help.png" role="data"/>
+ <file name="skins/larry/icons.png" role="data"/>
+ <file name="skins/larry/iehacks.css" role="data"/>
+ <file name="skins/larry/listicons.png" role="data"/>
+ <file name="skins/larry/safari.css" role="data"/>
+ <file name="skins/larry/sauserprefs.css" role="data"/>
+ <file name="skins/larry/tabstyles.css" role="data"/>
+ <file name="skins/larry/templates/sauserprefs.html" role="data"/>
+ <file name="skins/larry/templates/settingsedit.html" role="data"/>
+ </dir>
+ <!-- / -->
+ </contents>
+ <dependencies>
+ <required>
+ <php>
+ <min>5.2.1</min>
+ </php>
+ <pearinstaller>
+ <min>1.7.0</min>
+ </pearinstaller>
+ </required>
+ </dependencies>
+ <phprelease/>
+</package>
diff --git a/plugins/sauserprefs/sauserprefs.js b/plugins/sauserprefs/sauserprefs.js
new file mode 100644
index 000000000..3b965566f
--- /dev/null
+++ b/plugins/sauserprefs/sauserprefs.js
@@ -0,0 +1,459 @@
+/**
+ * SAUserPrefs plugin script
+ */
+
+rcube_webmail.prototype.sauserprefs_toggle_level_char = function(checkbox) {
+ var level_char;
+
+ if (level_char = rcube_find_object('rcmfd_spamlevelchar'))
+ level_char.disabled = !checkbox.checked;
+}
+
+rcube_webmail.prototype.sauserprefs_toggle_bayes = function(checkbox) {
+ var tickbox;
+ var dropdown;
+
+ if (tickbox = rcube_find_object('rcmfd_spambayesrules'))
+ tickbox.disabled = !checkbox.checked;
+
+ if (tickbox = rcube_find_object('rcmfd_spambayesautolearn'))
+ tickbox.disabled = !checkbox.checked;
+
+ if ((dropdown = rcube_find_object('rcmfd_bayesnonspam')) && (tickbox.checked || !checkbox.checked))
+ dropdown.disabled = !checkbox.checked;
+
+ if ((dropdown = rcube_find_object('rcmfd_bayesspam')) && (tickbox.checked || !checkbox.checked))
+ dropdown.disabled = !checkbox.checked;
+}
+
+rcube_webmail.prototype.sauserprefs_toggle_bayes_auto = function(checkbox) {
+ var dropdown;
+
+ if (dropdown = rcube_find_object('rcmfd_bayesnonspam'))
+ dropdown.disabled = !checkbox.checked;
+
+ if (dropdown = rcube_find_object('rcmfd_bayesspam'))
+ dropdown.disabled = !checkbox.checked;
+}
+
+rcube_webmail.prototype.sauserprefs_addressrule_import = function(address) {
+ parent.rcmail.set_busy(false, null, rcmail.env.sauserprefs_whitelist);
+
+ var adrTable = rcube_find_object('address-rules-table').tBodies[0];
+
+ var actions = document.getElementsByName('_address_rule_act[]');
+ var prefs = document.getElementsByName('_address_rule_field[]');
+ var addresses = document.getElementsByName('_address_rule_value[]');
+ var insHere;
+
+ for (var i = 1; i < addresses.length; i++) {
+ if (addresses[i].value == address && actions[i].value != "DELETE") {
+ return false;
+ }
+ else if (addresses[i].value > address) {
+ insHere = adrTable.rows[i + 1];
+ break;
+ }
+ }
+
+ var newNode = adrTable.rows[0].cloneNode(true);
+ adrTable.rows[1].style.display = 'none';
+
+ if (insHere)
+ adrTable.insertBefore(newNode, insHere);
+ else
+ adrTable.appendChild(newNode);
+
+ newNode.style.display = "";
+ newNode.cells[0].className = "whitelist_from";
+ newNode.cells[0].innerHTML = rcmail.gettext('whitelist_from','sauserprefs');
+ newNode.cells[1].innerHTML = address;
+ actions[newNode.rowIndex - 2].value = "INSERT";
+ prefs[newNode.rowIndex - 2].value = "whitelist_from";
+ addresses[newNode.rowIndex - 2].value = address;
+
+ rcmail.env.address_rule_count++;
+}
+
+rcube_webmail.prototype.sauserprefs_help = function(sel) {
+ var help = rcube_find_object(sel);
+ help.style.display = (help.style.display == 'none' ? '' : 'none');
+ return false;
+}
+
+$(document).ready(function() {
+ if (window.rcmail) {
+ rcmail.addEventListener('init', function(evt) {
+ var tab = $('<span>').attr('id', 'settingstabpluginsauserprefs').addClass('tablink');
+ var button = $('<a>').attr('href', rcmail.env.comm_path+'&_action=plugin.sauserprefs').attr('title', rcmail.gettext('managespam', 'sauserprefs')).html(rcmail.gettext('sauserprefs','sauserprefs')).appendTo(tab);
+
+ // add button and register command
+ rcmail.add_element(tab, 'tabs');
+
+ if (rcmail.env.action == 'plugin.sauserprefs.edit') {
+ rcmail.register_command('plugin.sauserprefs.select_all_langs', function() {
+ var langlist = document.getElementsByName('_spamlang[]');
+ var obj;
+
+ for (var i = 0; i < langlist.length; i++) {
+ langlist[i].checked = true;
+ obj = rcube_find_object('spam_lang_'+ i);
+ obj.title = rcmail.gettext('enabled','sauserprefs');
+ obj.className = 'enabled';
+ }
+
+ return false;
+ }, true);
+
+ rcmail.register_command('plugin.sauserprefs.select_invert_langs', function() {
+ var langlist = document.getElementsByName('_spamlang[]');
+ var obj;
+
+ for (var i = 0; i < langlist.length; i++) {
+ if (langlist[i].checked) {
+ langlist[i].checked = false;
+ obj = rcube_find_object('spam_lang_'+ i);
+ obj.title = rcmail.gettext('disabled','sauserprefs');
+ obj.className = 'disabled';
+ }
+ else {
+ langlist[i].checked = true;
+ obj = rcube_find_object('spam_lang_'+ i);
+ obj.title = rcmail.gettext('enabled','sauserprefs');
+ obj.className = 'enabled';
+ }
+ }
+
+ return false;
+ }, true);
+
+ rcmail.register_command('plugin.sauserprefs.select_no_langs', function() {
+ var langlist = document.getElementsByName('_spamlang[]');
+ var obj;
+
+ for (var i = 0; i < langlist.length; i++) {
+ langlist[i].checked = false;
+ obj = rcube_find_object('spam_lang_'+ i);
+ obj.title = rcmail.gettext('disabled','sauserprefs');
+ obj.className = 'disabled';
+ }
+
+ return false;
+ }, true);
+
+ rcmail.register_command('plugin.sauserprefs.message_lang', function(lang_code, obj) {
+ var langlist = document.getElementsByName('_spamlang[]');
+ var i = obj.parentNode.parentNode.rowIndex - 1;
+
+ if (langlist[i].checked) {
+ langlist[i].checked = false;
+ obj.title = rcmail.gettext('disabled','sauserprefs');
+ obj.className = 'disabled';
+ }
+ else {
+ langlist[i].checked = true;
+ obj.title = rcmail.gettext('enabled','sauserprefs');
+ obj.className = 'enabled';
+ }
+
+ return false;
+ }, true);
+
+ rcmail.register_command('plugin.sauserprefs.addressrule_del', function(props, obj) {
+ var adrTable = rcube_find_object('address-rules-table').tBodies[0];
+ var rowidx = obj.parentNode.parentNode.rowIndex - 1;
+ var fieldidx = rowidx - 1;
+
+ if (!confirm(rcmail.gettext('spamaddressdelete','sauserprefs')))
+ return false;
+
+ if (document.getElementsByName('_address_rule_act[]')[fieldidx].value == "INSERT") {
+ adrTable.deleteRow(rowidx);
+ }
+ else {
+ adrTable.rows[rowidx].style.display = 'none';
+ document.getElementsByName('_address_rule_act[]')[fieldidx].value = "DELETE";
+ }
+
+ rcmail.env.address_rule_count--;
+ if (rcmail.env.address_rule_count < 1)
+ adrTable.rows[1].style.display = '';
+
+ return false;
+ }, true);
+
+ rcmail.register_command('plugin.sauserprefs.addressrule_add', function() {
+ var adrTable = rcube_find_object('address-rules-table').tBodies[0];
+ var input_spamaddressrule = rcube_find_object('_spamaddressrule');
+ var selrule = input_spamaddressrule.selectedIndex;
+ var input_spamaddress = rcube_find_object('_spamaddress');
+
+ if (input_spamaddress.value.replace(/^\s+|\s+$/g, '') == '') {
+ alert(rcmail.gettext('spamenteraddress','sauserprefs'));
+ input_spamaddress.focus();
+ return false;
+ }
+ else if (!rcube_check_email(input_spamaddress.value.replace(/^\s+/, '').replace(/[\s,;]+$/, ''), true)) {
+ alert(rcmail.gettext('spamaddresserror','sauserprefs'));
+ input_spamaddress.focus();
+ return false;
+ }
+ else {
+ var actions = document.getElementsByName('_address_rule_act[]');
+ var prefs = document.getElementsByName('_address_rule_field[]');
+ var addresses = document.getElementsByName('_address_rule_value[]');
+ var insHere;
+
+ for (var i = 1; i < addresses.length; i++) {
+ if (addresses[i].value == input_spamaddress.value && actions[i].value != "DELETE") {
+ alert(rcmail.gettext('spamaddressexists','sauserprefs'));
+ input_spamaddress.focus();
+ return false;
+ }
+ else if (addresses[i].value > input_spamaddress.value) {
+ insHere = adrTable.rows[i + 1];
+ break;
+ }
+ }
+
+ var newNode = adrTable.rows[0].cloneNode(true);
+ adrTable.rows[1].style.display = 'none';
+
+ if (insHere)
+ adrTable.insertBefore(newNode, insHere);
+ else
+ adrTable.appendChild(newNode);
+
+ newNode.style.display = "";
+ newNode.cells[0].className = input_spamaddressrule.options[selrule].value;
+ newNode.cells[0].innerHTML = input_spamaddressrule.options[selrule].text;
+ newNode.cells[1].innerHTML = input_spamaddress.value;
+ actions[newNode.rowIndex - 2].value = "INSERT";
+ prefs[newNode.rowIndex - 2].value = input_spamaddressrule.options[selrule].value;
+ addresses[newNode.rowIndex - 2].value = input_spamaddress.value;
+
+ input_spamaddressrule.selectedIndex = 0;
+ input_spamaddress.value = '';
+
+ rcmail.env.address_rule_count++;
+ }
+ }, true);
+
+ rcmail.register_command('plugin.sauserprefs.whitelist_delete_all', function(props, obj) {
+ var adrTable = rcube_find_object('address-rules-table').tBodies[0];
+
+ if (!confirm(rcmail.gettext('spamaddressdeleteall','sauserprefs')))
+ return false;
+
+ for (var i = adrTable.rows.length - 1; i > 1; i--) {
+ if (document.getElementsByName('_address_rule_act[]')[i-1].value == "INSERT") {
+ adrTable.deleteRow(i);
+ rcmail.env.address_rule_count--;
+ }
+ else if (document.getElementsByName('_address_rule_act[]')[i-1].value != "DELETE") {
+ adrTable.rows[i].style.display = 'none';
+ document.getElementsByName('_address_rule_act[]')[i-1].value = "DELETE";
+ rcmail.env.address_rule_count--;
+ }
+ }
+
+ adrTable.rows[1].style.display = '';
+ return false;
+ }, true);
+
+ rcmail.register_command('plugin.sauserprefs.import_whitelist', function(props, obj) {
+ rcmail.env.sauserprefs_whitelist = rcmail.set_busy(true, 'sauserprefs.importingaddresses');
+ rcmail.http_request('plugin.sauserprefs.whitelist_import', '', rcmail.env.sauserprefs_whitelist);
+ return false;
+ }, true);
+
+ rcmail.register_command('plugin.sauserprefs.purge_bayes', function(props, obj) {
+ if (confirm(rcmail.gettext('purgebayesconfirm','sauserprefs'))) {
+ var lock = rcmail.set_busy(true, 'sauserprefs.purgingbayes');
+ rcmail.http_request('plugin.sauserprefs.purge_bayes', '', lock);
+ }
+
+ return false;
+ }, true);
+
+ rcmail.register_command('plugin.sauserprefs.save', function() { rcmail.gui_objects.editform.submit(); }, true);
+
+ rcmail.register_command('plugin.sauserprefs.default', function() {
+ if (confirm(rcmail.gettext('usedefaultconfirm','sauserprefs'))) {
+ // Score
+ if (rcube_find_object('rcmfd_spamthres'))
+ rcube_find_object('rcmfd_spamthres').selectedIndex = 0;
+
+ // Subject tag
+ if (rcube_find_object('rcmfd_spamsubject'))
+ rcube_find_object('rcmfd_spamsubject').value = rcmail.env.rewrite_header_Subject
+
+ // Languages
+ var langlist = document.getElementsByName('_spamlang[]');
+ var obj;
+ var dlangs = " " + rcmail.env.ok_languages + " ";
+
+ for (var i = 0; i < langlist.length; i++) {
+ langlist[i].checked = false;
+ obj = rcube_find_object('spam_lang_' + i);
+ obj.title = rcmail.gettext('disabled','sauserprefs');
+ obj.className = 'disabled';
+
+ if (dlangs.indexOf(" " + langlist[i].value + " ") > -1) {
+ langlist[i].checked = true;
+ obj = rcube_find_object('spam_lang_' + i);
+ obj.title = rcmail.gettext('enabled','sauserprefs');
+ obj.className = 'enabled';
+ }
+ }
+
+ // Tests
+ if (rcube_find_object('rcmfd_spamuserazor1')) {
+ if (rcmail.env.use_razor1 == '1')
+ rcube_find_object('rcmfd_spamuserazor1').checked = true;
+ else
+ rcube_find_object('rcmfd_spamuserazor1').checked = false;
+ }
+
+ if (rcube_find_object('rcmfd_spamuserazor2')) {
+ if (rcmail.env.use_razor2 == '1')
+ rcube_find_object('rcmfd_spamuserazor2').checked = true;
+ else
+ rcube_find_object('rcmfd_spamuserazor2').checked = false;
+ }
+
+ if (rcube_find_object('rcmfd_spamusepyzor')) {
+ if (rcmail.env.use_pyzor == '1')
+ rcube_find_object('rcmfd_spamusepyzor').checked = true;
+ else
+ rcube_find_object('rcmfd_spamusepyzor').checked = false;
+ }
+
+ if (rcube_find_object('rcmfd_spamusedcc')) {
+ if (rcmail.env.use_dcc == '1')
+ rcube_find_object('rcmfd_spamusedcc').checked = true;
+ else
+ rcube_find_object('rcmfd_spamusedcc').checked = false;
+ }
+
+ if (rcube_find_object('rcmfd_spamskiprblchecks')) {
+ if (rcmail.env.skip_rbl_checks == '1')
+ rcube_find_object('rcmfd_spamskiprblchecks').checked = true;
+ else
+ rcube_find_object('rcmfd_spamskiprblchecks').checked = false;
+ }
+
+ // Bayes
+ if (rcube_find_object('rcmfd_spamusebayes')) {
+ if (rcmail.env.use_bayes == '1')
+ rcube_find_object('rcmfd_spamusebayes').checked = true;
+ else
+ rcube_find_object('rcmfd_spamusebayes').checked = false;
+ }
+
+ if (rcube_find_object('rcmfd_spambayesautolearn')) {
+ if (rcmail.env.bayes_auto_learn == '1')
+ rcube_find_object('rcmfd_spambayesautolearn').checked = true;
+ else
+ rcube_find_object('rcmfd_spambayesautolearn').checked = false;
+ }
+
+ if (rcube_find_object('rcmfd_bayesnonspam'))
+ rcube_find_object('rcmfd_bayesnonspam').selectedIndex = 0;
+
+ if (rcube_find_object('rcmfd_bayesspam'))
+ rcube_find_object('rcmfd_bayesspam').selectedIndex = 0;
+
+ if (rcube_find_object('rcmfd_spambayesrules')) {
+ if (rcmail.env.use_bayes_rules == '1')
+ rcube_find_object('rcmfd_spambayesrules').checked = true;
+ else
+ rcube_find_object('rcmfd_spambayesrules').checked = false;
+ }
+
+ // Headers
+ if (rcube_find_object('rcmfd_spamfoldheaders')) {
+ if (rcmail.env.skip_rbl_checks == '1')
+ rcube_find_object('rcmfd_spamfoldheaders').checked = true;
+ else
+ rcube_find_object('rcmfd_spamfoldheaders').checked = false;
+ }
+
+ if (rcube_find_object('rcmfd_spamlevelstars')) {
+ if (rcmail.env.add_header_all_Level != '') {
+ rcube_find_object('rcmfd_spamlevelstars').checked = true;
+ rcube_find_object('rcmfd_spamlevelchar').value = rcmail.env.add_header_all_Level.substr(7, 1);
+ }
+ else {
+ rcube_find_object('rcmfd_spamlevelstars').checked = false;
+ rcube_find_object('rcmfd_spamlevelchar').value = "*";
+ }
+ }
+
+ // Report
+ if (rcube_find_object('rcmfd_spamreport_0')) {
+ if (rcmail.env.report_safe == '0')
+ rcube_find_object('rcmfd_spamreport_0').checked = true;
+ else
+ rcube_find_object('rcmfd_spamreport_0').checked = false;
+ }
+
+ if (rcube_find_object('rcmfd_spamreport_1')) {
+ if (rcmail.env.report_safe == '1')
+ rcube_find_object('rcmfd_spamreport_1').checked = true;
+ else
+ rcube_find_object('rcmfd_spamreport_1').checked = false;
+ }
+
+ if (rcube_find_object('rcmfd_spamreport_2')) {
+ if (rcmail.env.report_safe == '2')
+ rcube_find_object('rcmfd_spamreport_2').checked = true;
+ else
+ rcube_find_object('rcmfd_spamreport_2').checked = false;
+ }
+
+ // Delete whitelist
+ if (rcube_find_object('address-rules-table')) {
+ var adrTable = rcube_find_object('address-rules-table').tBodies[0];
+ for (var i = adrTable.rows.length - 1; i > 1; i--) {
+ if (document.getElementsByName('_address_rule_act[]')[i-1].value == "INSERT") {
+ adrTable.deleteRow(i);
+ rcmail.env.address_rule_count--;
+ }
+ else if (document.getElementsByName('_address_rule_act[]')[i-1].value != "DELETE") {
+ adrTable.rows[i].style.display = 'none';
+ document.getElementsByName('_address_rule_act[]')[i-1].value = "DELETE";
+ rcmail.env.address_rule_count--;
+ }
+ }
+ adrTable.rows[1].style.display = '';
+ }
+ }
+ }, true);
+
+ rcmail.enable_command('plugin.sauserprefs.save','plugin.sauserprefs.default', true);
+ }
+ });
+
+ if (rcmail.env.action == 'plugin.sauserprefs') {
+ rcmail.section_select = function(list) {
+ var id = list.get_single_selection()
+
+ if (id) {
+ var add_url = '';
+ var target = window;
+ this.set_busy(true);
+
+ if (this.env.contentframe && window.frames && window.frames[this.env.contentframe]) {
+ add_url = '&_framed=1';
+ target = window.frames[this.env.contentframe];
+ }
+
+ target.location.href = this.env.comm_path + '&_action=plugin.sauserprefs.edit&_section=' + id + add_url;
+ }
+
+ return true;
+ }
+ }
+ }
+}); \ No newline at end of file
diff --git a/plugins/sauserprefs/sauserprefs.php b/plugins/sauserprefs/sauserprefs.php
new file mode 100644
index 000000000..8cab496b7
--- /dev/null
+++ b/plugins/sauserprefs/sauserprefs.php
@@ -0,0 +1,909 @@
+<?php
+
+/**
+ * SAUserPrefs
+ *
+ * Plugin to allow the user to manage their SpamAssassin settings using an SQL database
+ *
+ * @version @package_version@
+ * @author Philip Weir
+ */
+class sauserprefs extends rcube_plugin
+{
+ public $task = 'mail|addressbook|settings';
+ private $storage;
+ private $sections = array();
+ private $cur_section;
+ private $global_prefs;
+ private $user_prefs;
+ private $addressbook = '0';
+ private $sa_locales = array('en', 'ja', 'ko', 'ru', 'th', 'zh');
+ private $sa_user;
+ static $deprecated_prefs = array('required_hits' => 'required_score');
+
+ function init()
+ {
+ $rcmail = rcube::get_instance();
+ $this->load_config();
+ $this->sa_user = $rcmail->config->get('sauserprefs_userid', "%u");
+
+ $identity_arr = $rcmail->user->get_identity();
+ $identity = $identity_arr['email'];
+ $this->sa_user = str_replace('%u', $_SESSION['username'], $this->sa_user);
+ $this->sa_user = str_replace('%l', $rcmail->user->get_username('local'), $this->sa_user);
+ $this->sa_user = str_replace('%d', $rcmail->user->get_username('domain'), $this->sa_user);
+ $this->sa_user = str_replace('%i', $identity, $this->sa_user);
+
+ // init storage
+ include('include/rcube_sauserprefs_storage.php');
+ $this->storage = new rcube_sauserprefs_storage($rcmail->config->get('sauserprefs_db_dsnw'), $rcmail->config->get('sauserprefs_db_dsnr'), $rcmail->config->get('sauserprefs_db_persistent'),
+ $this->sa_user, $rcmail->config->get('sauserprefs_sql_table_name'), $rcmail->config->get('sauserprefs_sql_username_field'), $rcmail->config->get('sauserprefs_sql_preference_field'),
+ $rcmail->config->get('sauserprefs_sql_value_field'), $rcmail->config->get('sauserprefs_bayes_delete_query'));
+
+ if ($rcmail->config->get('sauserprefs_whitelist_abook_id', false))
+ $this->addressbook = $rcmail->config->get('sauserprefs_whitelist_abook_id');
+
+ if ($rcmail->task == 'settings') {
+ $this->add_texts('localization/', array('sauserprefs', 'managespam'));
+ $this->include_stylesheet($this->local_skin_path() . '/tabstyles.css');
+
+ $this->sections = array(
+ 'general' => array('id' => 'general', 'section' => $this->gettext('spamgeneralsettings')),
+ 'tests' => array('id' => 'tests', 'section' => $this->gettext('spamtests')),
+ 'bayes' => array('id' => 'bayes', 'section' => $this->gettext('bayes')),
+ 'headers' => array('id' => 'headers', 'section' => $this->gettext('headers')),
+ 'report' => array('id' => 'report','section' => $this->gettext('spamreportsettings')),
+ 'addresses' => array('id' => 'addresses', 'section' => $this->gettext('spamaddressrules')),
+ );
+ $this->cur_section = rcube_utils::get_input_value('_section', rcube_utils::INPUT_GPC);
+
+ $this->register_action('plugin.sauserprefs', array($this, 'init_html'));
+ $this->register_action('plugin.sauserprefs.edit', array($this, 'init_html'));
+ $this->register_action('plugin.sauserprefs.save', array($this, 'save'));
+ $this->register_action('plugin.sauserprefs.whitelist_import', array($this, 'whitelist_import'));
+ $this->register_action('plugin.sauserprefs.purge_bayes', array($this, 'purge_bayes'));
+ $this->include_script('sauserprefs.js');
+ }
+ elseif ($rcmail->config->get('sauserprefs_whitelist_sync')) {
+ $this->add_hook('contact_create', array($this, 'contact_add'));
+ $this->add_hook('contact_update', array($this, 'contact_save'));
+ $this->add_hook('contact_delete', array($this, 'contact_delete'));
+ }
+ }
+
+ function init_html()
+ {
+ $this->_load_global_prefs();
+ $this->_load_user_prefs();
+
+ $this->api->output->set_pagetitle($this->gettext('sauserprefssettings'));
+
+ if (rcube::get_instance()->action == 'plugin.sauserprefs.edit') {
+ $this->user_prefs = array_merge($this->global_prefs, $this->user_prefs);
+ $this->api->output->add_handler('userprefs', array($this, 'gen_form'));
+ $this->api->output->add_handler('sectionname', array($this, 'prefs_section_name'));
+ $this->api->output->send('sauserprefs.settingsedit');
+ }
+ else {
+ $this->api->output->add_handler('sasectionslist', array($this, 'section_list'));
+ $this->api->output->add_handler('saprefsframe', array($this, 'preference_frame'));
+ $this->api->output->send('sauserprefs.sauserprefs');
+ }
+ }
+
+ function section_list($attrib)
+ {
+ $no_override = array_flip(rcube::get_instance()->config->get('sauserprefs_dont_override'));
+
+ // add id to message list table if not specified
+ if (!strlen($attrib['id']))
+ $attrib['id'] = 'rcmsectionslist';
+
+ $sections = array();
+ $blocks = $attrib['sections'] ? preg_split('/[\s,;]+/', strip_quotes($attrib['sections'])) : array_keys($this->sections);
+ foreach ($blocks as $block) {
+ if (!isset($no_override['{' . $block . '}']))
+ $sections[$block] = $this->sections[$block];
+ }
+
+ // create XHTML table
+ $out = rcube::get_instance()->table_output($attrib, $sections, array('section'), 'id');
+
+ // set client env
+ $this->api->output->add_gui_object('sectionslist', $attrib['id']);
+ $this->api->output->include_script('list.js');
+
+ return $out;
+ }
+
+ function preference_frame($attrib)
+ {
+ if (!$attrib['id'])
+ $attrib['id'] = 'rcmprefsframe';
+
+ return $this->api->output->frame($attrib, true);
+ }
+
+ function gen_form($attrib)
+ {
+ $this->api->output->add_label(
+ 'sauserprefs.spamaddressexists', 'sauserprefs.spamenteraddress',
+ 'sauserprefs.spamaddresserror', 'sauserprefs.spamaddressdelete',
+ 'sauserprefs.spamaddressdeleteall', 'sauserprefs.enabled', 'sauserprefs.disabled',
+ 'sauserprefs.importingaddresses', 'sauserprefs.usedefaultconfirm', 'sauserprefs.purgebayesconfirm',
+ 'sauserprefs.whitelist_from');
+
+ // output global prefs as default in env
+ foreach($this->global_prefs as $key => $val)
+ $this->api->output->set_env(str_replace(" ", "_", $key), $val);
+
+ unset($attrib['form']);
+
+ list($form_start, $form_end) = get_form_tags($attrib, 'plugin.sauserprefs.save', null,
+ array('name' => '_section', 'value' => $this->cur_section));
+
+ $out = $form_start;
+
+ $out .= $this->_prefs_block($this->cur_section, $attrib);
+
+ return $out . $form_end;
+ }
+
+ function prefs_section_name()
+ {
+ return $this->sections[$this->cur_section]['section'];
+ }
+
+ function save()
+ {
+ $rcmail = rcube::get_instance();
+ $this->_load_global_prefs();
+ $this->_load_user_prefs();
+
+ $no_override = array_flip($rcmail->config->get('sauserprefs_dont_override'));
+ $new_prefs = array();
+ $result = true;
+
+ switch ($this->cur_section)
+ {
+ case 'general':
+ if (!isset($no_override['required_hits']))
+ $new_prefs['required_hits'] = rcube_utils::get_input_value('_spamthres', rcube_utils::INPUT_POST);
+
+ if (!isset($no_override['rewrite_header Subject']))
+ $new_prefs['rewrite_header Subject'] = rcube_utils::get_input_value('_spamsubject', rcube_utils::INPUT_POST);
+
+ if (!isset($no_override['ok_locales'])) {
+ $new_prefs['ok_locales'] = '';
+ if (is_array(rcube_utils::get_input_value('_spamlang', rcube_utils::INPUT_POST))) {
+ $locales = array_intersect(rcube_utils::get_input_value('_spamlang', rcube_utils::INPUT_POST), $this->sa_locales);
+ $new_prefs['ok_locales'] = implode(" ", $locales);
+ }
+ }
+
+ if (!isset($no_override['ok_languages']))
+ $new_prefs['ok_languages'] = is_array(rcube_utils::get_input_value('_spamlang', rcube_utils::INPUT_POST)) ? implode(" ", rcube_utils::get_input_value('_spamlang', rcube_utils::INPUT_POST)) : '';
+
+ break;
+
+ case 'headers':
+ if (!isset($no_override['fold_headers']))
+ $new_prefs['fold_headers'] = empty($_POST['_spamfoldheaders']) ? "0" : "1";
+
+ if (!isset($no_override['add_header all Level'])) {
+ $spamchar = empty($_POST['_spamlevelchar']) ? "*" : rcube_utils::get_input_value('_spamlevelchar', rcube_utils::INPUT_POST);
+
+ if (rcube_utils::get_input_value('_spamlevelstars', rcube_utils::INPUT_POST) == "1") {
+ $new_prefs['add_header all Level'] = "_STARS(". $spamchar .")_";
+ $new_prefs['remove_header all'] = "0";
+ }
+ else {
+ $new_prefs['add_header all Level'] = "";
+ $new_prefs['remove_header all'] = "Level";
+ }
+ }
+
+ break;
+
+ case 'tests':
+ if (!isset($no_override['use_razor1']))
+ $new_prefs['use_razor1'] = empty($_POST['_spamuserazor1']) ? "0" : "1";
+
+ if (!isset($no_override['use_razor2']))
+ $new_prefs['use_razor2'] = empty($_POST['_spamuserazor2']) ? "0" : "1";
+
+ if (!isset($no_override['use_pyzor']))
+ $new_prefs['use_pyzor'] = empty($_POST['_spamusepyzor']) ? "0" : "1";
+
+ if (!isset($no_override['use_dcc']))
+ $new_prefs['use_dcc'] = empty($_POST['_spamusedcc']) ? "0" : "1";
+
+ if (!isset($no_override['skip_rbl_checks']))
+ $new_prefs['skip_rbl_checks'] = empty($_POST['_spamskiprblchecks']) ? "1" : "0";
+
+ break;
+
+ case 'bayes':
+ if (!isset($no_override['use_bayes']))
+ $new_prefs['use_bayes'] = empty($_POST['_spamusebayes']) ? "0" : "1";
+
+ if (!isset($no_override['bayes_auto_learn']))
+ $new_prefs['bayes_auto_learn'] = empty($_POST['_spambayesautolearn']) ? "0" : "1";
+
+ if (!isset($no_override['bayes_auto_learn_threshold_nonspam']) && !empty($_POST['_bayesnonspam']))
+ $new_prefs['bayes_auto_learn_threshold_nonspam'] = rcube_utils::get_input_value('_bayesnonspam', rcube_utils::INPUT_POST);
+
+ if (!isset($no_override['bayes_auto_learn_threshold_spam']) && !empty($_POST['_bayesspam']))
+ $new_prefs['bayes_auto_learn_threshold_spam'] = rcube_utils::get_input_value('_bayesspam', rcube_utils::INPUT_POST);
+
+ if (!isset($no_override['use_bayes_rules']))
+ $new_prefs['use_bayes_rules'] = empty($_POST['_spambayesrules']) ? "0" : "1";
+
+ break;
+
+ case 'report':
+ if (!isset($no_override['report_safe']))
+ $new_prefs['report_safe'] = rcube_utils::get_input_value('_spamreport', rcube_utils::INPUT_POST);
+
+ break;
+
+ case 'addresses':
+ $acts = rcube_utils::get_input_value('_address_rule_act', rcube_utils::INPUT_POST);
+ $prefs = rcube_utils::get_input_value('_address_rule_field', rcube_utils::INPUT_POST);
+ $vals = rcube_utils::get_input_value('_address_rule_value', rcube_utils::INPUT_POST);
+
+ foreach ($acts as $idx => $act)
+ $new_prefs['addresses'][] = array('field' => $prefs[$idx], 'value' => $vals[$idx], 'action' => $act);
+
+ break;
+ }
+
+ // allow additional actions before prefs are saved
+ $data = $rcmail->plugins->exec_hook('sauserprefs_save', array(
+ 'section' => $this->cur_section, 'cur_prefs' => $this->user_prefs, 'new_prefs' => $new_prefs, 'global_prefs' => $this->global_prefs));
+
+ if (!$data['abort']) {
+ // save prefs
+ if ($this->storage->save_prefs($data['new_prefs'], $this->user_prefs, $this->global_prefs))
+ $this->api->output->command('display_message', $this->gettext('sauserprefchanged'), 'confirmation');
+ else
+ $this->api->output->command('display_message', $this->gettext('sauserpreffailed'), 'error');
+ }
+ else {
+ $this->api->output->command('display_message', $data['message'] ? $data['message'] : $this->gettext('sauserpreffailed'), 'error');
+ }
+
+ // go to next step
+ $rcmail->overwrite_action('plugin.sauserprefs.edit');
+ $this->_load_user_prefs();
+ $this->init_html();
+ }
+
+ function whitelist_import()
+ {
+ $contacts = rcube::get_instance()->get_address_book($this->addressbook);
+ $contacts->set_page(1);
+ $contacts->set_pagesize(99999);
+ $result = $contacts->list_records(null, 0, true);
+
+ if (empty($result) || $result->count == 0)
+ return;
+
+ $records = $result->records;
+ foreach ($records as $row_data) {
+ foreach ($this->_gen_email_arr($row_data) as $email)
+ $this->api->output->command('sauserprefs_addressrule_import', $email, '', '');
+ }
+
+ $contacts->close();
+ }
+
+ function purge_bayes()
+ {
+ $rcmail = rcube::get_instance();
+
+ if (!$rcmail->config->get('sauserprefs_bayes_delete', false)) {
+ $this->api->output->command('display_message', $this->gettext('servererror'), 'error');
+ return;
+ }
+
+ if ($this->storage->purge_bayes())
+ $this->api->output->command('display_message', $this->gettext('done'), 'confirmation');
+ else
+ $this->api->output->command('display_message', $this->gettext('servererror'), 'error');
+ }
+
+ function contact_add($args)
+ {
+ $rcmail = rcube::get_instance();
+
+ // only works with specified address book
+ if ($args['source'] != $this->addressbook && $args['source'] != null)
+ return;
+
+ $emails = $this->_gen_email_arr($args['record']);
+ $this->storage->whitelist_add($emails);
+ }
+
+ function contact_save($args)
+ {
+ $this->contact_delete($args);
+ $this->contact_add($args);
+ }
+
+ function contact_delete($args)
+ {
+ $rcmail = rcube::get_instance();
+
+ // only works with specified address book
+ if ($args['source'] != $this->addressbook && $args['source'] != null)
+ return;
+
+ if (!is_array($args['id']))
+ $args['id'] = array($args['id']);
+
+ $contacts = $rcmail->get_address_book($this->addressbook);
+ foreach ($args['id'] as $id) {
+ $emails = $this->_gen_email_arr($contacts->get_record($id, true));
+ $this->storage->whitelist_delete($emails);
+ }
+
+ $contacts->close();
+ }
+
+ private function _load_global_prefs()
+ {
+ $rcmail = rcube::get_instance();
+ $this->global_prefs = $this->_load_prefs($rcmail->config->get('sauserprefs_global_userid'));
+ $this->global_prefs = array_merge($rcmail->config->get('sauserprefs_default_prefs'), $this->global_prefs);
+ }
+
+ private function _load_user_prefs()
+ {
+ $this->user_prefs = $this->_load_prefs($this->sa_user);
+ }
+
+ private function _load_prefs($user)
+ {
+ $rcmail = rcube::get_instance();
+ $prefs = $this->storage->load_prefs($user);
+
+ // sort address rules
+ $prefs['addresses'] = $this->_subval_sort($prefs['addresses'], 'value');
+
+ return $prefs;
+ }
+
+ private function _prefs_block($part, $attrib)
+ {
+ $rcmail = rcube::get_instance();
+ $no_override = array_flip($rcmail->config->get('sauserprefs_dont_override'));
+ $locale_info = localeconv();
+
+ switch ($part)
+ {
+ // General tests
+ case 'general':
+ $out = '';
+ $data = '';
+
+ $table = new html_table(array('class' => 'generalprefstable', 'cols' => 2));
+
+ if (!isset($no_override['required_hits'])) {
+ $field_id = 'rcmfd_spamthres';
+ $input_spamthres = new html_select(array('name' => '_spamthres', 'id' => $field_id));
+ $input_spamthres->add($this->gettext('defaultscore'), '');
+
+ $decPlaces = 0;
+ if ($rcmail->config->get('sauserprefs_score_inc') - (int)$rcmail->config->get('sauserprefs_score_inc') > 0)
+ $decPlaces = strlen($rcmail->config->get('sauserprefs_score_inc') - (int)$rcmail->config->get('sauserprefs_score_inc')) - 2;
+
+ $score_found = false;
+ for ($i = 1; $i <= 10; $i = $i + $rcmail->config->get('sauserprefs_score_inc')) {
+ $input_spamthres->add(number_format($i, $decPlaces, $locale_info['decimal_point'], ''), number_format($i, $decPlaces, '.', ''));
+
+ if (!$score_found && $this->user_prefs['required_hits'] && (float)$this->user_prefs['required_hits'] == (float)$i)
+ $score_found = true;
+ }
+
+ if (!$score_found && $this->user_prefs['required_hits'])
+ $input_spamthres->add(str_replace('%s', $this->user_prefs['required_hits'], $this->gettext('otherscore')), (float)$this->user_prefs['required_hits']);
+
+ $table->add('title', html::label($field_id, rcmail::Q($this->gettext('spamthres'))));
+ $table->add(null, $input_spamthres->show(number_format($this->user_prefs['required_hits'], $decPlaces, '.', '')));
+ $table->add(array('colspan' => 2), rcmail::Q($this->gettext('spamthresexp')));
+ }
+
+ if (!isset($no_override['rewrite_header Subject'])) {
+ $field_id = 'rcmfd_spamsubject';
+ $input_spamsubject = new html_inputfield(array('name' => '_spamsubject', 'id' => $field_id, 'value' => $this->user_prefs['rewrite_header Subject'], 'style' => 'width:200px;'));
+
+ $table->add('title', html::label($field_id, rcmail::Q($this->gettext('spamsubject'))));
+ $table->add(null, $input_spamsubject->show());
+
+ $table->add('title', "&nbsp;");
+ $table->add(null, rcmail::Q($this->gettext('spamsubjectblank')));
+ }
+
+ if ($table->size() > 0)
+ $out .= html::tag('fieldset', null, html::tag('legend', null, rcmail::Q($this->gettext('mainoptions'))) . $table->show());
+
+ if (!isset($no_override['ok_languages']) || !isset($no_override['ok_locales'])) {
+ $data = html::p(null, rcmail::Q($this->gettext('spamlangexp')));
+
+ $table = new html_table(array('class' => 'langprefstable', 'cols' => 1));
+
+ $select_all = $this->api->output->button(array('command' => 'plugin.sauserprefs.select_all_langs', 'type' => 'link', 'label' => 'all'));
+ $select_none = $this->api->output->button(array('command' => 'plugin.sauserprefs.select_no_langs', 'type' => 'link', 'label' => 'none'));
+ $select_invert = $this->api->output->button(array('command' => 'plugin.sauserprefs.select_invert_langs', 'type' => 'link', 'label' => 'invert'));
+
+ $table->add(array('id' => 'listcontrols'), $this->gettext('select') .":&nbsp;&nbsp;". $select_all ."&nbsp;&nbsp;". $select_invert ."&nbsp;&nbsp;". $select_none);
+
+ $lang_table = new html_table(array('id' => 'spam-langs-table', 'class' => 'records-table', 'cellspacing' => '0', 'cols' => 2));
+ $lang_table->add_header(array('colspan' => 2), $this->gettext('language'));
+
+ if (!isset($no_override['ok_locales'])) {
+ if ($this->user_prefs['ok_locales'] == "all")
+ $ok_locales = $this->sa_locales;
+ else
+ $ok_locales = explode(" ", $this->user_prefs['ok_locales']);
+ }
+ else {
+ $ok_locales = array();
+ }
+
+ if (!isset($no_override['ok_languages'])) {
+ if ($this->user_prefs['ok_languages'] == "all")
+ $ok_languages = array_keys($rcmail->config->get('sauserprefs_languages'));
+ else
+ $ok_languages = explode(" ", $this->user_prefs['ok_languages']);
+ }
+ else {
+ $tmp_array = $rcmail->config->get('sauserprefs_languages');
+ $rcmail->config->set('sauserprefs_languages', array_intersect_key($tmp_array, array_flip($this->sa_locales)));
+ $ok_languages = array();
+ }
+
+ $i = 0;
+ $locales_langs = array_merge($ok_locales, $ok_languages);
+ foreach ($rcmail->config->get('sauserprefs_languages') as $lang_code => $name) {
+ if (in_array($lang_code, $locales_langs))
+ $button = $this->api->output->button(array('command' => 'plugin.sauserprefs.message_lang', 'prop' => $lang_code, 'type' => 'link', 'class' => 'enabled', 'id' => 'spam_lang_' . $i, 'title' => 'sauserprefs.enabled', 'content' => ' '));
+ else
+ $button = $this->api->output->button(array('command' => 'plugin.sauserprefs.message_lang', 'prop' => $lang_code, 'type' => 'link', 'class' => 'disabled', 'id' => 'spam_lang_' . $i, 'title' => 'sauserprefs.disabled', 'content' => ' '));
+
+ $input_spamlang = new html_checkbox(array('style' => 'display: none;', 'name' => '_spamlang[]', 'value' => $lang_code));
+
+ $lang_table->add('lang', $name);
+ $lang_table->add('tick', $button . $input_spamlang->show(in_array($lang_code, $locales_langs) ? $lang_code : ''));
+
+ $i++;
+ }
+
+ $table->add('scroller', html::div(array('id' => 'spam-langs-cont'), $lang_table->show()));
+
+ $out .= html::tag('fieldset', null, html::tag('legend', null, rcmail::Q($this->gettext('langoptions'))) . $data . $table->show());
+ }
+
+ break;
+
+ // Header settings
+ case 'headers':
+ $data = html::p(null, rcmail::Q($this->gettext('headersexp')));
+
+ $table = new html_table(array('class' => 'headersprefstable', 'cols' => 3));
+
+ if (!isset($no_override['fold_headers'])) {
+ $help_button = html::img(array('class' => $imgclass, 'src' => $attrib['helpicon'], 'alt' => $this->gettext('sieveruleheaders'), 'border' => 0, 'style' => 'margin-left: 4px;'));
+ $help_button = html::a(array('name' => '_headerhlp', 'href' => "#", 'onclick' => 'return '. rcmail_output::JS_OBJECT_NAME .'.sauserprefs_help("fold_help");', 'title' => $this->gettext('help')), $help_button);
+
+ $field_id = 'rcmfd_spamfoldheaders';
+ $input_spamreport = new html_checkbox(array('name' => '_spamfoldheaders', 'id' => $field_id, 'value' => '1'));
+
+ $table->add('title', html::label($field_id, rcmail::Q($this->gettext('foldheaders'))));
+ $table->add(null, $input_spamreport->show($this->user_prefs['fold_headers']));
+ $table->add('help', $help_button);
+ $table->set_row_attribs(array('id' => 'fold_help', 'style' => 'display: none;'));
+ $table->add(array('colspan' => '3'), rcmail::Q($this->gettext('foldhelp')));
+ }
+
+ if (!isset($no_override['add_header all Level'])) {
+ $help_button = html::img(array('class' => $imgclass, 'src' => $attrib['helpicon'], 'alt' => $this->gettext('sieveruleheaders'), 'border' => 0, 'style' => 'margin-left: 4px;'));
+ $help_button = html::a(array('name' => '_headerhlp', 'href' => "#", 'onclick' => 'return '. rcmail_output::JS_OBJECT_NAME .'.sauserprefs_help("level_help");', 'title' => $this->gettext('help')), $help_button);
+
+ if ($this->user_prefs['remove_header all'] != 'Level') {
+ $enabled = "1";
+ $char = $this->user_prefs['add_header all Level'];
+ $char = substr($char, 7, 1);
+ }
+ else {
+ $enabled = "0";
+ $char = "*";
+ }
+
+ $field_id = 'rcmfd_spamlevelstars';
+ $input_spamreport = new html_checkbox(array('name' => '_spamlevelstars', 'id' => $field_id, 'value' => '1',
+ 'onchange' => rcmail_output::JS_OBJECT_NAME . '.sauserprefs_toggle_level_char(this)'));
+
+ $table->add('title', html::label($field_id, rcmail::Q($this->gettext('spamlevelstars'))));
+ $table->add(null, $input_spamreport->show($enabled));
+ $table->add('help', $help_button);
+ $table->set_row_attribs(array('id' => 'level_help', 'style' => 'display: none;'));
+ $table->add(array('colspan' => '3'), rcmail::Q($this->gettext('levelhelp')));
+
+ $field_id = 'rcmfd_spamlevelchar';
+ $input_spamsubject = new html_inputfield(array('name' => '_spamlevelchar', 'id' => $field_id, 'value' => $char,
+ 'style' => 'width:20px;', 'disabled' => $enabled?0:1));
+
+ $table->add('title', html::label($field_id, rcmail::Q($this->gettext('spamlevelchar'))));
+ $table->add(null, $input_spamsubject->show());
+ $table->add('help', '&nbsp;');
+ }
+
+ $out = html::tag('fieldset', null, html::tag('legend', null, rcmail::Q($this->gettext('mainoptions'))) . $data . $table->show());
+ break;
+
+ // Test settings
+ case 'tests':
+ $data = html::p(null, rcmail::Q($this->gettext('spamtestssexp')));
+
+ $table = new html_table(array('class' => 'testsprefstable', 'cols' => 3));
+
+ if (!isset($no_override['use_razor1'])) {
+ $help_button = html::img(array('class' => $imgclass, 'src' => $attrib['helpicon'], 'alt' => $this->gettext('sieveruleheaders'), 'border' => 0, 'style' => 'margin-left: 4px;'));
+ $help_button = html::a(array('name' => '_headerhlp', 'href' => "#", 'onclick' => 'return '. rcmail_output::JS_OBJECT_NAME .'.sauserprefs_help("raz1_help");', 'title' => $this->gettext('help')), $help_button);
+
+ $field_id = 'rcmfd_spamuserazor1';
+ $input_spamtest = new html_checkbox(array('name' => '_spamuserazor1', 'id' => $field_id, 'value' => '1'));
+
+ $table->add('title', html::label($field_id, rcmail::Q($this->gettext('userazor1'))));
+ $table->add(null, $input_spamtest->show($this->user_prefs['use_razor1']));
+ $table->add('help', $help_button);
+ $table->set_row_attribs(array('id' => 'raz1_help', 'style' => 'display: none;'));
+ $table->add(array('colspan' => '3'), rcmail::Q($this->gettext('raz1help')));
+ }
+
+ if (!isset($no_override['use_razor2'])) {
+ $help_button = html::img(array('class' => $imgclass, 'src' => $attrib['helpicon'], 'alt' => $this->gettext('sieveruleheaders'), 'border' => 0, 'style' => 'margin-left: 4px;'));
+ $help_button = html::a(array('name' => '_headerhlp', 'href' => "#", 'onclick' => 'return '. rcmail_output::JS_OBJECT_NAME .'.sauserprefs_help("raz2_help");', 'title' => $this->gettext('help')), $help_button);
+
+ $field_id = 'rcmfd_spamuserazor2';
+ $input_spamtest = new html_checkbox(array('name' => '_spamuserazor2', 'id' => $field_id, 'value' => '1'));
+
+ $table->add('title', html::label($field_id, rcmail::Q($this->gettext('userazor2'))));
+ $table->add(null, $input_spamtest->show($this->user_prefs['use_razor2']));
+ $table->add('help', $help_button);
+ $table->set_row_attribs(array('id' => 'raz2_help', 'style' => 'display: none;'));
+ $table->add(array('colspan' => '3'), rcmail::Q($this->gettext('raz2help')));
+ }
+
+ if (!isset($no_override['use_pyzor'])) {
+ $help_button = html::img(array('class' => $imgclass, 'src' => $attrib['helpicon'], 'alt' => $this->gettext('sieveruleheaders'), 'border' => 0, 'style' => 'margin-left: 4px;'));
+ $help_button = html::a(array('name' => '_headerhlp', 'href' => "#", 'onclick' => 'return '. rcmail_output::JS_OBJECT_NAME .'.sauserprefs_help("pyz_help");', 'title' => $this->gettext('help')), $help_button);
+
+ $field_id = 'rcmfd_spamusepyzor';
+ $input_spamtest = new html_checkbox(array('name' => '_spamusepyzor', 'id' => $field_id, 'value' => '1'));
+
+ $table->add('title', html::label($field_id, rcmail::Q($this->gettext('usepyzor'))));
+ $table->add(null, $input_spamtest->show($this->user_prefs['use_pyzor']));
+ $table->add('help', $help_button);
+ $table->set_row_attribs(array('id' => 'pyz_help', 'style' => 'display: none;'));
+ $table->add(array('colspan' => '3'), rcmail::Q($this->gettext('pyzhelp')));
+ }
+
+ if (!isset($no_override['use_dcc'])) {
+ $help_button = html::img(array('class' => $imgclass, 'src' => $attrib['helpicon'], 'alt' => $this->gettext('sieveruleheaders'), 'border' => 0, 'style' => 'margin-left: 4px;'));
+ $help_button = html::a(array('name' => '_headerhlp', 'href' => "#", 'onclick' => 'return '. rcmail_output::JS_OBJECT_NAME .'.sauserprefs_help("dcc_help");', 'title' => $this->gettext('help')), $help_button);
+
+ $field_id = 'rcmfd_spamusedcc';
+ $input_spamtest = new html_checkbox(array('name' => '_spamusedcc', 'id' => $field_id, 'value' => '1'));
+
+ $table->add('title', html::label($field_id, rcmail::Q($this->gettext('usedcc'))));
+ $table->add(null, $input_spamtest->show($this->user_prefs['use_dcc']));
+ $table->add('help', $help_button);
+ $table->set_row_attribs(array('id' => 'dcc_help', 'style' => 'display: none;'));
+ $table->add(array('colspan' => '3'), rcmail::Q($this->gettext('dcchelp')));
+ }
+
+ if (!isset($no_override['skip_rbl_checks'])) {
+ $help_button = html::img(array('class' => $imgclass, 'src' => $attrib['helpicon'], 'alt' => $this->gettext('sieveruleheaders'), 'border' => 0, 'style' => 'margin-left: 4px;'));
+ $help_button = html::a(array('name' => '_headerhlp', 'href' => "#", 'onclick' => 'return '. rcmail_output::JS_OBJECT_NAME .'.sauserprefs_help("rbl_help");', 'title' => $this->gettext('help')), $help_button);
+
+ $field_id = 'rcmfd_spamskiprblchecks';
+ $enabled = $this->user_prefs['skip_rbl_checks'] == "1" ? "0" : "1";
+ $input_spamtest = new html_checkbox(array('name' => '_spamskiprblchecks', 'id' => $field_id, 'value' => '1'));
+
+ $table->add('title', html::label($field_id, rcmail::Q($this->gettext('skiprblchecks'))));
+ $table->add(null, $input_spamtest->show($enabled));
+ $table->add('help', $help_button);
+ $table->set_row_attribs(array('id' => 'rbl_help', 'style' => 'display: none;'));
+ $table->add(array('colspan' => '3'), rcmail::Q($this->gettext('rblhelp')));
+ }
+
+ $out = html::tag('fieldset', null, html::tag('legend', null, rcmail::Q($this->gettext('mainoptions'))) . $data . $table->show());
+ break;
+
+ // Bayes settings
+ case 'bayes':
+ $data = html::p(null, rcmail::Q($this->gettext('bayeshelp')));
+
+ $table = new html_table(array('class' => 'bayesprefstable', 'cols' => 3));
+
+ if (!isset($no_override['use_bayes'])) {
+ $help_button = html::img(array('class' => $imgclass, 'src' => $attrib['helpicon'], 'alt' => $this->gettext('sieveruleheaders'), 'border' => 0, 'style' => 'margin-left: 4px;'));
+ $help_button = html::a(array('name' => '_headerhlp', 'href' => "#", 'onclick' => 'return '. rcmail_output::JS_OBJECT_NAME .'.sauserprefs_help("bayes_help");', 'title' => $this->gettext('help')), $help_button);
+
+ $field_id = 'rcmfd_spamusebayes';
+ $input_spamtest = new html_checkbox(array('name' => '_spamusebayes', 'id' => $field_id, 'value' => '1',
+ 'onchange' => rcmail_output::JS_OBJECT_NAME . '.sauserprefs_toggle_bayes(this)'));
+
+ if ($rcmail->config->get('sauserprefs_bayes_delete', false))
+ $delete_link = "&nbsp;&nbsp;&nbsp;" . html::span(array('id' => 'listcontrols'), $this->api->output->button(array('command' => 'plugin.sauserprefs.purge_bayes', 'type' => 'link', 'label' => 'sauserprefs.purgebayes', 'title' => 'sauserprefs.purgebayesexp')));
+
+ $table->add('title', html::label($field_id, rcmail::Q($this->gettext('usebayes'))));
+ $table->add(null, $input_spamtest->show($this->user_prefs['use_bayes']) . $delete_link);
+ $table->add('help', '&nbsp;');
+ $table->set_row_attribs(array('id' => 'bayes_help', 'style' => 'display: none;'));
+ $table->add(array('colspan' => '3'), rcmail::Q($this->gettext('bayeshelp')));
+ }
+
+ if (!isset($no_override['use_bayes_rules'])) {
+ $help_button = html::img(array('class' => $imgclass, 'src' => $attrib['helpicon'], 'alt' => $this->gettext('sieveruleheaders'), 'border' => 0, 'style' => 'margin-left: 4px;'));
+ $help_button = html::a(array('name' => '_headerhlp', 'href' => "#", 'onclick' => 'return '. rcmail_output::JS_OBJECT_NAME .'.sauserprefs_help("bayesrules_help");', 'title' => $this->gettext('help')), $help_button);
+
+ $field_id = 'rcmfd_spambayesrules';
+ $input_spamtest = new html_checkbox(array('name' => '_spambayesrules', 'id' => $field_id, 'value' => '1', 'disabled' => $this->user_prefs['use_bayes']?0:1));
+
+ $table->add('title', html::label($field_id, rcmail::Q($this->gettext('bayesrules'))));
+ $table->add(null, $input_spamtest->show($this->user_prefs['use_bayes_rules']));
+ $table->add('help', $help_button);
+ $table->set_row_attribs(array('id' => 'bayesrules_help', 'style' => 'display: none;'));
+ $table->add(array('colspan' => '3'), rcmail::Q($this->gettext('bayesruleshlp')));
+ }
+
+ if (!isset($no_override['bayes_auto_learn'])) {
+ $help_button = html::img(array('class' => $imgclass, 'src' => $attrib['helpicon'], 'alt' => $this->gettext('sieveruleheaders'), 'border' => 0, 'style' => 'margin-left: 4px;'));
+ $help_button = html::a(array('name' => '_headerhlp', 'href' => "#", 'onclick' => 'return '. rcmail_output::JS_OBJECT_NAME .'.sauserprefs_help("bayesauto_help");', 'title' => $this->gettext('help')), $help_button);
+
+ $field_id = 'rcmfd_spambayesautolearn';
+ $input_spamtest = new html_checkbox(array('name' => '_spambayesautolearn', 'id' => $field_id, 'value' => '1',
+ 'onchange' => rcmail_output::JS_OBJECT_NAME . '.sauserprefs_toggle_bayes_auto(this)', 'disabled' => $this->user_prefs['use_bayes']?0:1));
+
+ $table->add('title', html::label($field_id, rcmail::Q($this->gettext('bayesautolearn'))));
+ $table->add(null, $input_spamtest->show($this->user_prefs['bayes_auto_learn']));
+ $table->add('help', $help_button);
+ $table->set_row_attribs(array('id' => 'bayesauto_help', 'style' => 'display: none;'));
+ $table->add(array('colspan' => '3'), rcmail::Q($this->gettext('bayesautohelp')));
+ }
+
+ if ($table->size() > 0)
+ $out = html::tag('fieldset', null, html::tag('legend', null, rcmail::Q($this->gettext('mainoptions'))) . $table->show());
+
+ $table = new html_table(array('class' => 'bayesprefstable', 'cols' => 2));
+
+ $data = "";
+ if (!isset($no_override['bayes_auto_learn_threshold_nonspam'])) {
+ $field_id = 'rcmfd_bayesnonspam';
+ $input_bayesnthres = new html_select(array('name' => '_bayesnonspam', 'id' => $field_id, 'disabled' => (!$this->user_prefs['bayes_auto_learn'] || !$this->user_prefs['use_bayes'])?1:0));
+ $input_bayesnthres->add($this->gettext('defaultscore'), '');
+
+ $decPlaces = 1;
+ //if ($rcmail->config->get('sauserprefs_score_inc') - (int)$rcmail->config->get('sauserprefs_score_inc') > 0)
+ // $decPlaces = strlen($rcmail->config->get('sauserprefs_score_inc') - (int)$rcmail->config->get('sauserprefs_score_inc')) - 2;
+
+ $score_found = false;
+ for ($i = -1; $i <= 1; $i = $i + 0.1) {
+ $input_bayesnthres->add(number_format($i, $decPlaces, $locale_info['decimal_point'], ''), number_format($i, $decPlaces, '.', ''));
+
+ if (!$score_found && $this->user_prefs['bayes_auto_learn_threshold_nonspam'] && (float)$this->user_prefs['bayes_auto_learn_threshold_nonspam'] == (float)$i)
+ $score_found = true;
+ }
+
+ if (!$score_found && $this->user_prefs['bayes_auto_learn_threshold_nonspam'])
+ $input_bayesnthres->add(str_replace('%s', $this->user_prefs['bayes_auto_learn_threshold_nonspam'], $this->gettext('otherscore')), (float)$this->user_prefs['bayes_auto_learn_threshold_nonspam']);
+
+ $table->add('title', html::label($field_id, rcmail::Q($this->gettext('bayesnonspam'))));
+ $table->add(null, $input_bayesnthres->show(number_format($this->user_prefs['bayes_auto_learn_threshold_nonspam'], $decPlaces, '.', '')));
+ $table->add(array('colspan' => '2'), rcmail::Q($this->gettext('bayesnonspamexp')));
+ }
+
+ if (!isset($no_override['bayes_auto_learn_threshold_spam'])) {
+ $field_id = 'rcmfd_bayesspam';
+ $input_bayesthres = new html_select(array('name' => '_bayesspam', 'id' => $field_id, 'disabled' => (!$this->user_prefs['bayes_auto_learn'] || !$this->user_prefs['use_bayes'])?1:0));
+ $input_bayesthres->add($this->gettext('defaultscore'), '');
+
+ $decPlaces = 0;
+ if ($rcmail->config->get('sauserprefs_score_inc') - (int)$rcmail->config->get('sauserprefs_score_inc') > 0)
+ $decPlaces = strlen($rcmail->config->get('sauserprefs_score_inc') - (int)$rcmail->config->get('sauserprefs_score_inc')) - 2;
+
+ $score_found = false;
+ for ($i = 1; $i <= 20; $i = $i + $rcmail->config->get('sauserprefs_score_inc')) {
+ $input_bayesthres->add(number_format($i, $decPlaces, $locale_info['decimal_point'], ''), number_format($i, $decPlaces, '.', ''));
+
+ if (!$score_found && $this->user_prefs['bayes_auto_learn_threshold_spam'] && (float)$this->user_prefs['bayes_auto_learn_threshold_spam'] == (float)$i)
+ $score_found = true;
+ }
+
+ if (!$score_found && $this->user_prefs['required_hits'])
+ $input_bayesthres->add(str_replace('%s', $this->user_prefs['bayes_auto_learn_threshold_spam'], $this->gettext('otherscore')), (float)$this->user_prefs['bayes_auto_learn_threshold_spam']);
+
+ $table->add('title', html::label($field_id, rcmail::Q($this->gettext('bayesspam'))));
+ $table->add(null, $input_bayesthres->show(number_format($this->user_prefs['bayes_auto_learn_threshold_spam'], $decPlaces, '.', '')));
+ $table->add(array('colspan' => '2'), rcmail::Q($this->gettext('bayesspamexp')));
+ }
+
+ if ($table->size() > 0)
+ $out .= html::tag('fieldset', null, html::tag('legend', null, rcmail::Q($this->gettext('bayesautooptions'))) . $table->show());
+
+ break;
+
+ // Report settings
+ case 'report':
+ $data = html::p(null, rcmail::Q($this->gettext('spamreport')));
+
+ $table = new html_table(array('class' => 'reportprefstable', 'cols' => 2));
+
+ if (!isset($no_override['report_safe'])) {
+ $field_id = 'rcmfd_spamreport';
+ $input_spamreport0 = new html_radiobutton(array('name' => '_spamreport', 'id' => $field_id.'_0', 'value' => '0'));
+ $table->add('title', html::label($field_id.'_0', rcmail::Q($this->gettext('spamreport0'))));
+ $table->add(null, $input_spamreport0->show($this->user_prefs['report_safe']));
+
+ $input_spamreport1 = new html_radiobutton(array('name' => '_spamreport', 'id' => $field_id.'_1', 'value' => '1'));
+ $table->add('title', html::label($field_id.'_1', rcmail::Q($this->gettext('spamreport1'))));
+ $table->add(null, $input_spamreport1->show($this->user_prefs['report_safe']));
+ $data .= $input_spamreport1->show($this->user_prefs['report_safe']) ."&nbsp;". html::label($field_id .'_1', rcmail::Q($this->gettext('spamreport1'))) . "<br />";
+
+ $input_spamreport2 = new html_radiobutton(array('name' => '_spamreport', 'id' => $field_id.'_2', 'value' => '2'));
+ $table->add('title', html::label($field_id.'_2', rcmail::Q($this->gettext('spamreport2'))));
+ $table->add(null, $input_spamreport2->show($this->user_prefs['report_safe']));
+ }
+
+ $out = html::tag('fieldset', null, html::tag('legend', null, rcmail::Q($this->gettext('mainoptions'))) . $table->show());
+ break;
+
+ // Address settings
+ case 'addresses':
+ $data = html::p(null, rcmail::Q($this->gettext('whitelistexp')));
+
+ if ($rcmail->config->get('sauserprefs_whitelist_sync'))
+ $data .= rcmail::Q($this->gettext('autowhitelist')) . "<br /><br />";
+
+ $table = new html_table(array('class' => 'addressprefstable', 'cols' => 4));
+
+ $field_id = 'rcmfd_spamaddressrule';
+ $input_spamaddressrule = new html_select(array('name' => '_spamaddressrule', 'id' => $field_id));
+ $input_spamaddressrule->add($this->gettext('whitelist_from'),'whitelist_from');
+ $input_spamaddressrule->add($this->gettext('blacklist_from'), 'blacklist_from');
+ $input_spamaddressrule->add($this->gettext('whitelist_to'), 'whitelist_to');
+
+ $field_id = 'rcmfd_spamaddress';
+ $input_spamaddress = new html_inputfield(array('name' => '_spamaddress', 'id' => $field_id, 'style' => 'width:200px;'));
+
+ $field_id = 'rcmbtn_add_address';
+ $button_addaddress = $this->api->output->button(array('command' => 'plugin.sauserprefs.addressrule_add', 'type' => 'input', 'class' => 'button', 'label' => 'sauserprefs.addrule'));
+
+ $table->add('ruletype', $input_spamaddressrule->show());
+ $table->add('address', $input_spamaddress->show());
+ $table->add('action', $button_addaddress);
+ $table->add(null, "&nbsp;");
+
+ $import = $this->api->output->button(array('command' => 'plugin.sauserprefs.import_whitelist', 'type' => 'link', 'label' => 'import', 'title' => 'sauserprefs.importfromaddressbook'));
+ $delete_all = $this->api->output->button(array('command' => 'plugin.sauserprefs.whitelist_delete_all', 'type' => 'link', 'label' => 'sauserprefs.deleteall'));
+
+ $table->add(array('colspan' => 4, 'id' => 'listcontrols'), $import ."&nbsp;&nbsp;". $delete_all);
+
+ $address_table = new html_table(array('id' => 'address-rules-table', 'class' => 'records-table', 'cellspacing' => '0', 'cols' => 3));
+ $address_table->add_header('rule', $this->gettext('rule'));
+ $address_table->add_header('email', $this->gettext('email'));
+ $address_table->add_header('control', '&nbsp;');
+
+ $this->_address_row($address_table, null, null, $attrib);
+
+ if (sizeof($this->user_prefs['addresses']) > 0)
+ $norules = 'display: none;';
+
+ $address_table->set_row_attribs(array('style' => $norules));
+ $address_table->add(array('colspan' => '3'), rcube_utils::rep_specialchars_output($this->gettext('noaddressrules')));
+
+ $this->api->output->set_env('address_rule_count', sizeof($this->user_prefs['addresses']));
+ foreach ($this->user_prefs['addresses'] as $address)
+ $this->_address_row($address_table, $address['field'], $address['value'], $attrib);
+
+ $table->add(array('colspan' => 4, 'class' => 'scroller'), html::div(array('id' => 'address-rules-cont'), $address_table->show()));
+
+ if ($table->size())
+ $out = html::tag('fieldset', null, html::tag('legend', null, rcmail::Q($this->gettext('mainoptions'))) . $data . $table->show());
+
+ break;
+
+ default:
+ $out = '';
+ }
+
+ return $out;
+ }
+
+ private function _address_row($address_table, $field, $value, $attrib)
+ {
+ if (!isset($field))
+ $address_table->set_row_attribs(array('style' => 'display: none;'));
+
+ $hidden_action = new html_hiddenfield(array('name' => '_address_rule_act[]', 'value' => ''));
+ $hidden_field = new html_hiddenfield(array('name' => '_address_rule_field[]', 'value' => $field));
+ $hidden_text = new html_hiddenfield(array('name' => '_address_rule_value[]', 'value' => $value));
+
+ switch ($field)
+ {
+ case "whitelist_from":
+ $fieldtxt = rcube_utils::rep_specialchars_output($this->gettext('whitelist_from'));
+ break;
+ case "blacklist_from":
+ $fieldtxt = rcube_utils::rep_specialchars_output($this->gettext('blacklist_from'));
+ break;
+ case "whitelist_to":
+ $fieldtxt = rcube_utils::rep_specialchars_output($this->gettext('whitelist_to'));
+ break;
+ }
+
+ $address_table->add(array('class' => $field), $fieldtxt);
+ $address_table->add(array('class' => 'email'), $value);
+ $del_button = $this->api->output->button(array('command' => 'plugin.sauserprefs.addressrule_del', 'type' => 'link', 'class' => 'delete', 'label' => 'delete', 'content' => ' '));
+ $address_table->add('control', $del_button . $hidden_action->show() . $hidden_field->show() . $hidden_text->show());
+
+ return $address_table;
+ }
+
+ static function map_pref_name($pref, $reverse = false)
+ {
+ if (!$reverse) {
+ if (array_key_exists($pref, self::$deprecated_prefs))
+ $pref = self::$deprecated_prefs[$pref];
+ }
+ else {
+ if (($orig_pref = array_search($pref, self::$deprecated_prefs)) != FALSE)
+ $pref = $orig_pref;
+ }
+
+ return $pref;
+ }
+
+ private function _subval_sort($a, $subkey)
+ {
+ if (sizeof($a) == 0)
+ return array();
+
+ foreach ($a as $k => $v)
+ $b[$k] = strtolower($v[$subkey]);
+
+ asort($b);
+
+ foreach ($b as $k => $v)
+ $c[] = $a[$k];
+
+ return $c;
+ }
+
+ private function _gen_email_arr($contact)
+ {
+ $emails = array();
+
+ if (!is_array($contact))
+ return $emails;
+
+ foreach ($contact as $key => $value) {
+ if (preg_match('/^email(:(.+))?$/i', $key, $matches)) {
+ foreach ((array)$value as $subkey => $subval) {
+ if ($matches[2])
+ $emails[$matches[2] . $subkey] = $subval;
+ else
+ $emails['email' . $subkey] = $subval;
+ }
+ }
+ }
+
+ return $emails;
+ }
+}
+
+?> \ No newline at end of file
diff --git a/plugins/sauserprefs/skins/classic/help.gif b/plugins/sauserprefs/skins/classic/help.gif
new file mode 100644
index 000000000..ea7bbb363
--- /dev/null
+++ b/plugins/sauserprefs/skins/classic/help.gif
Binary files differ
diff --git a/plugins/sauserprefs/skins/classic/icons.gif b/plugins/sauserprefs/skins/classic/icons.gif
new file mode 100644
index 000000000..e52c33e51
--- /dev/null
+++ b/plugins/sauserprefs/skins/classic/icons.gif
Binary files differ
diff --git a/plugins/sauserprefs/skins/classic/icons.png b/plugins/sauserprefs/skins/classic/icons.png
new file mode 100644
index 000000000..065d880bd
--- /dev/null
+++ b/plugins/sauserprefs/skins/classic/icons.png
Binary files differ
diff --git a/plugins/sauserprefs/skins/classic/ie6hacks.css b/plugins/sauserprefs/skins/classic/ie6hacks.css
new file mode 100644
index 000000000..65c3e6af8
--- /dev/null
+++ b/plugins/sauserprefs/skins/classic/ie6hacks.css
@@ -0,0 +1,9 @@
+/**
+ * SAUserPrefs plugin styles (IE6 hacks)
+ */
+
+#spam-langs-table td.tick a,
+#address-rules-table td.control a
+{
+ background-image: url(icons.gif);
+} \ No newline at end of file
diff --git a/plugins/sauserprefs/skins/classic/iehacks.css b/plugins/sauserprefs/skins/classic/iehacks.css
new file mode 100644
index 000000000..0577d936c
--- /dev/null
+++ b/plugins/sauserprefs/skins/classic/iehacks.css
@@ -0,0 +1,9 @@
+/**
+ * SAUserPrefs plugin styles (IE hacks)
+ */
+
+#address-rules-table,
+#spam-langs-table
+{
+ width: expression('auto');
+} \ No newline at end of file
diff --git a/plugins/sauserprefs/skins/classic/safari.css b/plugins/sauserprefs/skins/classic/safari.css
new file mode 100644
index 000000000..0ff418083
--- /dev/null
+++ b/plugins/sauserprefs/skins/classic/safari.css
@@ -0,0 +1,6 @@
+/**
+ * SAUserPrefs plugin styles (safari hacks)
+ */
+
+html>body*#address-rules-table[id$="address-rules-table"]:not([class="none"]) { table-layout: auto; }
+html>body*#spam-langs-table[id$="spam-langs-table"]:not([class="none"]) { table-layout: auto; } \ No newline at end of file
diff --git a/plugins/sauserprefs/skins/classic/sauserprefs.css b/plugins/sauserprefs/skins/classic/sauserprefs.css
new file mode 100644
index 000000000..81ba60250
--- /dev/null
+++ b/plugins/sauserprefs/skins/classic/sauserprefs.css
@@ -0,0 +1,185 @@
+/**
+ * SAUserPrefs plugin styles
+ */
+
+#address-rules-cont,
+#spam-langs-cont
+{
+ border: 1px solid #999999;
+ background-color: #F9F9F9;
+ height: 200px;
+ overflow: auto;
+ width: 510px;
+}
+
+body.address-rules-table,
+body.spam-langs-table
+{
+ margin: 0px;
+ background-color: #F9F9F9;
+}
+
+#address-rules-table,
+#spam-langs-table
+{
+ width: 100%;
+ display: table;
+ table-layout: fixed;
+}
+
+#address-rules-table thead td.rule
+{
+ width: 180px;
+}
+
+#address-rules-table thead td.control
+{
+ width: 40px;
+}
+
+#spam-langs-table td.lang,
+#address-rules-table td.rule,
+#address-rules-table td.email,
+#address-rules-table td.email
+{
+ text-align: left;
+ vertical-align: middle;
+}
+
+#spam-langs-table td.tick,
+#address-rules-table td.control
+{
+ text-align: right;
+ vertical-align: middle;
+}
+
+#spam-langs-table td.tick a,
+#address-rules-table td.control a
+{
+ display: block;
+ float: right;
+ width: 16px;
+ height: 16px;
+ background-image: url(icons.png);
+}
+
+#address-rules-table td.control a.delete
+{
+ background-position: 0 0;
+}
+
+#spam-langs-table td.tick a.enabled
+{
+ background-position: 0 -18px;
+}
+
+#spam-langs-table td.tick a.disabled
+{
+ background-position: 0 -36px;
+}
+
+.whitelist_from,
+.whitelist_to
+{
+ color: #008800;
+ text-align: left;
+ vertical-align: middle;
+
+}
+
+.blacklist_from
+{
+ color: #BB0000;
+ text-align: left;
+ vertical-align: middle;
+}
+
+#listcontrols
+{
+ font-size: 11px;
+ text-align: right;
+}
+
+#listcontrols a,
+#listcontrols a:active,
+#listcontrols a:visited
+{
+ color: #CC0000;
+ font-size: 11px;
+ text-decoration: none;
+}
+
+#listcontrols a:hover
+{
+ text-decoration: underline;
+}
+
+table.generalprefstable,
+table.headersprefstable,
+table.testsprefstable,
+table.bayesprefstable,
+table.reportprefstable
+{
+ width: 100%;
+}
+
+table.generalprefstable td.title
+{
+ width: 115px;
+}
+
+table.headersprefstable td.title
+{
+ width: 220px;
+}
+
+table.testsprefstable td.title
+{
+ width: 175px;
+}
+
+table.bayesprefstable td.title
+{
+ width: 220px;
+}
+
+table.reportprefstable td.title
+{
+ width: 320px;
+}
+
+table.generalprefstable td.help,
+table.langprefstable td.help,
+table.headersprefstable td.help,
+table.testsprefstable td.help,
+table.bayesprefstable td.help,
+table.reportprefstable td.help,
+table.addressprefstable td.help
+{
+ text-align: right;
+}
+
+table.addressprefstable td.ruletype
+{
+ width: 180px;
+ padding-bottom: 10px;
+}
+
+table.addressprefstable td.address
+{
+ width: 220px;
+ padding-bottom: 10px;
+}
+
+table.addressprefstable td.action
+{
+ width: 100px;
+ text-align: right;
+ padding-bottom: 10px;
+}
+
+table.langprefstable td.scroller,
+table.addressprefstable td.scroller
+{
+ padding: 0;
+} \ No newline at end of file
diff --git a/plugins/sauserprefs/skins/classic/tabstyles.css b/plugins/sauserprefs/skins/classic/tabstyles.css
new file mode 100644
index 000000000..c3cfaa4ac
--- /dev/null
+++ b/plugins/sauserprefs/skins/classic/tabstyles.css
@@ -0,0 +1,3 @@
+/**
+ * SAUserPrefs plugin styles (tab styles)
+ */
diff --git a/plugins/sauserprefs/skins/classic/templates/sauserprefs.html b/plugins/sauserprefs/skins/classic/templates/sauserprefs.html
new file mode 100644
index 000000000..dae567837
--- /dev/null
+++ b/plugins/sauserprefs/skins/classic/templates/sauserprefs.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title><roundcube:object name="pagetitle" /></title>
+<roundcube:include file="/includes/links.html" />
+<link rel="stylesheet" type="text/css" href="/this/sauserprefs.css" />
+<roundcube:if condition="browser:ie" />
+<link rel="stylesheet" type="text/css" href="/this/iehacks.css" />
+<roundcube:endif />
+<roundcube:if condition="browser:safari" />
+<link rel="stylesheet" type="text/css" href="/this/safari.css" />
+<roundcube:endif />
+<script type="text/javascript" src="/functions.js"></script>
+<script type="text/javascript" src="/splitter.js"></script>
+
+<style type="text/css">
+#sectionslist { width: <roundcube:exp expression="!empty(cookie:spamprefsviewsplitter) ? cookie:spamprefsviewsplitter-5 : 190" />px; }
+#prefs-box { left: <roundcube:exp expression="!empty(cookie:spamprefsviewsplitter) ? cookie:spamprefsviewsplitter+5 : 200" />px;
+<roundcube:exp expression="browser:ie ? ('width:expression((parseInt(this.parentNode.offsetWidth)-'.(!empty(cookie:spamprefsviewsplitter) ? cookie:spamprefsviewsplitter+5 : 200).')+\\'px\\');') : ''" />
+}
+</style>
+</head>
+<body>
+
+<roundcube:include file="/includes/taskbar.html" />
+<roundcube:include file="/includes/header.html" />
+<roundcube:include file="/includes/settingstabs.html" />
+
+<div id="mainscreen">
+
+<div id="sectionslist">
+<roundcube:object name="sasectionslist" id="sections-table" class="records-table" cellspacing="0" />
+</div>
+
+<script type="text/javascript">
+ var spamprefviewsplit = new rcube_splitter({id:'spamprefsviewsplitter', p1: 'sectionslist', p2: 'prefs-box', orientation: 'v', relative: true, start: 195});
+ rcmail.add_onload('spamprefviewsplit.init()');
+</script>
+
+<div id="prefs-box">
+<roundcube:object name="saprefsframe" id="prefs-frame" width="100%" height="100%" frameborder="0" src="/watermark.html" />
+</div>
+
+</div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/plugins/sauserprefs/skins/classic/templates/settingsedit.html b/plugins/sauserprefs/skins/classic/templates/settingsedit.html
new file mode 100644
index 000000000..73ba59880
--- /dev/null
+++ b/plugins/sauserprefs/skins/classic/templates/settingsedit.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title><roundcube:object name="pagetitle" /></title>
+<roundcube:include file="/includes/links.html" />
+<link rel="stylesheet" type="text/css" href="/this/sauserprefs.css" />
+<roundcube:if condition="browser:ie" />
+<link rel="stylesheet" type="text/css" href="/this/iehacks.css" />
+<roundcube:endif />
+<roundcube:if condition="browser:safari" />
+<link rel="stylesheet" type="text/css" href="/this/safari.css" />
+<roundcube:endif />
+<!--[if lte IE 6]><link rel="stylesheet" type="text/css" href="/this//ie6hacks.css" /><![endif]-->
+<script type="text/javascript" src="/functions.js"></script>
+</head>
+<body class="iframe">
+
+<div id="prefs-title" class="boxtitle"><roundcube:object name="sectionname" /></div>
+
+<div id="prefs-details" class="boxcontent">
+<roundcube:object name="userprefs" form="form" helpIcon="/this/help.gif" />
+<div id="formfooter">
+<div class="footerleft">
+<roundcube:button command="plugin.sauserprefs.default" type="input" class="button" label="sauserprefs.usedefault" style="margin-right:0.5em" />
+<roundcube:button command="plugin.sauserprefs.save" type="input" class="button mainaction" label="save" />
+</div>
+</div>
+</div>
+
+<p>&nbsp;</p>
+
+</body>
+</html> \ No newline at end of file
diff --git a/plugins/sauserprefs/skins/larry/help.png b/plugins/sauserprefs/skins/larry/help.png
new file mode 100644
index 000000000..9f7a6ae44
--- /dev/null
+++ b/plugins/sauserprefs/skins/larry/help.png
Binary files differ
diff --git a/plugins/sauserprefs/skins/larry/icons.png b/plugins/sauserprefs/skins/larry/icons.png
new file mode 100644
index 000000000..6e070901e
--- /dev/null
+++ b/plugins/sauserprefs/skins/larry/icons.png
Binary files differ
diff --git a/plugins/sauserprefs/skins/larry/iehacks.css b/plugins/sauserprefs/skins/larry/iehacks.css
new file mode 100644
index 000000000..0577d936c
--- /dev/null
+++ b/plugins/sauserprefs/skins/larry/iehacks.css
@@ -0,0 +1,9 @@
+/**
+ * SAUserPrefs plugin styles (IE hacks)
+ */
+
+#address-rules-table,
+#spam-langs-table
+{
+ width: expression('auto');
+} \ No newline at end of file
diff --git a/plugins/sauserprefs/skins/larry/listicons.png b/plugins/sauserprefs/skins/larry/listicons.png
new file mode 100644
index 000000000..3571ac6c4
--- /dev/null
+++ b/plugins/sauserprefs/skins/larry/listicons.png
Binary files differ
diff --git a/plugins/sauserprefs/skins/larry/safari.css b/plugins/sauserprefs/skins/larry/safari.css
new file mode 100644
index 000000000..0ff418083
--- /dev/null
+++ b/plugins/sauserprefs/skins/larry/safari.css
@@ -0,0 +1,6 @@
+/**
+ * SAUserPrefs plugin styles (safari hacks)
+ */
+
+html>body*#address-rules-table[id$="address-rules-table"]:not([class="none"]) { table-layout: auto; }
+html>body*#spam-langs-table[id$="spam-langs-table"]:not([class="none"]) { table-layout: auto; } \ No newline at end of file
diff --git a/plugins/sauserprefs/skins/larry/sauserprefs.css b/plugins/sauserprefs/skins/larry/sauserprefs.css
new file mode 100644
index 000000000..41dfab2e2
--- /dev/null
+++ b/plugins/sauserprefs/skins/larry/sauserprefs.css
@@ -0,0 +1,253 @@
+/**
+ * SAUserPrefs plugin styles
+ */
+
+#address-rules-cont,
+#spam-langs-cont
+{
+ height: 200px;
+ overflow: auto;
+ width: 100%;
+}
+
+body.address-rules-table,
+body.spam-langs-table
+{
+ margin: 0px;
+}
+
+#address-rules-table,
+#spam-langs-table
+{
+ width: 100%;
+ display: table;
+ table-layout: fixed;
+ border: 0;
+}
+
+#address-rules-table thead td,
+#spam-langs-table thead td
+{
+ background-color: #CCC;
+ font-weight: bold;
+ color: #000;
+}
+
+#address-rules-table thead td.rule
+{
+ width: 180px;
+}
+
+#address-rules-table thead td.control
+{
+ width: 40px;
+}
+
+#spam-langs-table td.lang,
+#address-rules-table td.rule,
+#address-rules-table td.email,
+#address-rules-table td.email
+{
+ text-align: left;
+ vertical-align: middle;
+ border-left: 0;
+ border-right: 0;
+}
+
+#spam-langs-table td.tick,
+#address-rules-table td.control
+{
+ text-align: right;
+ vertical-align: middle;
+ border-left: 0;
+ border-right: 0;
+}
+
+#spam-langs-table td.tick a,
+#address-rules-table td.control a
+{
+ display: block;
+ float: right;
+ width: 16px;
+ height: 16px;
+ background-image: url(icons.png);
+ cursor: pointer;
+}
+
+#address-rules-table td.control a.delete
+{
+ background-position: 0 -1px;
+}
+
+#spam-langs-table td.tick a.enabled
+{
+ background-position: 0 -18px;
+}
+
+#spam-langs-table td.tick a.disabled
+{
+ background-position: 0 -36px;
+}
+
+.whitelist_from,
+.whitelist_to
+{
+ color: #008800;
+ text-align: left;
+ vertical-align: middle;
+}
+
+.blacklist_from
+{
+ color: #BB0000;
+ text-align: left;
+ vertical-align: middle;
+}
+
+#listcontrols
+{
+ font-size: 11px;
+ text-align: right;
+}
+
+#listcontrols a,
+#listcontrols a:active,
+#listcontrols a:visited
+{
+ color: #2D5986;
+ font-size: 11px;
+ text-decoration: none;
+}
+
+#listcontrols a:hover
+{
+ text-decoration: underline;
+}
+
+table.generalprefstable,
+table.langprefstable,
+table.headersprefstable,
+table.testsprefstable,
+table.bayesprefstable,
+table.reportprefstable,
+table.addressprefstable
+{
+ width: 100%;
+ border-spacing: 0;
+ border-collapse: collapse;
+}
+
+table.generalprefstable td,
+table.langprefstable td,
+table.headersprefstable td,
+table.testsprefstable td,
+table.bayesprefstable td,
+table.reportprefstable td,
+table.addressprefstable td
+{
+ width: 80%;
+ padding: 4px 10px;
+ background: #eee;
+ border-bottom: 2px solid #fff;
+}
+
+table.addressprefstable td
+{
+ width: auto;
+}
+
+table.generalprefstable td.title,
+table.langprefstable td.title,
+table.headersprefstable td.title,
+table.testsprefstable td.title,
+table.bayesprefstable td.title,
+table.reportprefstable td.title,
+table.addressprefstable td.title
+{
+ width: 20%;
+ color: #333;
+ padding-right: 20px;
+ white-space: nowrap;
+}
+
+table.addressprefstable td.ruletype
+{
+ width: 180px;
+}
+
+table.addressprefstable td.address
+{
+ width: 220px;
+}
+
+table.addressprefstable td.action
+{
+ width: 100px;
+ text-align: right;
+}
+
+table.langprefstable td.scroller,
+table.addressprefstable td.scroller
+{
+ padding: 0;
+}
+
+#sections-table #rcmrowtests td.section
+{
+ background-image: url(listicons.png);
+ background-position: 5px -199px;
+}
+
+#sections-table #rcmrowtests.selected td.section
+{
+ background-image: url(listicons.png);
+ background-position: 5px -225px;
+}
+
+#sections-table #rcmrowbayes td.section
+{
+ background-image: url(listicons.png);
+ background-position: 5px -248px;
+}
+
+#sections-table #rcmrowbayes.selected td.section
+{
+ background-image: url(listicons.png);
+ background-position: 5px -270px;
+}
+
+#sections-table #rcmrowheaders td.section
+{
+ background-image: url(listicons.png);
+ background-position: 5px -99px;
+}
+
+#sections-table #rcmrowheaders.selected td.section
+{
+ background-image: url(listicons.png);
+ background-position: 5px -124px;
+}
+
+#sections-table #rcmrowreport td.section
+{
+ background-image: url(listicons.png);
+ background-position: 5px -150px;
+}
+
+#sections-table #rcmrowreport.selected td.section
+{
+ background-image: url(listicons.png);
+ background-position: 5px -174px;
+}
+
+#sections-table #rcmrowaddresses td.section
+{
+ background-image: url(listicons.png);
+ background-position: 4px -50px;
+}
+
+#sections-table #rcmrowaddresses.selected td.section
+{
+ background-image: url(listicons.png);
+ background-position: 4px -74px;
+} \ No newline at end of file
diff --git a/plugins/sauserprefs/skins/larry/tabstyles.css b/plugins/sauserprefs/skins/larry/tabstyles.css
new file mode 100644
index 000000000..c22f8199a
--- /dev/null
+++ b/plugins/sauserprefs/skins/larry/tabstyles.css
@@ -0,0 +1,15 @@
+/**
+ * SAUserPrefs plugin styles (tab styles)
+ */
+
+#settings-sections #settingstabpluginsauserprefs a
+{
+ background-image: url(listicons.png);
+ background-position: 3px -3px;
+}
+
+#settings-sections #settingstabpluginsauserprefs.selected a
+{
+ background-image: url(listicons.png);
+ background-position: 3px -27px;
+} \ No newline at end of file
diff --git a/plugins/sauserprefs/skins/larry/templates/sauserprefs.html b/plugins/sauserprefs/skins/larry/templates/sauserprefs.html
new file mode 100644
index 000000000..6f734f092
--- /dev/null
+++ b/plugins/sauserprefs/skins/larry/templates/sauserprefs.html
@@ -0,0 +1,54 @@
+<roundcube:object name="doctype" value="html5" />
+<html>
+<head>
+<title><roundcube:object name="pagetitle" /></title>
+<roundcube:include file="/includes/links.html" />
+<link rel="stylesheet" type="text/css" href="/this/sauserprefs.css" />
+<roundcube:if condition="browser:ie" />
+<link rel="stylesheet" type="text/css" href="/this/iehacks.css" />
+<roundcube:endif />
+<roundcube:if condition="browser:safari" />
+<link rel="stylesheet" type="text/css" href="/this/safari.css" />
+<roundcube:endif />
+</head>
+<body class="noscroll">
+
+<roundcube:include file="/includes/header.html" />
+
+<div id="mainscreen" class="offset">
+
+<roundcube:include file="/includes/settingstabs.html" />
+
+<div id="settings-right">
+
+<div id="sectionslist" class="uibox listbox">
+<div class="scroller">
+ <roundcube:object name="sasectionslist" id="sections-table" class="listing" />
+</div>
+</div>
+
+<div id="preferences-box" class="uibox contentbox">
+<div class="iframebox">
+ <roundcube:object name="saprefsframe" id="preferences-frame" style="width:100%; height:100%" frameborder="0" src="/watermark.html" />
+</div>
+<roundcube:object name="message" id="message" class="statusbar" />
+</div>
+
+</div>
+
+</div>
+
+<roundcube:include file="/includes/footer.html" />
+
+<script type="text/javascript">
+/* <![CDATA[ */
+
+$(document).ready(function(){
+ new rcube_splitter({id:'sauserprefssplitter', p1: '#sectionslist', p2: '#preferences-box', orientation: 'v', relative: true, start: 240}).init();
+});
+
+/* ]]> */
+</script>
+
+</body>
+</html> \ No newline at end of file
diff --git a/plugins/sauserprefs/skins/larry/templates/settingsedit.html b/plugins/sauserprefs/skins/larry/templates/settingsedit.html
new file mode 100644
index 000000000..302288027
--- /dev/null
+++ b/plugins/sauserprefs/skins/larry/templates/settingsedit.html
@@ -0,0 +1,30 @@
+<roundcube:object name="doctype" value="html5" />
+<html>
+<head>
+<title><roundcube:object name="pagetitle" /></title>
+<roundcube:include file="/includes/links.html" />
+<link rel="stylesheet" type="text/css" href="/this/sauserprefs.css" />
+<roundcube:if condition="browser:ie" />
+<link rel="stylesheet" type="text/css" href="/this/iehacks.css" />
+<roundcube:endif />
+<roundcube:if condition="browser:safari" />
+<link rel="stylesheet" type="text/css" href="/this/safari.css" />
+<roundcube:endif />
+</head>
+<body class="iframe">
+
+<h1 class="boxtitle"><roundcube:object name="sectionname" /></h1>
+
+<div id="preferences-details" class="boxcontent">
+<roundcube:object name="userprefs" form="form" class="propform" helpIcon="/this/help.png" />
+</div>
+
+<div class="footerleft formbuttons">
+<roundcube:button command="plugin.sauserprefs.save" type="input" class="button mainaction" label="save" />
+<roundcube:button command="plugin.sauserprefs.default" type="input" class="button" label="sauserprefs.usedefault" style="margin-right:0.5em" />
+</div>
+
+<roundcube:include file="/includes/footer.html" />
+
+</body>
+</html> \ No newline at end of file
diff --git a/plugins/sieverules/config.inc.php.dist b/plugins/sieverules/config.inc.php.dist
new file mode 100644
index 000000000..7d8f48238
--- /dev/null
+++ b/plugins/sieverules/config.inc.php.dist
@@ -0,0 +1,147 @@
+<?php
+
+/**
+ * SieveRules configuration file
+ */
+
+// managesieve server address
+// The host can contain the following macros that will be expanded as follows:
+// %n - hostname ($_SERVER['SERVER_NAME'])
+// %t - hostname without the first part
+// %d - domain (http hostname $_SERVER['HTTP_HOST'] without the first part)
+// %s - domain name after the '@' from e-mail address provided at login screen
+// For example %n = mail.domain.tld, %t = domain.tld
+$rcmail_config['sieverules_host'] = 'localhost';
+
+// managesieve server port
+$rcmail_config['sieverules_port'] = 2000;
+
+// Log managesieve conversation to <log_dir>/sieverules or to syslog
+$rcmail_config['sieverules_debug'] = false;
+
+// authentication method. Can be CRAM-MD5, DIGEST-MD5, PLAIN, LOGIN, EXTERNAL
+// or none. Optional, defaults to best method supported by server.
+$rcmail_config['sieverules_auth_type'] = null;
+
+// optional managesieve authentication identifier to be used as authorization proxy,
+// authenticate as a different user but act on behalf of the logged in user,
+// works with PLAIN and DIGEST-MD5 auth.
+$rcmail_config['sieverules_auth_cid'] = null;
+
+// optional managesieve authentication password to be used for sieverules_auth_cid
+$rcmail_config['sieverules_auth_pw'] = null;
+
+// enable TLS for managesieve server connection
+$rcmail_config['sieverules_usetls'] = FALSE;
+
+// folder delimiter - if your sieve system uses a different folder delimiter to
+// your IMAP server set it here, otherwise leave as null to use IMAP delimiter
+$rcmail_config['sieverules_folder_delimiter'] = null;
+
+// Sieve RFC says that we should use UTF-8 encoding for mailbox names,
+// but some implementations does not covert UTF-8 to modified UTF-7.
+// set to null for default behaviour
+$rcmail_config['sieverules_folder_encoding'] = null;
+
+// include the IMAP root in the folder path when creating the rules
+// set to false to never include the IMAP root in the folder path
+// set to null for default behaviour
+$rcmail_config['sieverules_include_imap_root'] = null;
+
+// ruleset name
+$rcmail_config['sieverules_ruleset_name'] = 'roundcube';
+
+// allow multiple actions
+$rcmail_config['sieverules_multiple_actions'] = TRUE;
+
+// allowed actions
+$rcmail_config['sieverules_allowed_actions'] = array(
+ 'fileinto' => TRUE,
+ 'vacation' => TRUE,
+ 'reject' => TRUE,
+ 'redirect' => TRUE,
+ 'keep' => TRUE,
+ 'discard' => TRUE,
+ 'imapflags' => TRUE,
+ 'notify' => TRUE,
+ 'stop' => TRUE,
+ 'editheaderadd' => TRUE,
+ 'editheaderrem' => TRUE
+ );
+
+// headers listed as examples of "Other headers"
+$rcmail_config['sieverules_other_headers'] = array(
+ 'Reply-To', 'List-Id', 'MailingList', 'Mailing-List',
+ 'X-ML-Name', 'X-List', 'X-List-Name', 'X-Mailing-List',
+ 'Resent-From', 'Resent-To', 'X-Mailer', 'X-MailingList',
+ 'X-Spam-Status', 'X-Priority', 'Importance', 'X-MSMail-Priority',
+ 'Precedence', 'Return-Path', 'Received', 'Auto-Submitted',
+ 'X-Spam-Flag', 'X-Spam-Tests', 'Sender',
+ );
+
+// Predefined rules
+// each rule should be in it own array - examples provided in README
+// 'name' => name of the rule, displayed in the rule type select box
+// 'type' => one of: header, address, envelope, size
+// 'header' => name of the header to test
+// 'operator' => operator to use, for all possible values please see README
+// 'extra' => extra information needed for the rule in some cases
+// 'target' => value that the header is tested against
+$rcmail_config['sieverules_predefined_rules'] = array();
+
+// Advanced editor
+// allows the user to edit the sieve file directly, without the restrictions of the normal UI
+// 0 - Disabled, option not shown in the UI
+// 1 - Enabled, option shown in the UI
+// 2 - Option shown in the UI and used by default
+$rcmail_config['sieverules_adveditor'] = 0;
+
+// Allow users to use multiple rulesets
+$rcmail_config['sieverules_multiplerules'] = FALSE;
+
+// Default (or global) sieve rule file
+$rcmail_config['sieverules_default_file'] = '/etc/dovecot/sieve/default';
+
+// Auto load default sieve rule file if no rules exist and no import filters match
+$rcmail_config['sieverules_auto_load_default'] = FALSE;
+
+// Example sieve rule file
+$rcmail_config['sieverules_example_file'] = '/etc/dovecot/sieve/example';
+
+// Force the :addresses line to always be added to new vacation rules
+// Some sieve setups require that the :address part of a vacation rule is always present for the message to be sent
+// Cyrus setups need this to option set to true
+$rcmail_config['sieverules_force_vacto'] = FALSE;
+
+// Limit the selection of :addresses available to only those setup in as an identity
+// Setting this to false will give the user a textbox to enter in any address(es) they like, rather than a list of checkboxes
+$rcmail_config['sieverules_limit_vacto'] = TRUE;
+
+// Allow users to set the :from option when creating new vacation rules, not all servers support this option
+// If your server supports the variables extension users also have an 'auto detect' option which will detect the address to which the message was sent
+// Else the user's default identity will be used as the default value
+$rcmail_config['sieverules_show_vacfrom'] = FALSE;
+
+// Allow users to set the :handle option when creating new vacation rules, not all servers support this option
+$rcmail_config['sieverules_show_vachandle'] = FALSE;
+
+// The rule file can be written as one IF/ELSIF statement or as a series of unrelated IF statements
+// TRUE - one IF/ELSIF statement (default)
+// FALSE - a series of unrelated IF statements
+$rcmail_config['sieverules_use_elsif'] = TRUE;
+
+// Fileinto action options
+// 0 - List only subscribed folders
+// 1 - List subscribed and unsubscribed folders
+// 2 - List subscribed and unsubscribed folders and allow users to enter a folder name (for advanced users only, requires sieve mailbox extension)
+$rcmail_config['sieverules_fileinto_options'] = 0;
+
+// Define the format of the :from option value for vacation and notify actions
+// 0 - Use only the email address - :from "user@example.com"
+// 1 - Use the name and email address, not all servers support this option - :from "First Last <user@example.com>"
+$rcmail_config['sieverules_from_format'] = 0;
+
+// For information on customising the rule file see "The structure of the rule file" in the README
+// For information on customising the contents of the drop downs see "Default values for header, operator and flag drop downs" in the README
+
+?> \ No newline at end of file
diff --git a/plugins/sieverules/importFilters/avelsieve.php b/plugins/sieverules/importFilters/avelsieve.php
new file mode 100644
index 000000000..c1e3fef9a
--- /dev/null
+++ b/plugins/sieverules/importFilters/avelsieve.php
@@ -0,0 +1,54 @@
+<?php
+
+/**
+ * SieveRules import filter for Avelsieve
+ *
+ * The class should be named 'srimport_[filename]'
+ * Each import filter must have:
+ * An attribute called name
+ * A pubic function called detector
+ * A pubic function called importer
+ * The importer function can return either a string to be parsed by the SieveRules parser
+ * or an array, similar to the one created by the SieveRules parser
+ */
+class srimport_avelsieve
+{
+ public $name = 'Squirrelmail (Avelsieve)';
+
+ public function detector($script)
+ {
+ return preg_match('/#AVELSIEVE_VERSION.*/', $script) ? True : False;
+ }
+
+ public function importer($script)
+ {
+ $i = 0;
+ $content = '';
+ $name = array();
+
+ // tokenize rules
+ if ($tokens = preg_split('/(#START_SIEVE_RULE.*END_SIEVE_RULE)\n/', $script, -1, PREG_SPLIT_DELIM_CAPTURE)) {
+ foreach($tokens as $token) {
+ if (preg_match('/(require\s+\[.*\];)/i', $token, $matches)) {
+ $content .= $matches[1] . "\n";
+ }
+ elseif (!preg_match('/^#START_SIEVE_RULE.*/', $token, $matches)) {
+ $rulename = "# rule:[";
+ $parts = explode ('"', trim($token));
+
+ for ($i = 1; $i < count($parts); $i+=2)
+ $rulename .= $parts[$i] . " ";
+
+ $rulename .= "]\n";
+ $content .= $rulename;
+
+ $content .= trim($token) . "\n";
+ }
+ }
+ }
+
+ return $content;
+ }
+}
+
+?> \ No newline at end of file
diff --git a/plugins/sieverules/importFilters/ingo.php b/plugins/sieverules/importFilters/ingo.php
new file mode 100644
index 000000000..8d85ce6e1
--- /dev/null
+++ b/plugins/sieverules/importFilters/ingo.php
@@ -0,0 +1,52 @@
+<?php
+
+/**
+ * SieveRules import filter for INGO
+ *
+ * The class should be named 'srimport_[filename]'
+ * Each import filter must have:
+ * An attribute called name
+ * A pubic function called detector
+ * A pubic function called importer
+ * The importer function can return either a string to be parsed by the SieveRules parser
+ * or an array, similar to the one created by the SieveRules parser
+ */
+class srimport_ingo
+{
+ public $name = 'Horde (INGO)';
+
+ public function detector($script)
+ {
+ return preg_match('/# [a-z0-9\ ]+/i', $script) ? True : False;
+ }
+
+ public function importer($script)
+ {
+ $i = 0;
+ $name = array();
+ // tokenize rules
+ if ($tokens = preg_split('/(# .+)\r?\n/i', $script, -1, PREG_SPLIT_DELIM_CAPTURE)) {
+ // unset first token, its the ingo header
+ $tokens[1] = "";
+
+ foreach($tokens as $token) {
+ if (preg_match('/^# (.+)/i', $token, $matches)) {
+ $name[$i] = $matches[1];
+ $content .= "# rule:[" . $name[$i] . "]\n";
+ }
+ elseif (isset($name[$i])) {
+ $token = str_replace(":comparator \"i;ascii-casemap\" ", "", $token);
+ $content .= $token . "\n";
+ $i++;
+ }
+ elseif (preg_match('/^\r?\n?require/i', $token)) {
+ $content .= $token . "\n";
+ }
+ }
+ }
+
+ return $content;
+ }
+}
+
+?> \ No newline at end of file
diff --git a/plugins/sieverules/include/rcube_sieve.php b/plugins/sieverules/include/rcube_sieve.php
new file mode 100644
index 000000000..a5fd9649a
--- /dev/null
+++ b/plugins/sieverules/include/rcube_sieve.php
@@ -0,0 +1,249 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | rcube_sieve class for managesieve operations (using PEAR::Net_Sieve) |
+ | |
+ | Author: Aleksander Machniak <alec@alec.pl> |
+ | Modifications by: Philip Weir |
+ | * Make ruleset name configurable |
+ | * Added import functions |
+ +-----------------------------------------------------------------------+
+*/
+
+define('SIEVE_ERROR_CONNECTION', 1);
+define('SIEVE_ERROR_LOGIN', 2);
+define('SIEVE_ERROR_NOT_EXISTS', 3); // script not exists
+define('SIEVE_ERROR_INSTALL', 4); // script installation
+define('SIEVE_ERROR_ACTIVATE', 5); // script activation
+define('SIEVE_ERROR_OTHER', 255); // other/unknown error
+
+class rcube_sieve
+{
+ private $sieve;
+ private $ruleset;
+ private $importers = array();
+ private $elsif;
+ private $cache = false;
+ public $error = false;
+ public $list = array();
+ public $script;
+
+ public function __construct($username, $password, $host, $port, $auth_type = NULL, $usetls, $ruleset, $dir, $elsif = true, $auth_cid = NULL, $auth_pw = NULL)
+ {
+ $this->sieve = new Net_Sieve();
+
+ $data = rcube::get_instance()->plugins->exec_hook('sieverules_connect', array(
+ 'username' => $username, 'password' => $password, 'host' => $host, 'port' => $port,
+ 'auth_type' => $auth_type, 'usetls' => $usetls, 'ruleset' => $ruleset, 'dir' => $dir,
+ 'elsif' => $elsif, 'auth_cid' => $auth_cid, 'auth_pw' => $auth_pw));
+
+ $username = $data['username'];
+ $password = $data['password'];
+ $host = $data['host'];
+ $port = $data['port'];
+ $auth_type = $data['auth_type'];
+ $usetls = $data['usetls'];
+ $ruleset = $data['ruleset'];
+ $dir = $data['dir'];
+ $elsif = $data['elsif'];
+ $auth_cid = $data['auth_cid'];
+ $auth_pw = $data['auth_pw'];
+
+ if (PEAR::isError($this->sieve->connect($host, $port, NULL, $usetls)))
+ return $this->_set_error(SIEVE_ERROR_CONNECTION);
+
+ if (!empty($auth_cid)) {
+ $authz = $username;
+ $username = $auth_cid;
+ $password = $auth_pw;
+ }
+
+ if (PEAR::isError($this->sieve->login($username, $password, $auth_type ? strtoupper($auth_type) : NULL, $authz)))
+ return $this->_set_error(SIEVE_ERROR_LOGIN);
+
+ $this->ruleset = $ruleset;
+ $this->elsif = $elsif;
+
+ if ($this->ruleset !== false) {
+ $this->get_script();
+ }
+ else {
+ $this->ruleset = $this->get_active();
+ $this->get_script();
+ }
+
+ // init importers
+ $dir = slashify(realpath(slashify($dir) . 'importFilters/'));
+ $handle = opendir($dir);
+ while ($importer = readdir($handle)) {
+ if (is_file($dir . $importer) && is_readable($dir . $importer)) {
+ include($dir . $importer);
+
+ $importer = substr($importer, 0, -4);
+ $importer = 'srimport_' . $importer;
+
+ if (class_exists($importer, false)) {
+ $importerClass = new $importer();
+ $this->importers[$importer] = $importerClass;
+ }
+ }
+ }
+ closedir($handle);
+ }
+
+ public function __destruct()
+ {
+ $this->sieve->disconnect();
+ }
+
+ public function error()
+ {
+ return $this->error ? $this->error : false;
+ }
+
+ public function save($script = '')
+ {
+ if (!$script)
+ $script = $this->script->as_text();
+
+ if (!$script)
+ $script = '/* empty script */';
+
+ // allow additional actions before ruleset is saved
+ $data = rcube::get_instance()->plugins->exec_hook('sieverules_save', array(
+ 'ruleset' => $this->ruleset, 'script' => $script));
+
+ if ($data['abort'])
+ return $data['message'] ? $data['message'] : false;
+
+ if (PEAR::isError($this->sieve->installScript($this->ruleset, $data['script'])))
+ return $this->_set_error(SIEVE_ERROR_INSTALL);
+
+ if ($this->cache) $_SESSION['sieverules_script_cache_' . $this->ruleset] = serialize($this->script);
+
+ return true;
+ }
+
+ public function get_extensions()
+ {
+ if ($this->sieve) {
+ $ext = $this->sieve->getExtensions();
+ $ext = array_map('strtolower', (array) $ext);
+ return $ext;
+ }
+ }
+
+ public function check_import()
+ {
+ $result = false;
+
+ foreach ($this->list as $ruleset) {
+ if ($ruleset == $this->ruleset)
+ continue;
+
+ $script = $this->sieve->getScript($ruleset);
+
+ foreach ($this->importers as $id => $importer) {
+ if ($importer->detector($script)) {
+ $result = array($id, $importer->name, $ruleset);
+ break;
+ }
+ }
+ }
+
+ return $result;
+ }
+
+ public function do_import($type, $ruleset)
+ {
+ $script = $this->sieve->getScript($ruleset);
+ $content = $this->importers[$type]->importer($script);
+ $this->script->import_filters($content);
+
+ if (is_array($content))
+ return $this->save();
+ else
+ return $this->save($content);
+ }
+
+ public function get_script()
+ {
+ if (!$this->sieve)
+ return false;
+
+ if ($this->cache && $_SESSION['sieverules_script_cache']) {
+ $this->list = unserialize($_SESSION['sieverules_scripts_list']);
+ $this->script = unserialize($_SESSION['sieverules_script_cache_' . $this->ruleset]);
+ return;
+ }
+
+ $this->list = $this->sieve->listScripts();
+
+ if (PEAR::isError($this->list))
+ return $this->_set_error(SIEVE_ERROR_OTHER);
+
+ if (in_array($this->ruleset, $this->list)) {
+ $script = $this->sieve->getScript($this->ruleset);
+
+ if (PEAR::isError($script))
+ return $this->_set_error(SIEVE_ERROR_OTHER);
+ }
+ else {
+ $this->_set_error(SIEVE_ERROR_NOT_EXISTS);
+ $script = '';
+ }
+
+ $data = rcube::get_instance()->plugins->exec_hook('sieverules_load', array(
+ 'ruleset' => $this->ruleset, 'script' => $script));
+
+ $this->script = new rcube_sieve_script($data['script'], $this->get_extensions(), $this->elsif);
+
+ if ($this->cache) {
+ $_SESSION['sieverules_scripts_list'] = serialize($this->list);
+ $_SESSION['sieverules_script_cache_' . $this->ruleset] = serialize($this->script);
+ }
+ }
+
+ public function get_active()
+ {
+ return $this->sieve->getActive();
+ }
+
+ public function set_active($ruleset)
+ {
+ if (PEAR::isError($this->sieve->setActive($ruleset)))
+ return $this->_set_error(SIEVE_ERROR_ACTIVATE);
+
+ return true;
+ }
+
+ public function del_script($script)
+ {
+ return $this->sieve->removeScript($script);
+ }
+
+ public function set_ruleset($ruleset)
+ {
+ $this->ruleset = $ruleset;
+ $this->get_script();
+ }
+
+ public function set_debug($debug)
+ {
+ $this->sieve->setDebug($debug, array($this, 'debug_handler'));
+ }
+
+ public function debug_handler(&$sieve, $message)
+ {
+ rcube::write_log('sieverules', preg_replace('/\r\n$/', '', $message));
+ }
+
+ private function _set_error($error)
+ {
+ $this->error = $error;
+ return false;
+ }
+}
+
+?> \ No newline at end of file
diff --git a/plugins/sieverules/include/rcube_sieve_script.php b/plugins/sieverules/include/rcube_sieve_script.php
new file mode 100644
index 000000000..2dbd52a28
--- /dev/null
+++ b/plugins/sieverules/include/rcube_sieve_script.php
@@ -0,0 +1,969 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | rcube_sieve_script class for sieverules script parsing |
+ | |
+ | Author: Aleksander Machniak <alec@alec.pl> |
+ | Modifications by: Philip Weir |
+ | * Changed name of keys in script array |
+ | * Added support for address and envelope |
+ | * Added support for vacation |
+ | * Added support for disabled rules (written to file as comment) |
+ | * Added support for regex tests |
+ | * Added support for imapflags |
+ | * Added support for relational operators and comparators |
+ | * Added support for subaddress tests |
+ | * Added support for notify action |
+ | * Added support for stop action |
+ | * Added support for body and copy |
+ | * Added support for spamtest and virustest |
+ | * Added support for date |
+ | * Added support for editheader |
+ +-----------------------------------------------------------------------+
+*/
+
+define('SIEVE_ERROR_BAD_ACTION', 1);
+define('SIEVE_ERROR_NOT_FOUND', 2);
+
+// define constants for sieve file
+if (!defined('RCUBE_SIEVE_NEWLINE'))
+ define('RCUBE_SIEVE_NEWLINE', "\r\n");
+
+if (!defined('RCUBE_SIEVE_INDENT'))
+ define('RCUBE_SIEVE_INDENT', "\t");
+
+if (!defined('RCUBE_SIEVE_HEADER'))
+ define('RCUBE_SIEVE_HEADER', "## Generated by Roundcube Webmail SieveRules Plugin ##");
+
+class rcube_sieve_script
+{
+ private $elsif = true;
+ private $content = array();
+ private $supported = array(
+ 'fileinto',
+ 'reject',
+ 'ereject',
+ 'vacation',
+ 'imapflags',
+ 'imap4flags',
+ 'notify',
+ 'enotify',
+ 'spamtest',
+ 'virustest',
+ 'date',
+ 'editheader'
+ );
+ public $raw = '';
+
+ public function __construct($script, $ext = array(), $elsif = true)
+ {
+ $this->raw = $script;
+ $this->elsif = $elsif;
+
+ // adjust supported extenstion to match sieve server
+ $this->supported = array_intersect($this->supported, $ext);
+ if (in_array('copy', $ext))
+ $this->supported = array_merge($this->supported, array('fileinto_copy','redirect_copy'));
+
+ if (in_array('editheader', $ext))
+ $this->supported = array_merge($this->supported, array('editheaderadd','editheaderrem'));
+
+ // include standard actions in supported list
+ $this->supported = array_merge($this->supported, array('redirect','keep','discard','stop'));
+
+ // load script
+ $this->content = $this->parse_text($script);
+ }
+
+ public function add_text($script)
+ {
+ $content = $this->parse_text($script);
+ $result = false;
+
+ // check existsing script rules names
+ foreach ($this->content as $idx => $elem)
+ $names[$elem['name']] = $idx;
+
+ foreach ($content as $elem) {
+ if (!isset($names[$elem['name']])) {
+ array_push($this->content, $elem);
+ $result = true;
+ }
+ }
+
+ return $result;
+ }
+
+ public function import_filters($content)
+ {
+ if (is_array($content)) {
+ $result = false;
+
+ // check existsing script rules names
+ foreach ($this->content as $idx => $elem)
+ $names[$elem['name']] = $idx;
+
+ foreach ($content as $elem) {
+ if (!isset($names[$elem['name']])) {
+ array_push($this->content, $elem);
+ $result = true;
+ }
+ }
+ }
+ else {
+ $this->add_text($content);
+ }
+ }
+
+ public function add_rule($content, $pos = null)
+ {
+ foreach ($content['actions'] as $action) {
+ if (!in_array($action['type'], $this->supported))
+ return SIEVE_ERROR_BAD_ACTION;
+ }
+
+ if ($pos !== null)
+ array_splice($this->content, $pos, 0, array($content));
+ else
+ array_push($this->content, $content);
+
+ return true;
+ }
+
+ public function delete_rule($index)
+ {
+ if (isset($this->content[$index])) {
+ unset($this->content[$index]);
+ $this->content = array_values($this->content);
+ return true;
+ }
+
+ return SIEVE_ERROR_NOT_FOUND;
+ }
+
+ public function size()
+ {
+ return sizeof($this->content);
+ }
+
+ public function update_rule($index, $content)
+ {
+ foreach ($content['actions'] as $action) {
+ if (!in_array($action['type'], $this->supported))
+ return SIEVE_ERROR_BAD_ACTION;
+ }
+
+ if ($this->content[$index]) {
+ $this->content[$index] = $content;
+ return true;
+ }
+
+ return SIEVE_ERROR_NOT_FOUND;
+ }
+
+ public function move_rule($source, $destination)
+ {
+ $this->add_rule($this->content[$source], $destination);
+
+ if ($source < $destination)
+ $this->delete_rule($source);
+ else
+ $this->delete_rule($source + 1);
+ }
+
+ public function as_text()
+ {
+ $script = '';
+ $variables = '';
+ $exts = array();
+
+ // rules
+ $activeRules = 0;
+ foreach ($this->content as $rule) {
+ $tests = array();
+ $i = 0;
+
+ if ($rule['disabled'] == 1) {
+ $script .= '# rule:[' . $rule['name'] . "]" . RCUBE_SIEVE_NEWLINE;
+ $script .= '# disabledRule:[' . $this->_safe_serial(serialize($rule)) . "]" . RCUBE_SIEVE_NEWLINE;
+ }
+ else {
+ // header
+ $script .= '# rule:[' . $rule['name'] . "]" . RCUBE_SIEVE_NEWLINE;
+
+ // constraints expressions
+ foreach ($rule['tests'] as $test) {
+ $tests[$i] = '';
+
+ switch ($test['type']) {
+ case 'size':
+ $tests[$i] .= ($test['not'] ? 'not ' : '');
+ $tests[$i] .= 'size :' . ($test['operator']=='under' ? 'under ' : 'over ') . $test['target'];
+ break;
+ case 'virustest':
+ case 'spamtest':
+ array_push($exts, $test['type']);
+ array_push($exts, 'relational');
+ array_push($exts, 'comparator-i;ascii-numeric');
+ $tests[$i] .= ($test['not'] ? 'not ' : '');
+ $tests[$i] .= $test['type'] . ' :value ' . ($test['operator'] == 'eq' ? '"eq" ' :
+ ($test['operator'] == 'le' ? '"le" ' : '"ge" ')) .
+ ':comparator "i;ascii-numeric" "' . $test['target'] .'"';
+ break;
+ case 'true':
+ $tests[$i] .= ($test['not'] ? 'not true' : 'true');
+ break;
+ case 'exists':
+ $tests[$i] .= ($test['not'] ? 'not ' : '');
+
+ if (is_array($test['header']))
+ $tests[$i] .= 'exists ["' . implode('", "', $this->_escape_string($test['header'])) . '"]';
+ else
+ $tests[$i] .= 'exists "' . $this->_escape_string($test['header']) . '"';
+
+ break;
+ case 'envelope':
+ array_push($exts, 'envelope');
+ case 'header':
+ case 'address':
+ if ($test['operator'] == 'regex')
+ array_push($exts, 'regex');
+ elseif (substr($test['operator'], 0, 5) == 'count' || substr($test['operator'], 0, 5) == 'value')
+ array_push($exts, 'relational');
+ elseif ($test['operator'] == 'user' || $test['operator'] == 'detail' || $test['operator'] == 'domain')
+ array_push($exts, 'subaddress');
+
+ $tests[$i] .= ($test['not'] ? 'not ' : '');
+ $tests[$i] .= $test['type']. ' :' . $test['operator'];
+
+ if ($test['comparator'] != '') {
+ if ($test['comparator'] != 'i;ascii-casemap' && $test['comparator'] != 'i;octet')
+ array_push($exts, 'comparator-' . $test['comparator']);
+
+ $tests[$i] .= ' :comparator "' . $test['comparator'] . '"';
+ }
+
+ if (is_array($test['header']))
+ $tests[$i] .= ' ["' . implode('", "', $this->_escape_string($test['header'])) . '"]';
+ else
+ $tests[$i] .= ' "' . $this->_escape_string($test['header']) . '"';
+
+ if (is_array($test['target']))
+ $tests[$i] .= ' ["' . implode('", "', $this->_escape_string($test['target'])) . '"]';
+ else
+ $tests[$i] .= ' "' . $this->_escape_string($test['target']) . '"';
+
+ break;
+ case 'body':
+ array_push($exts, 'body');
+ if ($test['operator'] == 'regex')
+ array_push($exts, 'regex');
+ elseif (substr($test['operator'], 0, 5) == 'count' || substr($test['operator'], 0, 5) == 'value')
+ array_push($exts, 'relational');
+
+ $tests[$i] .= ($test['not'] ? 'not ' : '');
+ $tests[$i] .= $test['type'];
+
+ if ($test['bodypart'] != '')
+ $tests[$i] .= ' :' . $test['bodypart'];
+
+ if ($test['contentpart'] != '')
+ $tests[$i] .= ' "'. $test['contentpart'] .'"';
+
+ $tests[$i] .= ' :' . $test['operator'];
+
+ if ($test['comparator'] != '') {
+ if ($test['comparator'] != 'i;ascii-casemap' && $test['comparator'] != 'i;octet')
+ array_push($exts, 'comparator-' . $test['comparator']);
+
+ $tests[$i] .= ' :comparator "' . $test['comparator'] . '"';
+ }
+
+ if (is_array($test['target']))
+ $tests[$i] .= ' ["' . implode('", "', $this->_escape_string($test['target'])) . '"]';
+ else
+ $tests[$i] .= ' "' . $this->_escape_string($test['target']) . '"';
+
+ break;
+ case 'date':
+ array_push($exts, 'date');
+ if ($test['operator'] == 'regex')
+ array_push($exts, 'regex');
+ elseif (substr($test['operator'], 0, 5) == 'count' || substr($test['operator'], 0, 5) == 'value')
+ array_push($exts, 'relational');
+
+ $tests[$i] .= ($test['not'] ? 'not ' : '');
+ $tests[$i] .= $test['header'];
+
+ $timezone = rcube::get_instance()->config->get('timezone', 'auto');
+ if ($timezone != 'auto') {
+ $tz = new DateTimeZone($timezone);
+ $date = new DateTime('now', $tz);
+ $tests[$i] .= ' :zone ' . '"' . $date->format('O') . '"';
+ }
+
+ $tests[$i] .= ' :' . $test['operator'];
+
+ if ($test['comparator'] != '') {
+ if ($test['comparator'] != 'i;ascii-casemap' && $test['comparator'] != 'i;octet')
+ array_push($exts, 'comparator-' . $test['comparator']);
+
+ $tests[$i] .= ' :comparator "' . $test['comparator'] . '"';
+ }
+
+ $tests[$i] .= ' "' . $this->_escape_string($test['datepart']) . '"';
+ $tests[$i] .= ' "' . $this->_escape_string($test['target']) . '"';
+
+ break;
+ }
+
+ $i++;
+ }
+
+ $script .= ($activeRules > 0 && $this->elsif ? 'els' : '') . ($rule['join'] ? 'if allof (' : 'if anyof (');
+ $activeRules++;
+
+ if (sizeof($tests) > 1)
+ $script .= implode("," . RCUBE_SIEVE_NEWLINE . RCUBE_SIEVE_INDENT, $tests);
+ elseif (sizeof($tests))
+ $script .= $tests[0];
+ else
+ $script .= 'true';
+
+
+ $script .= ")". RCUBE_SIEVE_NEWLINE ."{" . RCUBE_SIEVE_NEWLINE;
+
+ // action(s)
+ $actions = '';
+ foreach ($rule['actions'] as $action) {
+ switch ($action['type']) {
+ case 'fileinto':
+ case 'fileinto_copy':
+ array_push($exts, 'fileinto');
+
+ $args = '';
+ if ($action['type'] == 'fileinto_copy') {
+ array_push($exts, 'copy');
+ $args .= ' :copy';
+ }
+
+ if ($action['create']) {
+ array_push($exts, 'mailbox');
+ $args .= ' :create';
+ }
+
+ // variables support in fileinto by David Warden
+ if (preg_match('/\$\{\d+\}/', $action['target']))
+ array_push($exts, 'variables');
+
+ $actions .= RCUBE_SIEVE_INDENT . "fileinto" . $args . " \"" . $this->_escape_string($action['target']) . "\";" . RCUBE_SIEVE_NEWLINE;
+ break;
+ case 'redirect':
+ case 'redirect_copy':
+ $args = '';
+ if ($action['type'] == 'redirect_copy') {
+ array_push($exts, 'copy');
+ $args .= ' :copy';
+ }
+
+ $tokens = preg_split('/[,;\s]/', $action['target']);
+ foreach ($tokens as $email)
+ $actions .= RCUBE_SIEVE_INDENT . "redirect" . $args . " \"" . $this->_escape_string($email) . "\";" . RCUBE_SIEVE_NEWLINE;
+ break;
+ case 'reject':
+ case 'ereject':
+ array_push($exts, $action['type']);
+
+ if (strpos($action['target'], "\n")!==false)
+ $actions .= RCUBE_SIEVE_INDENT . $action['type']." text:" . RCUBE_SIEVE_NEWLINE . $action['target'] . RCUBE_SIEVE_NEWLINE . "." . RCUBE_SIEVE_NEWLINE . ";" . RCUBE_SIEVE_NEWLINE;
+ else
+ $actions .= RCUBE_SIEVE_INDENT . $action['type']." \"" . $this->_escape_string($action['target']) . "\";" . RCUBE_SIEVE_NEWLINE;
+
+ break;
+ case 'vacation':
+ array_push($exts, 'vacation');
+ $action['subject'] = $this->_escape_string($action['subject']);
+
+// // encoding subject header with mb_encode provides better results with asian characters
+// if (function_exists("mb_encode_mimeheader"))
+// {
+// mb_internal_encoding($action['charset']);
+// $action['subject'] = mb_encode_mimeheader($action['subject'], $action['charset'], 'Q');
+// mb_internal_encoding(RCUBE_CHARSET);
+// }
+
+ // detect original recipient
+ if ($action['from'] == 'auto' && strpos($variables, 'set "from"') === false) {
+ array_push($exts, 'variables');
+
+ $variables .= 'set "from" "";' . RCUBE_SIEVE_NEWLINE;
+ $variables .= 'if header :matches "to" "*" {' . RCUBE_SIEVE_NEWLINE;
+ $variables .= RCUBE_SIEVE_INDENT . 'set "from" "${1}";' . RCUBE_SIEVE_NEWLINE;
+ $variables .= '}' . RCUBE_SIEVE_NEWLINE;
+
+ $action['from'] = "\${from}";
+ }
+ elseif ($action['from'] == 'auto') {
+ $action['from'] = "\${from}";
+ }
+
+ // append original subject
+ if ($action['origsubject'] == '1' && strpos($variables, 'set "subject"') === false) {
+ array_push($exts, 'variables');
+
+ $variables .= 'set "subject" "";' . RCUBE_SIEVE_NEWLINE;
+ $variables .= 'if header :matches "subject" "*" {' . RCUBE_SIEVE_NEWLINE;
+ $variables .= RCUBE_SIEVE_INDENT . 'set "subject" "${1}";' . RCUBE_SIEVE_NEWLINE;
+ $variables .= '}' . RCUBE_SIEVE_NEWLINE;
+
+ $action['subject'] = trim($action['subject']);
+ if (substr($action['subject'], -1, 1) != ":") $action['subject'] .= ":";
+ $action['subject'] .= " \${subject}";
+ }
+
+ $actions .= RCUBE_SIEVE_INDENT . "vacation" . RCUBE_SIEVE_NEWLINE;
+ if (!empty($action['days'])) $actions .= RCUBE_SIEVE_INDENT . RCUBE_SIEVE_INDENT . ":days ". $action['days'] . RCUBE_SIEVE_NEWLINE;
+ if (!empty($action['addresses'])) $actions .= RCUBE_SIEVE_INDENT . RCUBE_SIEVE_INDENT . ":addresses [\"". str_replace(",", "\",\"", $this->_escape_string($action['addresses'])) ."\"]" . RCUBE_SIEVE_NEWLINE;
+ if (!empty($action['subject'])) $actions .= RCUBE_SIEVE_INDENT . RCUBE_SIEVE_INDENT . ":subject \"". $action['subject'] ."\"" . RCUBE_SIEVE_NEWLINE;
+ if (!empty($action['handle'])) $actions .= RCUBE_SIEVE_INDENT . RCUBE_SIEVE_INDENT . ":handle \"". $this->_escape_string($action['handle']) ."\"" . RCUBE_SIEVE_NEWLINE;
+ if (!empty($action['from'])) $actions .= RCUBE_SIEVE_INDENT . RCUBE_SIEVE_INDENT . ":from \"". $this->_escape_string($action['from']) ."\"" . RCUBE_SIEVE_NEWLINE;
+
+ if ($action['htmlmsg']) {
+ $MAIL_MIME = new Mail_mime("\r\n");
+
+ $action['msg'] = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN">' .
+ "\r\n<html><body>\r\n" . $action['msg'] . "\r\n</body></html>\r\n";
+
+ $MAIL_MIME->setHTMLBody($action['msg']);
+
+ // add a plain text version of the e-mail as an alternative part.
+ $h2t = new rcube_html2text($action['msg'], false, true, 0);
+ $plainTextPart = $h2t->get_text();
+ if (!$plainTextPart) {
+ // empty message body breaks attachment handling in drafts
+ $plainTextPart = "\r\n";
+ }
+ else {
+ // make sure all line endings are CRLF (#1486712)
+ $plainTextPart = preg_replace('/\r?\n/', "\r\n", $plainTextPart);
+ }
+
+ $MAIL_MIME->setTXTBody($plainTextPart);
+
+ $MAIL_MIME->setParam('html_charset', $action['charset']);
+ $MAIL_MIME->setParam('text_charset', $action['charset']);
+
+ $action['msg'] = $MAIL_MIME->getMessage();
+ }
+
+ // escape lines which start is a .
+ $action['msg'] = preg_replace('/(^|\r?\n)\./', "$1..", $action['msg']);
+
+ if ($action['htmlmsg'])
+ $actions .= RCUBE_SIEVE_INDENT . RCUBE_SIEVE_INDENT . ":mime text:". RCUBE_SIEVE_NEWLINE . $action['msg'] . RCUBE_SIEVE_NEWLINE . "." . RCUBE_SIEVE_NEWLINE . ";" . RCUBE_SIEVE_NEWLINE;
+ elseif ($action['charset'] != "UTF-8")
+ $actions .= RCUBE_SIEVE_INDENT . RCUBE_SIEVE_INDENT . ":mime text:". RCUBE_SIEVE_NEWLINE ."Content-Type: text/plain; charset=". $action['charset'] . RCUBE_SIEVE_NEWLINE . RCUBE_SIEVE_NEWLINE . $action['msg'] . RCUBE_SIEVE_NEWLINE . "." . RCUBE_SIEVE_NEWLINE . ";" . RCUBE_SIEVE_NEWLINE;
+ elseif (strpos($action['msg'], "\n") !== false)
+ $actions .= RCUBE_SIEVE_INDENT . RCUBE_SIEVE_INDENT . "text:" . RCUBE_SIEVE_NEWLINE . $action['msg'] . RCUBE_SIEVE_NEWLINE . "." . RCUBE_SIEVE_NEWLINE . ";" . RCUBE_SIEVE_NEWLINE;
+ else
+ $actions .= RCUBE_SIEVE_INDENT . RCUBE_SIEVE_INDENT . "\"" . $this->_escape_string($action['msg']) . "\";" . RCUBE_SIEVE_NEWLINE;
+
+ break;
+ case 'imapflags':
+ case 'imap4flags':
+ array_push($exts, $action['type']);
+
+ if (strpos($actions, "setflag") !== false)
+ $actions .= RCUBE_SIEVE_INDENT . "addflag \"" . $this->_escape_string($action['target']) . "\";" . RCUBE_SIEVE_NEWLINE;
+ else
+ $actions .= RCUBE_SIEVE_INDENT . "setflag \"" . $this->_escape_string($action['target']) . "\";" . RCUBE_SIEVE_NEWLINE;
+
+ break;
+ case 'notify':
+ array_push($exts, 'notify');
+ $actions .= RCUBE_SIEVE_INDENT . "notify" . RCUBE_SIEVE_NEWLINE;
+ $actions .= RCUBE_SIEVE_INDENT . RCUBE_SIEVE_INDENT . ":method \"" . $this->_escape_string($action['method']) . "\"" . RCUBE_SIEVE_NEWLINE;
+ if (!empty($action['options'])) $actions .= RCUBE_SIEVE_INDENT . RCUBE_SIEVE_INDENT . ":options [\"" . str_replace(",", "\",\"", $this->_escape_string($action['options'])) . "\"]" . RCUBE_SIEVE_NEWLINE;
+ if (!empty($action['from'])) $actions .= RCUBE_SIEVE_INDENT . RCUBE_SIEVE_INDENT . ":from \"" . $this->_escape_string($action['from']) . "\"" . RCUBE_SIEVE_NEWLINE;
+ if (!empty($action['importance'])) $actions .= RCUBE_SIEVE_INDENT . RCUBE_SIEVE_INDENT . ":importance \"" . $this->_escape_string($action['importance']) . "\"" . RCUBE_SIEVE_NEWLINE;
+ $actions .= RCUBE_SIEVE_INDENT . RCUBE_SIEVE_INDENT . ":message \"". $this->_escape_string($action['msg']) ."\";" . RCUBE_SIEVE_NEWLINE;
+ break;
+ case 'enotify':
+ array_push($exts, 'enotify');
+ $actions .= RCUBE_SIEVE_INDENT . "notify" . RCUBE_SIEVE_NEWLINE;
+ if (!empty($action['options'])) $actions .= RCUBE_SIEVE_INDENT . RCUBE_SIEVE_INDENT . ":options [\"" . str_replace(",", "\",\"", $this->_escape_string($action['options'])) . "\"]" . RCUBE_SIEVE_NEWLINE;
+ if (!empty($action['from'])) $actions .= RCUBE_SIEVE_INDENT . RCUBE_SIEVE_INDENT . ":from \"" . $this->_escape_string($action['from']) . "\"" . RCUBE_SIEVE_NEWLINE;
+ if (!empty($action['importance'])) $actions .= RCUBE_SIEVE_INDENT . RCUBE_SIEVE_INDENT . ":importance \"" . $this->_escape_string($action['importance']) . "\"" . RCUBE_SIEVE_NEWLINE;
+ $actions .= RCUBE_SIEVE_INDENT . RCUBE_SIEVE_INDENT . ":message \"". $this->_escape_string($action['msg']) ."\"" . RCUBE_SIEVE_NEWLINE;
+ $actions .= RCUBE_SIEVE_INDENT . RCUBE_SIEVE_INDENT . "\"" . $this->_escape_string($action['method']) . "\";" . RCUBE_SIEVE_NEWLINE;
+ break;
+ case 'editheaderadd':
+ array_push($exts, 'editheader');
+ $actions .= RCUBE_SIEVE_INDENT . "addheader";
+
+ if ($action['index'] == 'last')
+ $actions .= " :last";
+
+ $actions .= " \"". $this->_escape_string($action['name']) ."\" \"". $this->_escape_string($action['value']) ."\";" . RCUBE_SIEVE_NEWLINE;
+ break;
+ case 'editheaderrem':
+ array_push($exts, 'editheader');
+ $actions .= RCUBE_SIEVE_INDENT . "deleteheader";
+
+ if (is_numeric($action['index']))
+ $actions .= " :index " . $action['index'];
+ elseif ($action['index'] == 'last')
+ $actions .= " :last";
+
+ if (strlen($action['operator']) > 0)
+ $actions .= " :" . $action['operator'];
+
+ $actions .= " \"". $this->_escape_string($action['name']) ."\"";
+
+ if (strlen($action['value']) > 0)
+ $actions .= " \"". $this->_escape_string($action['value']) ."\"";
+
+ $actions .= ";" . RCUBE_SIEVE_NEWLINE;
+ break;
+ case 'keep':
+ case 'discard':
+ case 'stop':
+ $actions .= RCUBE_SIEVE_INDENT . $action['type'] .";" . RCUBE_SIEVE_NEWLINE;
+ break;
+ }
+ }
+
+ $script .= $actions . "}" . RCUBE_SIEVE_NEWLINE;
+ }
+ }
+
+ if ($variables)
+ $variables .= RCUBE_SIEVE_NEWLINE;
+
+ // requires
+ $exts = array_unique($exts);
+ if (sizeof($exts))
+ $script = 'require ["' . implode('","', $exts) . "\"];" . RCUBE_SIEVE_NEWLINE . RCUBE_SIEVE_NEWLINE . $variables . $script;
+
+ // author
+ if ($script && RCUBE_SIEVE_HEADER)
+ $script = RCUBE_SIEVE_HEADER . RCUBE_SIEVE_NEWLINE . $script;
+
+ return $script;
+ }
+
+ public function as_array()
+ {
+ return $this->content;
+ }
+
+ public function parse_text($script)
+ {
+ $i = 0;
+ $content = array();
+
+ // remove C comments
+ $script = preg_replace('|/\*.*?\*/|sm', '', $script);
+
+ // tokenize rules - \r is optional for backward compatibility (added 20090413)
+ if ($tokens = preg_split('/(# rule:\[.*\])\r?\n/', $script, -1, PREG_SPLIT_DELIM_CAPTURE)) {
+ foreach($tokens as $token) {
+ if (preg_match('/^# rule:\[(.*)\]/', $token, $matches)) {
+ $content[$i]['name'] = $matches[1];
+ }
+ elseif (isset($content[$i]['name']) && sizeof($content[$i]) == 1 && preg_match('/^# disabledRule:\[(.*)\]/', $token, $matches)) {
+ $content[$i] = unserialize($this->_regular_serial($matches[1]));
+ $i++;
+ }
+ elseif (isset($content[$i]['name']) && sizeof($content[$i]) == 1) {
+ if ($rule = $this->_tokenize_rule($token)) {
+ $content[$i] = array_merge($content[$i], $rule);
+ $i++;
+ }
+ else {
+ unset($content[$i]);
+ }
+ }
+ }
+ }
+
+ return $content;
+ }
+
+ private function _tokenize_rule($content)
+ {
+ $result = NULL;
+
+ if (preg_match('/^(if|elsif|else)\s+((true|not\s+true|allof|anyof|exists|header|not|size|envelope|address|spamtest|virustest|date|currentdate)\s+(.*))\s+\{(.*)\}$/sm', trim($content), $matches)) {
+ list($tests, $join) = $this->_parse_tests(trim($matches[2]));
+ $actions = $this->_parse_actions(trim($matches[5]));
+
+ if ($tests && $actions) {
+ $result = array(
+ 'tests' => $tests,
+ 'actions' => $actions,
+ 'join' => $join,
+ );
+ }
+ }
+
+ return $result;
+ }
+
+ private function _parse_actions($content)
+ {
+ $content = str_replace("\r\n", "\n", $content);
+ $result = NULL;
+
+ // supported actions
+ $patterns[] = '^\s*discard;';
+ $patterns[] = '^\s*keep;';
+ $patterns[] = '^\s*stop;';
+ $patterns[] = '^\s*fileinto\s+(:copy\s+)?(:create\s+)?(.*?[^\\\]);';
+ $patterns[] = '^\s*redirect\s+(:copy\s+)?(.*?[^\\\]);';
+ $patterns[] = '^\s*setflag\s+(.*?[^\\\]);';
+ $patterns[] = '^\s*addflag\s+(.*?[^\\\]);';
+ $patterns[] = '^\s*reject\s+text:(.*)\n\.\n;';
+ $patterns[] = '^\s*ereject\s+text:(.*)\n\.\n;';
+ $patterns[] = '^\s*reject\s+(.*?[^\\\]);';
+ $patterns[] = '^\s*ereject\s+(.*?[^\\\]);';
+ $patterns[] = '^\s*vacation\s+(:days\s+([0-9]+)\s+)?(:addresses\s+\[(.*?[^\\\])\]\s+)?(:subject\s+(".*?[^"\\\]")\s+)?(:handle\s+(".*?[^"\\\]")\s+)?(:from\s+(".*?[^"\\\]")\s+)?(:mime\s+)?text:(.*)\n\.\n;';
+ $patterns[] = '^\s*vacation\s+(:days\s+([0-9]+)\s+)?(:addresses\s+\[(.*?[^\\\])\]\s+)?(:subject\s+(".*?[^"\\\]")\s+)?(:handle\s+(".*?[^"\\\]")\s+)?(:from\s+(".*?[^"\\\]")\s+)?(.*?[^\\\]);';
+ $patterns[] = '^\s*notify\s+:method\s+(".*?[^"\\\]")\s+(:options\s+\[(.*?[^\\\])\]\s+)?(:from\s+(".*?[^"\\\]")\s+)?(:importance\s+(".*?[^"\\\]")\s+)?:message\s+(".*?[^"\\\]");';
+ $patterns[] = '^\s*notify\s+(:options\s+\[(.*?[^\\\])\]\s+)?(:from\s+(".*?[^"\\\]")\s+)?(:importance\s+(".*?[^"\\\]")\s+)?:message\s+(".*?[^"\\\]")\s+(.*);';
+ $patterns[] = '^\s*addheader\s+(:(last))?\s*(".*?[^"\\\]")\s+(".*?[^"\\\]");';
+ $patterns[] = '^\s*deleteheader\s+(:(last)|:index\s([0-9])+)?\s*(:(contains))?\s*(".*?[^"\\\]")\s*(".*?[^"\\\]")?;';
+
+ $pattern = '/(' . implode('$)|(', $patterns) . '$)/ms';
+
+ // parse actions body
+ if (preg_match_all($pattern, $content, $mm, PREG_SET_ORDER)) {
+ foreach ($mm as $m) {
+ $content = trim($m[0]);
+
+ if (preg_match('/^(discard|keep|stop)/', $content, $matches)) {
+ $result[] = array('type' => $matches[1]);
+ }
+ elseif (preg_match('/^fileinto\s+:copy/', $content)) {
+ $result[] = array('type' => 'fileinto_copy', 'target' => $this->_parse_string($m[sizeof($m)-1]));
+ }
+ elseif (preg_match('/^fileinto/', $content)) {
+ $result[] = array('type' => 'fileinto', 'target' => $this->_parse_string($m[sizeof($m)-1]));
+ }
+ elseif (preg_match('/^redirect\s+:copy/', $content)) {
+ $result[] = array('type' => 'redirect_copy', 'target' => $this->_parse_string($m[sizeof($m)-1]));
+ }
+ elseif (preg_match('/^redirect/', $content)) {
+ $result[] = array('type' => 'redirect', 'target' => $this->_parse_string($m[sizeof($m)-1]));
+ }
+ elseif (preg_match('/^(reject|ereject)\s+(.*);$/sm', $content, $matches)) {
+ $result[] = array('type' => $matches[1], 'target' => $this->_parse_string($matches[2]));
+ }
+ elseif (preg_match('/^(setflag|addflag)/', $content)) {
+ if (in_array('imap4flags', $this->supported))
+ $result[] = array('type' => 'imap4flags', 'target' => $this->_parse_string($m[sizeof($m)-1]));
+ else
+ $result[] = array('type' => 'imapflags', 'target' => $this->_parse_string($m[sizeof($m)-1]));
+ }
+ elseif (preg_match('/^vacation\s+(:days\s+([0-9]+)\s+)?(:addresses\s+\[(.*?[^\\\])\]\s+)?(:subject\s+(".*?[^"\\\]")\s+)?(:handle\s+(".*?[^"\\\]")\s+)?(:from\s+(".*?[^"\\\]")\s+)?(.*);$/sm', $content, $matches)) {
+ $origsubject = "";
+ if (substr($matches[6], -13, 12) == ": \${subject}") {
+ $matches[6] = trim(substr($matches[6], 0, -13)) . "\"";
+ $origsubject = "1";
+ }
+
+ if ($matches[10] == "\"\${from}\"")
+ $matches[10] = "\"auto\"";
+
+// if (function_exists("mb_decode_mimeheader")) $matches[5] = mb_decode_mimeheader($matches[5]);
+
+ if (strpos($matches[11], 'Content-Type: multipart/alternative') !== false) {
+ $htmlmsg = true;
+
+ preg_match('/Content-Type: text\/html; charset=([^\r\n]+).*<body>(.+)<\/body>/sm', $matches[11], $htmlparts);
+ $msg = quoted_printable_decode($htmlparts[2]);
+ $charset = $htmlparts[1];
+ }
+ else {
+ $htmlmsg = false;
+ $msg = $this->_parse_string($matches[11]);
+ $charset = $this->_parse_charset($matches[11]);
+ }
+
+ // unescape lines which start is a .
+ $msg = preg_replace('/(^|\r?\n)\.\./', "$1.", $msg);
+
+ $result[] = array('type' => 'vacation',
+ 'days' => $matches[2],
+ 'subject' => $this->_parse_string($matches[6]),
+ 'origsubject' => $origsubject,
+ 'from' => $this->_parse_string($matches[10]),
+ 'addresses' => $this->_parse_string(str_replace("\",\"", ",", $matches[4])),
+ 'handle' => $this->_parse_string($matches[8]),
+ 'msg' => $msg,
+ 'htmlmsg' => $htmlmsg,
+ 'charset' => $charset);
+ }
+ elseif (preg_match('/^notify\s+:method\s+(".*?[^"\\\]")\s+(:options\s+\[(.*?[^\\\])\]\s+)?(:from\s+(".*?[^"\\\]")\s+)?(:importance\s+(".*?[^"\\\]")\s+)?:message\s+(".*?[^"\\\]");$/sm', $content, $matches)) {
+ $result[] = array('type' => 'notify',
+ 'method' => $this->_parse_string($matches[1]),
+ 'options' => $this->_parse_string($matches[3]),
+ 'from' => $this->_parse_string($matches[5]),
+ 'importance' => $this->_parse_string($matches[7]),
+ 'msg' => $this->_parse_string($matches[8]));
+ }
+ elseif (preg_match('/^notify\s+(:options\s+\[(.*?[^\\\])\]\s+)?(:from\s+(".*?[^"\\\]")\s+)?(:importance\s+(".*?[^"\\\]")\s+)?:message\s+(".*?[^"\\\]")\s+(.*);$/sm', $content, $matches)) {
+ $result[] = array('type' => 'enotify',
+ 'method' => $this->_parse_string($matches[8]),
+ 'options' => $this->_parse_string($matches[2]),
+ 'from' => $this->_parse_string($matches[4]),
+ 'importance' => $this->_parse_string($matches[6]),
+ 'msg' => $this->_parse_string($matches[7]));
+ }
+ elseif (preg_match('/^addheader/', $content)) {
+ $result[] = array('type' => 'editheaderadd',
+ 'index' => $m[sizeof($m)-3],
+ 'name' => $this->_parse_string($m[sizeof($m)-2]),
+ 'value' => $this->_parse_string($m[sizeof($m)-1]));
+ }
+ elseif (preg_match('/^deleteheader/', $content)) {
+ $result[] = array('type' => 'editheaderrem',
+ 'index' => $m[sizeof($m)-6] == 'last' ? $m[sizeof($m)-6] : $m[sizeof($m)-5],
+ 'operator' => $m[sizeof($m)-3],
+ 'name' => strlen($m[sizeof($m)-2]) == 0 ? $this->_parse_string($m[sizeof($m)-1]) : $this->_parse_string($m[sizeof($m)-2]),
+ 'value' => strlen($m[sizeof($m)-2]) == 0 ? '' : $this->_parse_string($m[sizeof($m)-1]));
+ }
+ }
+ }
+
+ return $result;
+ }
+
+ private function _parse_tests($content)
+ {
+ $result = NULL;
+
+ // lists
+ if (preg_match('/^(allof|anyof)\s+\((.*)\)$/sm', $content, $matches)) {
+ $content = $matches[2];
+ $join = $matches[1]=='allof' ? true : false;
+ }
+ else {
+ $join = false;
+ }
+
+ // supported tests regular expressions
+ $patterns[] = '(not\s+)?(exists)\s+\[(.*?[^\\\])\]';
+ $patterns[] = '(not\s+)?(exists)\s+(".*?[^\\\]")';
+ $patterns[] = '(not\s+)?(true)';
+ $patterns[] = '(not\s+)?(size)\s+:(under|over)\s+([0-9]+[KGM]{0,1})';
+ $patterns[] = '(not\s+)?(spamtest|virustest)\s+:value\s+"(eq|ge|le)"\s+:comparator\s+"i;ascii-numeric"\s+"(.*?[^\\\])"';
+ $patterns[] = '(not\s+)?(header|address|envelope)\s+:(contains|is|matches|regex|user|detail|domain)((\s+))\[(.*?[^\\\]")\]\s+\[(.*?[^\\\]")\]';
+ $patterns[] = '(not\s+)?(header|address|envelope)\s+:(contains|is|matches|regex|user|detail|domain)((\s+))(".*?[^\\\]")\s+(".*?[^\\\]")';
+ $patterns[] = '(not\s+)?(header|address|envelope)\s+:(contains|is|matches|regex|user|detail|domain)((\s+))\[(.*?[^\\\]")\]\s+(".*?[^\\\]")';
+ $patterns[] = '(not\s+)?(header|address|envelope)\s+:(contains|is|matches|regex|user|detail|domain)((\s+))(".*?[^\\\]")\s+\[(.*?[^\\\]")\]';
+ $patterns[] = '(not\s+)?(header|address|envelope)\s+:(count\s+".*?[^\\\]"|value\s+".*?[^\\\]")(\s+:comparator\s+"(.*?[^\\\])")?\s+\[(.*?[^\\\]")\]\s+\[(.*?[^\\\]")\]';
+ $patterns[] = '(not\s+)?(header|address|envelope)\s+:(count\s+".*?[^\\\]"|value\s+".*?[^\\\]")(\s+:comparator\s+"(.*?[^\\\])")?\s+(".*?[^\\\]")\s+(".*?[^\\\]")';
+ $patterns[] = '(not\s+)?(header|address|envelope)\s+:(count\s+".*?[^\\\]"|value\s+".*?[^\\\]")(\s+:comparator\s+"(.*?[^\\\])")?\s+\[(.*?[^\\\]")\]\s+(".*?[^\\\]")';
+ $patterns[] = '(not\s+)?(header|address|envelope)\s+:(count\s+".*?[^\\\]"|value\s+".*?[^\\\]")(\s+:comparator\s+"(.*?[^\\\])")?\s+(".*?[^\\\]")\s+\[(.*?[^\\\]")\]';
+ $patterns[] = '(not\s+)?(body)(\s+:(raw|text|content\s+".*?[^\\\]"))?\s+:(contains|is|matches|regex)((\s+))\[(.*?[^\\\]")\]';
+ $patterns[] = '(not\s+)?(body)(\s+:(raw|text|content\s+".*?[^\\\]"))?\s+:(contains|is|matches|regex)((\s+))(".*?[^\\\]")';
+ $patterns[] = '(not\s+)?(body)(\s+:(raw|text|content\s+".*?[^\\\]"))?\s+:(count\s+".*?[^\\\]"|value\s+".*?[^\\\]")(\s+:comparator\s+"(.*?[^\\\])")?\s+\[(.*?[^\\\]")\]';
+ $patterns[] = '(not\s+)?(body)(\s+:(raw|text|content\s+".*?[^\\\]"))?\s+:(count\s+".*?[^\\\]"|value\s+".*?[^\\\]")(\s+:comparator\s+"(.*?[^\\\])")?\s+(".*?[^\\\]")';
+ $patterns[] = '(not\s+)?(date|currentdate)(\s+:zone\s+"([\+\-][0-9]{4})")?\s+:(contains|is|matches|regex)((\s+))(".*?[^\\\]"\s+)?(".*?[^\\\]")\s+(".*?[^\\\]")';
+ $patterns[] = '(not\s+)?(date|currentdate)(\s+:zone\s+"([\+\-][0-9]{4})")?\s+:(count\s+".*?[^\\\]"|value\s+".*?[^\\\]")(\s+:comparator\s+"(.*?[^\\\])")?(\s+".*?[^\\\]")?\s+(".*?[^\\\]")\s+(".*?[^\\\]")';
+
+ // join patterns...
+ $pattern = '/(' . implode(')|(', $patterns) . ')/';
+
+ // ...and parse tests list
+ if (preg_match_all($pattern, $content, $matches, PREG_SET_ORDER)) {
+ foreach ($matches as $match) {
+ $size = sizeof($match);
+
+ if (preg_match('/^(not\s+)?size/', $match[0])) {
+ $result[] = array(
+ 'type' => 'size',
+ 'not' => $match[$size-4] ? true : false,
+ 'operator' => $match[$size-2], // under/over
+ 'target' => $match[$size-1], // value
+ );
+ }
+ elseif (preg_match('/^(not\s+)?(spamtest|virustest)/', $match[0])) {
+ $result[] = array(
+ 'type' => $match[$size-3],
+ 'not' => $match[$size-4] ? true : false,
+ 'operator' => $match[$size-2], // ge/le/eq
+ 'target' => $match[$size-1], // value
+ );
+ }
+ elseif (preg_match('/^(not\s+)?(header|address|envelope)/', $match[0])) {
+ $result[] = array(
+ 'type' => $match[$size-6],
+ 'not' => $match[$size-7] ? true : false,
+ 'operator' => $match[$size-5], // is/contains/matches
+ 'header' => $this->_parse_list($match[$size-2]), // header(s)
+ 'target' => $this->_parse_list($match[$size-1], ($match[$size-5] == 'regex' ? true : false)), // string(s)
+ 'comparator' => trim($match[$size-3])
+ );
+ }
+ elseif (preg_match('/^(not\s+)?exists/', $match[0])) {
+ $result[] = array(
+ 'type' => 'exists',
+ 'not' => $match[$size-3] ? true : false,
+ 'operator' => 'exists',
+ 'header' => $this->_parse_list($match[$size-1]), // header(s)
+ );
+ }
+ elseif (preg_match('/^(not\s+)?true/', $match[0])) {
+ $result[] = array(
+ 'type' => 'true',
+ 'not' => $match[$size-2] ? true : false,
+ );
+ }
+ elseif (preg_match('/^(not\s+)?body/', $match[0])) {
+ if (preg_match('/.*content\s+"(.*?[^\\\])".*/', $match[$size-5], $parts)) {
+ $bodypart = 'content';
+ $contentpart = $parts[1];
+ }
+ else {
+ $bodypart = $match[$size-5];
+ $contentpart = '';
+ }
+
+ $result[] = array(
+ 'type' => 'body',
+ 'not' => $match[$size-8] ? true : false,
+ 'bodypart' => $bodypart,
+ 'contentpart' => $contentpart,
+ 'operator' => $match[$size-4], // is/contains/matches
+ 'header' => 'body', // header(s)
+ 'target' => $this->_parse_list($match[$size-1], ($match[$size-4] == 'regex' ? true : false)), // string(s)
+ 'comparator' => trim($match[$size-2])
+ );
+ }
+ elseif (preg_match('/^(not\s+)?(date|currentdate)/', $match[0])) {
+ $result[] = array(
+ 'type' => 'date',
+ 'not' => $match[$size-10] ? true : false,
+ 'header' => $match[$size-9], // header
+ 'operator' => $match[$size-6], // is/contains/matches
+ 'datepart' => $this->_parse_list($match[$size-2]),
+ 'target' => $this->_parse_list($match[$size-1], ($match[$size-5] == 'regex' ? true : false)), // string(s)
+ 'field' => $match[$size-3], // received
+ 'comparator' => trim($match[$size-4])
+ );
+ }
+ }
+ }
+
+ return array($result, $join);
+ }
+
+ private function _parse_string($content)
+ {
+ $text = '';
+ $content = trim($content);
+
+ if (preg_match('/^:mime\s+text:(.*)\.$/sm', $content, $matches)) {
+ $parts = preg_split("/\r?\n/", $matches[1], 4);
+ $text = trim($parts[3]);
+ }
+ elseif (preg_match('/^text:(.*)\.$/sm', $content, $matches))
+ $text = trim($matches[1]);
+ elseif (preg_match('/^"(.*)"$/', $content, $matches))
+ $text = str_replace('\"', '"', $matches[1]);
+
+ return $text;
+ }
+
+ private function _parse_charset($content)
+ {
+ $charset = RCUBE_CHARSET;
+ $content = trim($content);
+
+ if (preg_match('/^:mime\s+text:(.*)\.$/sm', $content, $matches)) {
+ $parts = preg_split("/\r?\n/", $matches[1], 4);
+
+ $charset = trim(substr($parts[1], stripos($parts[1], "charset=") + 8));
+ }
+
+ return $charset;
+ }
+
+ private function _escape_string($content)
+ {
+ $replace['/"/'] = '\\"';
+
+ if (is_array($content)) {
+ for ($x=0, $y=sizeof($content); $x<$y; $x++)
+ $content[$x] = preg_replace(array_keys($replace), array_values($replace), $content[$x]);
+
+ return $content;
+ }
+ else {
+ return preg_replace(array_keys($replace), array_values($replace), $content);
+ }
+ }
+
+ private function _parse_list($content, $regex = false)
+ {
+ $result = array();
+
+ if ($regex) {
+ if (preg_match('/^"(.*)"$/', $content, $matches));
+ $content = $matches[1];
+
+ $content = str_replace('\"', '"', $content);
+ return $content;
+ }
+
+ for ($x=0, $len=strlen($content); $x<$len; $x++) {
+ switch ($content[$x]) {
+ case '\\':
+ $str .= $content[++$x];
+
+ break;
+ case '"':
+ if (isset($str)) {
+ $result[] = $str;
+ unset($str);
+ }
+ else {
+ $str = '';
+ }
+
+ break;
+ default:
+ if (isset($str))
+ $str .= $content[$x];
+
+ break;
+ }
+ }
+
+ if (sizeof($result)>1)
+ return $result;
+ elseif (sizeof($result) == 1)
+ return $result[0];
+ else
+ return NULL;
+ }
+
+ private function _safe_serial($data)
+ {
+ $data = str_replace("\r", "[!r]", $data);
+ $data = str_replace("\n", "[!n]", $data);
+ return $data;
+ }
+
+ private function _regular_serial($data)
+ {
+ $data = str_replace("[!r]", "\r", $data);
+ $data = str_replace("[!n]", "\n", $data);
+ return $data;
+ }
+}
+
+?> \ No newline at end of file
diff --git a/plugins/sieverules/jquery.maskedinput.js b/plugins/sieverules/jquery.maskedinput.js
new file mode 100644
index 000000000..0d9ce6e06
--- /dev/null
+++ b/plugins/sieverules/jquery.maskedinput.js
@@ -0,0 +1,7 @@
+/*
+ Masked Input plugin for jQuery
+ Copyright (c) 2007-2013 Josh Bush (digitalbush.com)
+ Licensed under the MIT license (http://digitalbush.com/projects/masked-input-plugin/#license)
+ Version: 1.3.1
+*/
+(function(e){function t(){var e=document.createElement("input"),t="onpaste";return e.setAttribute(t,""),"function"==typeof e[t]?"paste":"input"}var n,a=t()+".mask",r=navigator.userAgent,i=/iphone/i.test(r),o=/android/i.test(r);e.mask={definitions:{9:"[0-9]",a:"[A-Za-z]","*":"[A-Za-z0-9]"},dataName:"rawMaskFn",placeholder:"_"},e.fn.extend({caret:function(e,t){var n;if(0!==this.length&&!this.is(":hidden"))return"number"==typeof e?(t="number"==typeof t?t:e,this.each(function(){this.setSelectionRange?this.setSelectionRange(e,t):this.createTextRange&&(n=this.createTextRange(),n.collapse(!0),n.moveEnd("character",t),n.moveStart("character",e),n.select())})):(this[0].setSelectionRange?(e=this[0].selectionStart,t=this[0].selectionEnd):document.selection&&document.selection.createRange&&(n=document.selection.createRange(),e=0-n.duplicate().moveStart("character",-1e5),t=e+n.text.length),{begin:e,end:t})},unmask:function(){return this.trigger("unmask")},mask:function(t,r){var c,l,s,u,f,h;return!t&&this.length>0?(c=e(this[0]),c.data(e.mask.dataName)()):(r=e.extend({placeholder:e.mask.placeholder,completed:null},r),l=e.mask.definitions,s=[],u=h=t.length,f=null,e.each(t.split(""),function(e,t){"?"==t?(h--,u=e):l[t]?(s.push(RegExp(l[t])),null===f&&(f=s.length-1)):s.push(null)}),this.trigger("unmask").each(function(){function c(e){for(;h>++e&&!s[e];);return e}function d(e){for(;--e>=0&&!s[e];);return e}function m(e,t){var n,a;if(!(0>e)){for(n=e,a=c(t);h>n;n++)if(s[n]){if(!(h>a&&s[n].test(R[a])))break;R[n]=R[a],R[a]=r.placeholder,a=c(a)}b(),x.caret(Math.max(f,e))}}function p(e){var t,n,a,i;for(t=e,n=r.placeholder;h>t;t++)if(s[t]){if(a=c(t),i=R[t],R[t]=n,!(h>a&&s[a].test(i)))break;n=i}}function g(e){var t,n,a,r=e.which;8===r||46===r||i&&127===r?(t=x.caret(),n=t.begin,a=t.end,0===a-n&&(n=46!==r?d(n):a=c(n-1),a=46===r?c(a):a),k(n,a),m(n,a-1),e.preventDefault()):27==r&&(x.val(S),x.caret(0,y()),e.preventDefault())}function v(t){var n,a,i,l=t.which,u=x.caret();t.ctrlKey||t.altKey||t.metaKey||32>l||l&&(0!==u.end-u.begin&&(k(u.begin,u.end),m(u.begin,u.end-1)),n=c(u.begin-1),h>n&&(a=String.fromCharCode(l),s[n].test(a)&&(p(n),R[n]=a,b(),i=c(n),o?setTimeout(e.proxy(e.fn.caret,x,i),0):x.caret(i),r.completed&&i>=h&&r.completed.call(x))),t.preventDefault())}function k(e,t){var n;for(n=e;t>n&&h>n;n++)s[n]&&(R[n]=r.placeholder)}function b(){x.val(R.join(""))}function y(e){var t,n,a=x.val(),i=-1;for(t=0,pos=0;h>t;t++)if(s[t]){for(R[t]=r.placeholder;pos++<a.length;)if(n=a.charAt(pos-1),s[t].test(n)){R[t]=n,i=t;break}if(pos>a.length)break}else R[t]===a.charAt(pos)&&t!==u&&(pos++,i=t);return e?b():u>i+1?(x.val(""),k(0,h)):(b(),x.val(x.val().substring(0,i+1))),u?t:f}var x=e(this),R=e.map(t.split(""),function(e){return"?"!=e?l[e]?r.placeholder:e:void 0}),S=x.val();x.data(e.mask.dataName,function(){return e.map(R,function(e,t){return s[t]&&e!=r.placeholder?e:null}).join("")}),x.attr("readonly")||x.one("unmask",function(){x.unbind(".mask").removeData(e.mask.dataName)}).bind("focus.mask",function(){clearTimeout(n);var e;S=x.val(),e=y(),n=setTimeout(function(){b(),e==t.length?x.caret(0,e):x.caret(e)},10)}).bind("blur.mask",function(){y(),x.val()!=S&&x.change()}).bind("keydown.mask",g).bind("keypress.mask",v).bind(a,function(){setTimeout(function(){var e=y(!0);x.caret(e),r.completed&&e==x.val().length&&r.completed.call(x)},0)}),y()}))}})})(jQuery); \ No newline at end of file
diff --git a/plugins/sieverules/lib/Net/Sieve.php b/plugins/sieverules/lib/Net/Sieve.php
new file mode 120000
index 000000000..fa112b6a9
--- /dev/null
+++ b/plugins/sieverules/lib/Net/Sieve.php
@@ -0,0 +1 @@
+../../../../../php/Net/Sieve.php \ No newline at end of file
diff --git a/plugins/sieverules/localization/ca_ES.inc b/plugins/sieverules/localization/ca_ES.inc
new file mode 100644
index 000000000..63ad80d0f
--- /dev/null
+++ b/plugins/sieverules/localization/ca_ES.inc
@@ -0,0 +1,168 @@
+<?php
+/* Author: GràciaNet */
+
+$labels = array();
+$labels['filters'] = 'Filtres';
+$labels['managefilters'] = 'Gesti&oacute; de filtres';
+$labels['filtername'] = 'Nom del filtre';
+$labels['disablerule'] = 'Desactivar regla';
+$labels['disabled'] = 'Desactivada';
+$labels['newfilter'] = 'Nou filtre';
+$labels['moveup'] = 'Moure amunt';
+$labels['movedown'] = 'Moure avall';
+$labels['filterallof'] = 'coincideix amb TOTES les regles seg&uuml;ents';
+$labels['filteranyof'] = 'coincideix amb ALGUNA de les seg&uuml;ents regles';
+$labels['filterany'] = 'tots els missatges';
+$labels['filtercontains'] = 'cont&eacute;';
+$labels['filternotcontains'] = 'no cont&eacute';
+$labels['filteris'] = '&eacutes igual a';
+$labels['filterisnot'] = 'es diferent de';
+$labels['filterexists'] = 'existeix';
+$labels['filternotexists'] = 'no existeix';
+$labels['filterregex'] = 'coincideix amb l\'expressi&oacute; regular';
+$labels['filternotregex'] = 'no coincideix amb l\'expressi&oacute; regular';
+$labels['filterunder'] = '&eacutes menys que';
+$labels['filterover'] = '&eacutes m&eacutes que';
+$labels['filteradvoptions'] = 'm&eacutes opcions...';
+$labels['spamtest'] = 'Probabilitat de Spam';
+$labels['operator'] = 'Operador';
+$labels['comparator'] = 'Comparador';
+$labels['isgreaterthan'] = '&eacutes major que';
+$labels['isgreaterthanequal'] = '&eacutes major o igual que';
+$labels['islessthan'] = '&eacutes menor que';
+$labels['islessthanequal'] = '&eacutes menor o igual que';
+$labels['equals'] = '&eacutes igual a';
+$labels['notequals'] = '&eacutes diferent de';
+$labels['countisgreaterthan'] = 'quantitat &eacutes major que';
+$labels['countisgreaterthanequal'] = 'quantitat ñes major o igual que';
+$labels['countislessthan'] = 'quantitat &eacutes menor que';
+$labels['countislessthanequal'] = 'quantitat &eacutes menor o igual que';
+$labels['countequals'] = 'quantitat &eacutes igual a';
+$labels['countnotequals'] = 'quantitat &eacutes diferent de';
+$labels['valueisgreaterthan'] = 'valor &eacutes major que';
+$labels['valueisgreaterthanequal'] = 'valor &eacutes major o igual que';
+$labels['valueislessthan'] = 'valor &eacutes menor que';
+$labels['valueislessthanequal'] = 'valor &eacutes menor o igual que';
+$labels['valueequals'] = 'valor &eacutes igual a';
+$labels['valuenotequals'] = 'valor &eacutes diferent de';
+$labels['userpart'] = 'la part de l\'usuari &eacutes igual a';
+$labels['notuserpart'] = 'la part de l\'usuari &eacutes diferent de';
+$labels['detailpart'] = 'la part del detall &eacutes igual a';
+$labels['notdetailpart'] = 'la part del detall &eacutes diferent de';
+$labels['domainpart'] = 'la part del domini &eacutes igual a';
+$labels['notdomainpart'] = 'la part del domini &eacutes diferent de';
+$labels['teststring'] = 'Iniciant prova';
+$labels['messagemoveto'] = 'Moure missatge a';
+$labels['messageredirect'] = 'Redirigir missatge a';
+$labels['messageimapflags'] = 'Marcar missatge com';
+$labels['messagereject'] = 'Rebutjar amb avís';
+$labels['messagevacation'] = 'Missatge de vacances';
+$labels['messagekeep'] = 'Mantenir missatges';
+$labels['messagediscard'] = 'Descartar missatge';
+$labels['messagenotify'] = 'Enviar notificaci&oacute; ';
+$labels['messagestop'] = 'Deixar de processar filtres';
+$labels['messagehelp'] = 'Qu&egrave; &eacutes això?';
+$labels['sieveorigsubj'] = 'Afegir assumpte original a la resposta';
+$labels['sievevachandle'] = 'Manejador';
+$labels['method'] = 'M&egrave;tode';
+$labels['options'] = 'Opcions';
+$labels['messagesrules'] = 'Regles de filtrat';
+$labels['messagesactions'] = 'Accions del filtre';
+$labels['sieveto'] = 'Àlies';
+$labels['sievefrom'] = 'De';
+$labels['flag'] = 'Marca';
+$labels['importancen'] = 'Cap';
+$labels['importance1'] = '1';
+$labels['importance2'] = '2';
+$labels['importance3'] = '3';
+$labels['flagread'] = 'Llegit';
+$labels['flagdeleted'] = 'Eliminat';
+$labels['flaganswered'] = 'Respost';
+$labels['flagdraft'] = 'Esborrany';
+$labels['flagflagged'] = 'Marcat';
+$labels['addsieverule'] = 'Afegir una altra regla despr&eacutes d\'aquesta';
+$labels['addsieveact'] = 'Afegir una altra acci&oacute; despr&eacutes d\'aquesta';
+$labels['deletesieverule'] = 'Eliminar aquesta regla';
+$labels['deletesieveact'] = 'Eliminar aquesta acci&oacute; ';
+$labels['envelopefrom'] = 'Remitent a la capçalera';
+$labels['envelopeto'] = 'Destinatari e la capçalera';
+$labels['otherheader'] = 'Una altra capçalera';
+$labels['days'] = 'Període';
+$labels['message'] = 'Missatge';
+$labels['sieveruleheaders'] = 'Veure exemples d\'altres capçaleres';
+$labels['examplefilters'] = 'Filtres d\'exemple';
+$labels['importfilters'] = 'Importar filtres';
+$labels['usedefaultfilter'] = 'Utilitzar filters per defecte';
+$labels['importfilter'] = 'Importar filtre';
+$labels['adveditor'] = 'Editor avançat';
+$labels['messageredirectcopy'] = 'Envía una còpia a ';
+$labels['messagecopyto'] = 'Copiar missatge a ';
+$labels['body'] = 'Cos';
+$labels['auto'] = 'Auto';
+$labels['raw'] = 'Raw';
+$labels['text'] = 'Text';
+$labels['other'] = 'Altre';
+$labels['bodycontentpart'] = 'Contingut';
+$labels['notchecked'] = 'no seleccionat';
+$labels['spamlevelisgreaterthanequal'] = '&eacutes major o igual que';
+$labels['spamlevelislessthanequal'] = '&eacutes menor o igual que';
+$labels['spamlevelequals'] = '&eacutes igual a';
+$labels['selectruleset'] = 'Escollir conjunt de regles';
+$labels['activeruleset'] = '%s (actiu)';
+$labels['activateruleset'] = 'Activar aquest conjunt de regles';
+$labels['newruleset'] = 'Crear un nou conjunt de regles.';
+$labels['delruleset'] = 'Eliminar aquest conjunt de regles';
+$labels['renameruleset'] = 'Renombrar aquest conjunt de regles';
+$labels['copy'] = 'Copiar';
+$labels['copyexistingfilter'] = 'Copiar els filtres existentes';
+$labels['copytoruleset'] = 'Copiar filtre a un altre conjunt de regles';
+$labels['copyfromruleset'] = 'Copiar filtres des d\'un conjunt de regles existents';
+
+$messages = array();
+$messages['nosieverules'] = 'No s\'han trobat filtres.';
+$messages['filterdeleteconfirm'] = 'Est&agrave;s segur de voler eliminar aquest filtre?';
+$messages['ruledeleteconfirm'] = 'Est&agrave;s segur de voler eliminar aquesta regla?';
+$messages['actiondeleteconfirm'] = 'Est&agrave;s segur de voler eliminar aquesta acci&oacute; ?';
+$messages['filterunknownerror'] = 'Error desconegut en el servidor';
+$messages['filterconnerror'] = 'Impossible connectar amb el servidor sieve';
+$messages['filterdeleteerror'] = 'No s\'ha pogut eliminar el filtre. Error del servidor';
+$messages['filterdeleted'] = 'Filtre eliminat';
+$messages['filtersaved'] = 'Filtre guardat';
+$messages['filtersaveerror'] = 'Incapaç de guardar el filtre. Error en el servidor';
+$messages['vacdaysexp'] = 'El període &eacutes el número de dies que el missatge no ser&agrave; reenviat al mateix usuari, sense importar el nombre de vegades que intenti posar-se en contacte amb tu<br /><br />Por ejemplo, si en Jaume envia un misssatge un dilluns, i t&eacute un període fixat en 7, en Jaume rebr&agrave; un avís de vacances el dilluns però no en rebr&agrave; cap altre fins al proper dilluns, malgrat env&iuml;i m&eacutes missatges durant la setmana.';
+$messages['vachandleexp'] = 'Es pot usar un manejador per a vincular diferents missatges de vacances tots junts. Un cop s\'env&iuml;i el missatge no se n\'enviar&agrave; un altre que contingut el mateix manejador durant el període definit.';
+$messages['vactoexp'] = 'Llista de destinataris addicionals que seran inclosos en l\'auto-resposta. Si un usuari no &eacutes la sefa adreça personal i no est&agrave; a la llista no se li enviar&agrave;n missatges.';
+$messages['norulename'] = 'Cal assignar un nom al filtre';
+$messages['ruleexists'] = 'Ja existeix un filtre amb aquest nom. Escolleix-ne un altre';
+$messages['noheader'] = 'Heu d\'introdu&iuml;r el nom de la capçalera a verificar';
+$messages['headerbadchars'] = 'Error: La capçalera cont&eacute car&agrave;cters no permesos';
+$messages['noheadervalue'] = 'Ingresseu un valor per a comparar-lo amb la capçalera';
+$messages['sizewrongformat'] = 'Error: El tamany del missatge ha de ser num&egrave;ric';
+$messages['noredirect'] = 'Introdu&iuml;u una adreça de correu a la qual redirigir tots els missatges';
+$messages['redirectaddresserror'] = 'Error: Adreça no v&agrave;lida';
+$messages['noreject'] = 'Introdu&iuml;u el text a enviar en els missatges rebutjats';
+$messages['vacnodays'] = 'Introdu&iuml;u el número de dies per al període que el missatge no ser&agrave; reenviat a la mateixa persona';
+$messages['vacdayswrongformat'] = 'Error: El període ha de ser de m&eacutes d\'1 dia';
+$messages['vacnomsg'] = 'Introdu&iuml;u un text per al missatge';
+$messages['notifynomethod'] = 'Introdu&iuml;u un m&egrave;tode a trav&eacutes del qual s\'enviar&agrave; la notificaci&oacute; ';
+$messages['notifynomsg'] = 'Introdu&iuml;u un text per al seu missatge';
+$messages['sieveruleexp'] = 'Heu de definir una o m&eacutes regles que s\'empraran per a comprar els missatges. Els filtres s&oacute; n executats en l\'ordre que apareixen a l\'esquerra d\'aquesta pantalla. Si es troba una coincid&egrave;ncia, la resta del filtres no es comproven.';
+$messages['sieveactexp'] = 'Seleccioneu una de les opcions que apareixen a continuaci&oacute; . Aquesta acci&oacute; ser&agrave; executada per cada missatge que encaixi amb les regles definides a sobre d\'aquest text.';
+$messages['sieveheadershlp'] = 'A continuaci&oacute; hi ha alguns exemples de capçaleres que poden verificar-se amb filtres. Seleccioni\'n una per afegir a la regla o introdu&iuml;u-ne una de pròpia en el requadre de dalt.';
+$messages['movingfilter'] = 'Movent filtre...';
+$messages['noexistingfilters'] = 'No s\'han detectat filtres!';
+$messages['importdefault'] = '<b>Emprar filtres per defecte:</b> Hi ha un joc de filtres per defecte disponibles. Voleu instalar una còpia d\'aquests filtres?';
+$messages['importother'] = '<b>Importar filtres:</b> S\'ha trobat un altre joc de filtres de %s. Voleu importar-los a la llsita de filtres?';
+$messages['switchtoadveditor'] = 'L\'editor avançat li permet editar les regles de sieve directament. Qualsevol canvi que faci ser&agrave; il.legible per l\'editor normal de regles i es perder&agrave; si guarda modificacions amb l\'editor normal. Voleu continuar?';
+$messages['filterimported'] = 'Filtre importat correctament';
+$messages['filterimporterror'] = 'No s\'ha pogut importar el filtre . Error en el servidor';
+$messages['badoperator'] = 'Ho lamentem, però l\'operador seleccionat no es pot usar en aquesta regla.';
+$messages['filteractionerror'] = 'L\'acci&oacute; requerida no est&agrave; disponible en aquest servidor.';
+$messages['filtermissingerror'] = 'No s\'ha pogut localitzar la regla solicitada.';
+$messages['delrulesetconf'] = 'Esteu segur de voler eliminar aquest conjunt de regles?';
+$messages['rulesetexists'] = 'Ja existeix un conjunt de regles amb aquest nom. Escolliu-ne un altre.';
+$messages['copyexisting'] = '<b> Copia el seg&uuml;ent conjunt de regles:</b> Voleu importar els filtres d\'un conjunt de regles existents al conjunt actual?';
+$messages['filtercopied'] = 'Filtre copiat correctament';
+$messages['nosieverulesets'] = 'No s\'han trobat regles.';
+
+?> \ No newline at end of file
diff --git a/plugins/sieverules/localization/cs_CZ.inc b/plugins/sieverules/localization/cs_CZ.inc
new file mode 100644
index 000000000..f5a8b5f61
--- /dev/null
+++ b/plugins/sieverules/localization/cs_CZ.inc
@@ -0,0 +1,195 @@
+<?php
+/* Author: Kepi */
+
+$labels = array();
+$labels['filters'] = 'Filtry';
+$labels['filtersname'] = 'Filtry ($name)';
+$labels['managefilters'] = 'Spravovat filtry';
+$labels['filtername'] = 'Název filtru';
+$labels['disablerule'] = 'Vypnout filtr';
+$labels['disabled'] = 'vypnuto';
+$labels['newfilter'] = 'Nový filtr';
+$labels['moveup'] = 'Posunout nahoru';
+$labels['movedown'] = 'Posunout dolů';
+$labels['filterallof'] = 'odpovídá všem pravidlům';
+$labels['filteranyof'] = 'odpovídá alespoň jednomu pravidlu';
+$labels['filterany'] = 'všechny zprávy';
+$labels['filtercontains'] = 'obsahuje';
+$labels['filternotcontains'] = 'neobsahuje';
+$labels['filteris'] = 'je rovno';
+$labels['filterisnot'] = 'není rovno';
+$labels['filterexists'] = 'existuje';
+$labels['filternotexists'] = 'neexistuje';
+$labels['filterregex'] = 'odpovídá regulárnímu výrazu';
+$labels['filternotregex'] = 'neodpovídá regulárnímu výrazu';
+$labels['filterunder'] = 'je méně než';
+$labels['filterover'] = 'je více než';
+$labels['filterbefore'] = 'je před';
+$labels['filterafter'] = 'je po';
+$labels['filteradvoptions'] = 'více možností...';
+$labels['spamtest'] = 'Pravděpodobnost spamu';
+$labels['operator'] = 'Operátor';
+$labels['comparator'] = 'Porovnávání';
+$labels['isgreaterthan'] = 'je větší než';
+$labels['isgreaterthanequal'] = 'je větší nebo rovno';
+$labels['islessthan'] = 'je menší než';
+$labels['islessthanequal'] = 'je menší nebo rovno';
+$labels['equals'] = 'je rovno';
+$labels['notequals'] = 'není rovno';
+$labels['countisgreaterthan'] = 'počet je větší než';
+$labels['countisgreaterthanequal'] = 'počet je větší nebo roven';
+$labels['countislessthan'] = 'počet je menší než';
+$labels['countislessthanequal'] = 'počet je menší nebo roven';
+$labels['countequals'] = 'počet je roven';
+$labels['countnotequals'] = 'počet není roven';
+$labels['valueisgreaterthan'] = 'hodnota je větší než';
+$labels['valueisgreaterthanequal'] = 'hodnota je větší nebo rovna';
+$labels['valueislessthan'] = 'hodnota je menší než';
+$labels['valueislessthanequal'] = 'hodnota je menší nebo rovna';
+$labels['valueequals'] = 'hodnota je rovna';
+$labels['valuenotequals'] = 'hodnota není rovna';
+$labels['userpart'] = 'část uživatele je rovna';
+$labels['notuserpart'] = 'část uživatele není rovna';
+$labels['detailpart'] = 'upřesňující část je rovna';
+$labels['notdetailpart'] = 'upřesňující část není rovna';
+$labels['domainpart'] = 'doménová část je rovna';
+$labels['notdomainpart'] = 'doménová část není rovna';
+$labels['teststring'] = 'Testovací řetězec';
+$labels['messagemoveto'] = 'Přesunout zprávy do';
+$labels['messageredirect'] = 'Přesměrovat zprávy na';
+$labels['messageimapflags'] = 'Označit zprávy jako';
+$labels['messagereject'] = 'Odmítnout se zprávou';
+$labels['messagevacation'] = 'Automatická odpověď';
+$labels['messagekeep'] = 'Ponechat zprávu';
+$labels['messagediscard'] = 'Zahodit zprávu';
+$labels['messagenotify'] = 'Odeslat upozornění';
+$labels['messagestop'] = 'Přerušit vykonávání filtrů';
+$labels['messagehelp'] = 'Co je toto?';
+$labels['sieveorigsubj'] = 'K odpovědi připojit původní předmět';
+$labels['sievevachandle'] = 'Štítek';
+$labels['method'] = 'Metoda';
+$labels['options'] = 'Možnosti';
+$labels['messagesrules'] = 'Pravidla filtru';
+$labels['messagesactions'] = 'Akce filtru';
+$labels['sieveto'] = 'Aliasy';
+$labels['sievefrom'] = 'Od';
+$labels['flag'] = 'Priorita';
+$labels['importancen'] = 'Žádná';
+$labels['importance1'] = 'Vysoká';
+$labels['importance2'] = 'Normální';
+$labels['importance3'] = 'Nízká';
+$labels['flagread'] = 'Přečtené';
+$labels['flagdeleted'] = 'Odstraněné';
+$labels['flaganswered'] = 'Zodpovězené';
+$labels['flagdraft'] = 'Koncept';
+$labels['flagflagged'] = 'Označené';
+$labels['addsieverule'] = 'Přidat další pravidlo (pod toto pravidlo)';
+$labels['addsieveact'] = 'Přidat další akci (pod tuto akci)';
+$labels['deletesieverule'] = 'Odstranit toto pravidlo';
+$labels['deletesieveact'] = 'Odstranit tuto akci';
+$labels['envelopefrom'] = 'Skutečný odesílatel';
+$labels['envelopeto'] = 'Skutečný adresát';
+$labels['otherheader'] = 'Další hlavička';
+$labels['days'] = 'Prodleva';
+$labels['message'] = 'Zpráva';
+$labels['sieveruleheaders'] = 'Zobrazit ukázky dalších hlaviček';
+$labels['examplefilters'] = 'Ukázkové filtry';
+$labels['importfilters'] = 'Import filtrů';
+$labels['usedefaultfilter'] = 'Použít výchozí filtry';
+$labels['importfilter'] = 'Importovat filtry';
+$labels['moreactions'] = 'Více voleb...';
+$labels['adveditor'] = 'Pokročilý editor';
+$labels['stdeditor'] = 'Normální editor';
+$labels['messageredirectcopy'] = 'Odeslat kopii na';
+$labels['messagecopyto'] = 'Kopírovat zprávu do';
+$labels['body'] = 'Tělo zprávy';
+$labels['auto'] = 'Automaticky';
+$labels['raw'] = 'Surové';
+$labels['text'] = 'Textové';
+$labels['other'] = 'Ostatní';
+$labels['bodycontentpart'] = 'Obsahová část';
+$labels['notchecked'] = 'Nekontrolováno';
+$labels['spamlevelisgreaterthanequal'] = 'je větší nebo rovno';
+$labels['spamlevelislessthanequal'] = 'je menší nebo rovno';
+$labels['spamlevelequals'] = 'je rovno';
+$labels['i;ascii-casemap'] = 'shoda bez ohledu na velikost písmen';
+$labels['i;octet'] = 'přesná shoda';
+$labels['i;ascii-numeric'] = 'číselná shoda';
+$labels['selectruleset'] = 'Vyberte sadu pravidel';
+$labels['activeruleset'] = '%s (aktivní)';
+$labels['activateruleset'] = 'Aktivovat tuto sadu filtrů';
+$labels['isactive'] = 'Aktivní sada filtrů';
+$labels['isinactive'] = 'Neaktivní sada filtrů';
+$labels['newruleset'] = 'Vytvořit novou sadu filtrů';
+$labels['delruleset'] = 'Odstranit tuto sadu filtrů';
+$labels['renameruleset'] = 'Přejmenovat tuto sadu filtrů';
+$labels['copy'] = 'Kopírovat';
+$labels['copyexistingfilter'] = 'Kopírovat existující filtry';
+$labels['copytoruleset'] = 'Kopírovat filtr do jiné sady';
+$labels['copyfromruleset'] = 'Kopířovat filtry z existující sady';
+$labels['time'] = 'Čas';
+$labels['weekday'] = 'Den v týdnu';
+$labels['virustest'] = 'Pravděpodobnost viru';
+$labels['novirus'] = 'žádný virus nenalezen';
+$labels['virusremoved'] = 'virus nalezen a odstraněn';
+$labels['viruscured'] = 'virus nalezen a vyléčen';
+$labels['possiblevirus'] = 'zpráva pravděpodobně obsahuje virus';
+$labels['definitevirus'] = 'zpráva určitě obsahuje virus';
+
+$messages = array();
+$messages['nosieverules'] = 'Nenalezeny žádné filtry.';
+$messages['filterdeleteconfirm'] = 'Opravdu chcete smazat tento filtr?';
+$messages['ruledeleteconfirm'] = 'Opravdu chcete smazat toto pravidlo?';
+$messages['actiondeleteconfirm'] = 'Opravdu chcete smazat tuto akci?';
+$messages['filterunknownerror'] = 'Neznámá chyba serveru.';
+$messages['filterconnerror'] = 'Nepodařilo se připojit k serveru sieve.';
+$messages['filterdeleteerror'] = 'Nepodařilo se smazat filtr. Nastala chyba serveru.';
+$messages['filterdeleted'] = 'Filtr úspěšně smazán.';
+$messages['filtersaved'] = 'Filt úspěšně uložen.';
+$messages['filtersaveerror'] = 'Nepodařilo se uložit filtr. Nastala chyba serveru.';
+$messages['vacdaysexp'] = 'Prodleva je počet dní, během kterých nebude zpráva doručena stejnému uživateli, nehledě na to, kolikrát vás kontaktuje.<br /><br />Příklad: Pokud vám Honza napíše v pondělí a prodleva je nastavena na 7, Honza obdrží zprávu o vaší nedostupnosti v pondělí, ale do dalšího pondělí už žádnou další zprávu nedostane, nehledě na počet mailů, které vám během týdne pošle.';
+$messages['vachandleexp'] = 'Štítek může být použit ke spojení více různých oznámení o nedostupnosti dohromady. Jakmile je jedna zpráva zaslána, žádná další se stejným štítkem už v dané době zaslána nebude.';
+$messages['vactoexp'] = 'Seznam dalších emailů, které jsou v automatické odpovědi zahrnuty. Pokud není příjemcem emailu vaše hlavní adresa a není na tomto seznamu, žádná zpráva nebude odeslána.';
+$messages['vactoexp_adv'] = 'Jednotlivé adresy oddělte čárkou. Například: test1@adresa.cz,test2@adresa.cz,test3@adresa.cz';
+$messages['vactoexp_err'] = 'Chyba: Více aliasů musí být odděleno čárkou.';
+$messages['norulename'] = 'Zadejte prosím jméno pro tento filtr.';
+$messages['ruleexists'] = 'Filtr se stejným jménem již existuje. Zadejte prosím jiné.';
+$messages['noheader'] = 'Zadejte prosím jméno hlavičky k otestování.';
+$messages['headerbadchars'] = 'Chyba: hlavička obsahuje zakázané znaky.';
+$messages['noheadervalue'] = 'Zadejte prosím hodnotu, vůči které bude hlavička testována.';
+$messages['sizewrongformat'] = 'Chyba: velikost zprávy musí být číslo.';
+$messages['noredirect'] = 'Zadejte prosím emailovou adresu, na kterou se má zpráva přesměrovat.';
+$messages['redirectaddresserror'] = 'Chyba: zdá se, že je email chybný.';
+$messages['noreject'] = 'Zadejte prosím zprávu, která se odešle spolu s odmítnutým emailem.';
+$messages['vacnodays'] = 'Zadejte prosím počet dní pro prodlevu, během které nebude zpráva zasílána stejné osobě.';
+$messages['vacdayswrongformat'] = 'Chyba: prodleva musí být číslo větší nebo rovné 1.';
+$messages['vacnomsg'] = 'Zadejte prosím nějaký text pro vaši zprávu.';
+$messages['notifynomethod'] = 'Zadejte prosím metodu, jakou má být notifikace zaslána.';
+$messages['notifynomsg'] = 'Zadejte prosím nějaký text pro vaši zprávu.';
+$messages['sieveruleexp'] = 'Prosím přidejte jedno nebo více pravidel vůči kterým bude každá zpráva testována. Filtry jsou vyhodnocovány v pořadí v jakém jsou uvedeny v sloupci vlevo. Pokud je nalezena shoda, žádný další filtr se již nevyhodnocuje.';
+$messages['sieveruleexp_stop'] = 'Zadejte prosím jedno nebo více pravidel vůči kterým bude každá zpráva testována. Filtry jsou vyhodnocovány v pořadí v jakém jsou uvedeny v sloupci vlevo dokud není dosaženo \'Přerušení\' akce.';
+$messages['sieveactexp'] = 'Prosím vyberte si z voleb níže. Akce budou vykonány pro jakoukoliv zprávu, která vyhovuje pravidlům výše.';
+$messages['sieveheadershlp'] = 'Níže je několik případu hlaviček, které mohou být ve filtrech testovány. Pro přidání do pravidla vyberte hlavičku nebo zadejte vlastní v poli nahoře.';
+$messages['movingfilter'] = 'Přesouvám filtr...';
+$messages['noexistingfilters'] = 'Nenalezeny žádné existující filtry!';
+$messages['importdefault'] = '<b>Použít výchozí filtry:</b> Je dostupná sada výchozích filtrů. Přejte si tuto sadu využít?';
+$messages['importother'] = '<b>Importovat filtry:</b> Byla nalezena jiná sada filtrů z %s. Chcete tyto filtry importovat do stávající sady?';
+$messages['switchtoadveditor'] = 'Přepnutí do pokročilého editoru vám umožní přímo upravovat soubor sieve filtrů. Jakékoliv provedené změny mohou být nečitelné v normálním editoru a mohou být ztraceny, pokud je v normálním editoru uložíte. Přejete si pokračovat?';
+$messages['filterimported'] = 'Filtry úspěšně naimportovány.';
+$messages['filterimporterror'] = 'Nelze importovat filtry. Nastala chyba serveru.';
+$messages['notifyinvalidmethod'] = 'Metoda není napsána ve správném formátu, musí se jednat o URI. Například: `mailto:upozorneni@adresa.cz`.';
+$messages['nobodycontentpart'] = 'Zadejte prosím obsahovou část k otestování.';
+$messages['badoperator'] = 'Omlouváme se, ale operátor, který jste vybrali, nemůže být v tomto pravidle použit.';
+$messages['filteractionerror'] = 'Akce, které jste si vyžádali, není podporována serverem.';
+$messages['filtermissingerror'] = 'Nepodařilo se najít vyžádané pravidlo.';
+$messages['contentpartexp'] = 'MIME-typ nebo konkrétní část zprávy, která má být testována. Například: `message/rfc822`, `text/html`, `audio/mp3` or `image`.';
+$messages['delrulesetconf'] = 'Opravdu chcete smazat tuto sadu pravidel?';
+$messages['rulesetexists'] = 'Sada pravidel s tímto jménem již existuje. Zadejte prosím jinou.';
+$messages['copyexisting'] = '<b>Kopírovat existující sadu pravidel:</b> Chcete zkopírovat filtry z existující sady pravidel do vybrané sady?';
+$messages['filtercopied'] = 'Filtry úspěšně zkopírovány.';
+$messages['nosieverulesets'] = 'Nenalezeny žádné sady pravidel.';
+$messages['baddateformat'] = 'Chyba: Zadejte prosím datum ve formátu YYYY-MM-DD';
+$messages['badtimeformat'] = 'Chyba: Zadejte prosím čas ve formátu HH:MM:SS';
+$messages['missingfoldername'] = 'Chyba: Zadejte prosím jméno složky';
+
+?> \ No newline at end of file
diff --git a/plugins/sieverules/localization/de_CH.inc b/plugins/sieverules/localization/de_CH.inc
new file mode 100644
index 000000000..d203cd8c1
--- /dev/null
+++ b/plugins/sieverules/localization/de_CH.inc
@@ -0,0 +1,192 @@
+<?php
+/* Author: Mike Constabel */
+
+$labels = array();
+$labels['filters'] = 'Filter';
+$labels['managefilters'] = 'Filter verwalten';
+$labels['filtername'] = 'Filtername';
+$labels['disablerule'] = 'Filterregel abschalten';
+$labels['disabled'] = 'abgeschaltet';
+$labels['newfilter'] = 'Neuer Filter';
+$labels['moveup'] = 'Aufwärts';
+$labels['movedown'] = 'Abwärts';
+$labels['filterallof'] = 'trifft alle folgenden Regeln';
+$labels['filteranyof'] = 'trifft irgendeine der folgenden Regeln';
+$labels['filterany'] = 'alle Nachrichten';
+$labels['filtercontains'] = 'enthält';
+$labels['filternotcontains'] = 'enthält nicht';
+$labels['filteris'] = 'ist identisch mit';
+$labels['filterisnot'] = 'ist nicht identisch mit';
+$labels['filterexists'] = 'existiert';
+$labels['filternotexists'] = 'existiert nicht';
+$labels['filterregex'] = 'trifft auf den regulären Ausdruck zu';
+$labels['filternotregex'] = 'trifft nicht auf den regulären Ausdruck zu';
+$labels['filterunder'] = 'ist kleiner als';
+$labels['filterover'] = 'ist größer als';
+$labels['filterbefore'] = 'ist vor';
+$labels['filterafter'] = 'ist nach';
+$labels['filteradvoptions'] = 'weitere Optionen...';
+$labels['spamtest'] = 'Spam-Wahrscheinlichkeit';
+$labels['operator'] = 'Operator';
+$labels['comparator'] = 'Komparator';
+$labels['isgreaterthan'] = 'ist größer als';
+$labels['isgreaterthanequal'] = 'ist größer als oder gleich ';
+$labels['islessthan'] = 'ist kleiner als';
+$labels['islessthanequal'] = 'ist kleiner als oder gleich';
+$labels['equals'] = 'ist gleich';
+$labels['notequals'] = 'ist nicht gleich';
+$labels['countisgreaterthan'] = 'Anzahl ist größer als';
+$labels['countisgreaterthanequal'] = 'Anzahl ist mindestens';
+$labels['countislessthan'] = 'Anzahl ist kleiner';
+$labels['countislessthanequal'] = 'Anzahl ist höchstens';
+$labels['countequals'] = 'Anzahl ist gleich';
+$labels['countnotequals'] = 'Anzahl ist ungleich';
+$labels['valueisgreaterthan'] = 'Wert ist größer als';
+$labels['valueisgreaterthanequal'] = 'Wert ist mindestens';
+$labels['valueislessthan'] = 'Wert ist kleiner als';
+$labels['valueislessthanequal'] = 'Wert ist höchstens';
+$labels['valueequals'] = 'Wert ist gleich';
+$labels['valuenotequals'] = 'Wert ist ungleich';
+$labels['userpart'] = 'User-Teil gleicht';
+$labels['notuserpart'] = 'User-Teil gleicht nicht';
+$labels['detailpart'] = 'Detail-Teil gleicht';
+$labels['notdetailpart'] = 'Detail-Teil gleicht nicht';
+$labels['domainpart'] = 'Domain-Teil gleicht';
+$labels['notdomainpart'] = 'Domain-Teil gleicht nicht';
+$labels['teststring'] = 'Test-Zeichenkette';
+$labels['messagemoveto'] = 'Verschiebe Nachricht nach';
+$labels['messageredirect'] = 'Leite Nachricht weiter an';
+$labels['messageimapflags'] = 'Markiere Nachricht als';
+$labels['messagereject'] = 'Lehne Nachricht ab mit Begründung';
+$labels['messagevacation'] = 'Abwesenheitsnachricht';
+$labels['messagekeep'] = 'Behalte Nachricht';
+$labels['messagediscard'] = 'Verwerfe Nachricht';
+$labels['messagenotify'] = 'Sende Benachrichtigung';
+$labels['messagestop'] = 'Filterverarbeitung beenden';
+$labels['messagehelp'] = 'Hilfe';
+$labels['sieveorigsubj'] = 'Hänge originalen Betreff an die Antwort an';
+$labels['sievevachandle'] = 'Handle';
+$labels['method'] = 'Methode';
+$labels['options'] = 'Optionen';
+$labels['messagesrules'] = 'Filterregeln';
+$labels['messagesactions'] = 'Filteraktionen';
+$labels['sieveto'] = 'Alias';
+$labels['sievefrom'] = 'From';
+$labels['flag'] = 'Markierung';
+$labels['importancen'] = 'Keine';
+$labels['importance1'] = '1';
+$labels['importance2'] = '1';
+$labels['importance3'] = '1';
+$labels['flagread'] = 'Gelesen';
+$labels['flagdeleted'] = 'Gelöscht';
+$labels['flaganswered'] = 'Beantwortet';
+$labels['flagdraft'] = 'Entwurf';
+$labels['flagflagged'] = 'Markiert';
+$labels['addsieverule'] = 'Weitere Regel unterhalb dieser hinzufügen';
+$labels['addsieveact'] = 'Weitere Aktion unterhalb dieser hinzufügen';
+$labels['deletesieverule'] = 'Diese Regel löschen';
+$labels['deletesieveact'] = 'Diese Aktion löschen';
+$labels['envelopefrom'] = 'Envelope From';
+$labels['envelopeto'] = 'Envelope To';
+$labels['otherheader'] = 'Anderer Header';
+$labels['days'] = 'Zeitraum';
+$labels['message'] = 'Nachricht';
+$labels['sieveruleheaders'] = 'Zeige Beispiele für andere Header';
+$labels['examplefilters'] = 'Beispielfilter...';
+$labels['importfilters'] = 'Filter importieren';
+$labels['usedefaultfilter'] = 'Verwende Standardfilter';
+$labels['importfilter'] = 'Filter importieren';
+$labels['moreactions'] = 'Weitere Optionen...';
+$labels['adveditor'] = 'Erweiterter Editor';
+$labels['stdeditor'] = 'Standard-Editor';
+$labels['messageredirectcopy'] = 'Sende eine Kopie an';
+$labels['messagecopyto'] = 'Kopiere Nachricht nach';
+$labels['body'] = 'Body';
+$labels['auto'] = 'Auto';
+$labels['raw'] = 'Raw';
+$labels['text'] = 'Text';
+$labels['other'] = 'Anderes';
+$labels['bodycontentpart'] = 'Content Part';
+$labels['notchecked'] = 'nicht geprüft';
+$labels['spamlevelisgreaterthanequal'] = 'ist mindestens';
+$labels['spamlevelislessthanequal'] = 'ist höchstens';
+$labels['spamlevelequals'] = 'ist gleich';
+$labels['i;ascii-casemap'] = 'schreibungsunabhängige Zeichenfolge';
+$labels['i;octet'] = 'exakte Zeichenfolge';
+$labels['i;ascii-numeric'] = 'zahlenmäßige Übereinstimmung';
+$labels['selectruleset'] = 'Wähle Regelsatz';
+$labels['activeruleset'] = '%s (aktiv)';
+$labels['activateruleset'] = 'Aktiviere Regelsatz';
+$labels['newruleset'] = 'Erstelle Regelsatz';
+$labels['delruleset'] = 'Lösche diesen Regelsatz';
+$labels['renameruleset'] = 'Regelsatz umbenennen';
+$labels['copy'] = 'Kopieren';
+$labels['copyexistingfilter'] = 'Kopiere bestehende Filter';
+$labels['copytoruleset'] = 'Kopiere Filter in anderen Regelsatz';
+$labels['copyfromruleset'] = 'Kopiere Filter aus anderem Regelsatz';
+$labels['time'] = 'Zeit';
+$labels['weekday'] = 'Wochentag';
+$labels['virustest'] = 'Viruswahrscheinlichkeit';
+$labels['novirus'] = 'keinen Virus gefunden';
+$labels['virusremoved'] = 'Virus gefunden und entfernt';
+$labels['viruscured'] = 'Virus gefunden und kuriert';
+$labels['possiblevirus'] = 'Nachricht enthält möglicherweise einen Virus';
+$labels['definitevirus'] = 'Nachricht enthält definitiv einen Virus';
+
+$messages = array();
+$messages['nosieverules'] = 'Keine Filter gefunden.';
+$messages['filterdeleteconfirm'] = 'Bist du sicher das du diesen Filter löschen möchtest?';
+$messages['ruledeleteconfirm'] = 'Bist du sicher das du diese Regel löschen möchtest?';
+$messages['actiondeleteconfirm'] = 'Bist du sicher das du diese Aktion löschen möchtest?';
+$messages['filterunknownerror'] = 'Unbekannter Serverfehler';
+$messages['filterconnerror'] = 'Konnte keine Verbindung zum Sieve-Server aufbauen';
+$messages['filterdeleteerror'] = 'Konnte Filter nicht löschen. Serverfehler';
+$messages['filterdeleted'] = 'Filter erfolgreich gelöscht';
+$messages['filtersaved'] = 'Filter erfolgreich gespeichert';
+$messages['filtersaveerror'] = 'Konnte Filter nicht speichern. Serverfehler';
+$messages['vacdaysexp'] = 'Zeitraum in Anzahl Tagen, in dem die Abwesenheitsnachricht nicht erneut an den selben Absender gesendet wird.<br /><br />Beispiel: Wenn Joe dir am Montag eine Mail schickt und der Zeitraum beträgt 7, bekommt Joe sofort eine Abwesenheitsnachricht gesendet, dann aber bis zum darauffolgenden Montag keine mehr, egal wie häufig er weitere Mails sendet.';
+$messages['vachandleexp'] = 'Ein Handle kann genutzt werden um verschiedene Abwesenheitsnachrichten zu koppeln, so dass im Zeitraum keine weiteren Abwesenheitsnachrichten gesendet werden die das selbe Handle besitzen.';
+$messages['vactoexp'] = 'Liste zusätzlicher Empfängeradressen für die ebenfalls eine Abwesenheitsnachricht gesendet wird. Gehen Mails ein, deren Empfänger nicht die Hauptadresse ist und die nicht in dieser Liste stehen wird keine Abwesenheitsnachricht gesendet.';
+$messages['vactoexp_adv'] = 'Trenne mehrere Adressen mit einem Komma (,). Zum Beispiel: test1@example.com,test2@example.com,test3@example.com';
+$messages['vactoexp_err'] = 'Fehler: Mehrere Adressen müssen durch ein Komma (,) getrennt werden';
+$messages['norulename'] = 'Bitte gib einen Namen für diesen Filter ein';
+$messages['ruleexists'] = 'Ein Filter mit diesem Namen existiert bereits. Wähle einen anderen';
+$messages['noheader'] = 'Bitte gib den Namen des zu testenden Headers ein';
+$messages['headerbadchars'] = 'Fehler: Header enthält unzulässige Zeichen';
+$messages['noheadervalue'] = 'Bitte gib den Wert ein, gegen den der Header getestet werden soll';
+$messages['sizewrongformat'] = 'Fehler: Nachrichtengröße muss numerisch sein';
+$messages['noredirect'] = 'Bitte gib eine E-Mail Adresse zur Weiterleitung ein';
+$messages['redirectaddresserror'] = 'Fehler: E-Mail Adresse ungültig';
+$messages['noreject'] = 'Bitte gib eine Nachricht als Begründung für die Abweisung der Mail ein';
+$messages['vacnodays'] = 'Bitte gib die Anzahl Tage ein, währendessen die Abwesenheitsnachricht nicht erneut an den selben Absender gesendet wird.';
+$messages['vacdayswrongformat'] = 'Fehler: Der Zeitraum muss numerisch größer gleich 1 sein';
+$messages['vacnomsg'] = 'Bitte gib einen Text für deine Nachricht ein';
+$messages['notifynomethod'] = 'Bitte gibt eine Methode an mit der Benachrichtigungen versendet werden sollen.';
+$messages['notifynomsg'] = 'Bitte gebe einen Text für die Nachricht ein';
+$messages['sieveruleexp'] = 'Bitte erstelle eine oder mehrere Regeln gegen die jede Nachricht getestet werden soll. Filter werden in der Reihenfolge durchlaufen, in der sie links gelistet sind. Wenn ein Filter zutrifft, werden keine weiteren Filter durchlaufen.';
+$messages['sieveruleexp_stop'] = 'Bitte wähle mindestens eine Regel, die auf die Nachrichten angewandt werden soll. Filter werden in der Reihenfolge abgearbeitet, wie sie auf der linken Seite dargestellt sind bis eine \'Stop\'-Regel zutrifft.';
+$messages['sieveactexp'] = 'Bitte wähle eine von den unten gelisteten Optionen. Diese Aktionen werden für jede Nachricht ausgeführt, die auf obige Filterregel(n) passt.';
+$messages['sieveheadershlp'] = 'Unten werden einige Header als Beispiel für mögliche Header angezeigt. Wähle einen oder füge oben einen eigenen Header hinzu.';
+$messages['movingfilter'] = 'Verschiebe Filter...';
+$messages['noexistingfilters'] = 'Keine vorhandenen Filter gefunden!';
+$messages['importdefault'] = '<b>Verwende Standardfilter:</b> Es sind eine Reihe von Standardfiltern verfügbar. Möchtest Du diese verwenden?';
+$messages['importother'] = '<b>Filter importieren:</b> EIne Reihe von Filtern von %s wurden gefunden. Möchtest Du diese Filter Deinen Filtern hinzufügen?';
+$messages['switchtoadveditor'] = 'Die verwendung des erweiterten Editors ermöglicht es, die Sieve-Filter direkt zu bearbeiten. Alle Änderungen sind für den normalen Editor unlesbar und werden verworfen wenn eine Regel mit dem normalen Editor gespeichert wird. Möchtest Du fortfahren?';
+$messages['filterimported'] = 'Filterimport erfolgreich';
+$messages['filterimporterror'] = 'Fehler beim Filterimport. Serverfehler.';
+$messages['notifyinvalidmethod'] = 'Die Methode scheint ein ungültiges Format zu haben. Es muss eine URI sein, z. B.: `mailto:alert@example.com`.';
+$messages['nobodycontentpart'] = 'Bitte gib den zu testenden Bereich des Inhalts an';
+$messages['badoperator'] = 'Der gewählte Operator kann in dieser Regel nicht verwendet werden';
+$messages['filteractionerror'] = 'Die gewünschte Aktion wird vom Server nicht unterstützt';
+$messages['filtermissingerror'] = 'Die angeforderte Regel konnte nicht gefunden werden';
+$messages['contentpartexp'] = 'Der MIME-Typ oder der Teil der Nachricht, der getestet werden soll. Zum Beispiel: `message/rfc822`, `text/html`, `audio/mp3` oder `image`.';
+$messages['delrulesetconf'] = 'Soll dieser Regelsatz wirklich gelöscht werden?';
+$messages['rulesetexists'] = 'Ein Regelsatz mit diesem Namen existiert bereits. Bitte wähle einen anderen Namen.';
+$messages['copyexisting'] = 'Kopiere bestehenden Regelsatz: Sollen die Filter von einem bestehenden Regelsatz in den akutellen Regelsatz kopiert werden?';
+$messages['filtercopied'] = 'Filter erfolgreich kopiert.';
+$messages['nosieverulesets'] = 'Keine Regelsätze gefunden.';
+$messages['baddateformat'] = 'Fehler: Bitte das Datum im Format JJJJ-MM-TT eingeben.';
+$messages['badtimeformat'] = 'Fehler: Bitte die Uhrzeit im Format HH:MM:SS eingeben.';
+$messages['missingfoldername'] = 'Fehler: Bitte ein Verzeichnisnamen eingeben.';
+
+?> \ No newline at end of file
diff --git a/plugins/sieverules/localization/de_DE.inc b/plugins/sieverules/localization/de_DE.inc
new file mode 100644
index 000000000..3d7499c35
--- /dev/null
+++ b/plugins/sieverules/localization/de_DE.inc
@@ -0,0 +1,192 @@
+<?php
+/* Author: Michael Metz */
+
+$labels = array();
+$labels['filters'] = 'Filter';
+$labels['managefilters'] = 'Filter verwalten';
+$labels['filtername'] = 'Filtername';
+$labels['disablerule'] = 'Filterregel abschalten';
+$labels['disabled'] = 'abgeschaltet';
+$labels['newfilter'] = 'Neuer Filter';
+$labels['moveup'] = 'Aufwärts';
+$labels['movedown'] = 'Abwärts';
+$labels['filterallof'] = 'trifft alle folgenden Regeln';
+$labels['filteranyof'] = 'trifft irgendeine der folgenden Regeln';
+$labels['filterany'] = 'alle Nachrichten';
+$labels['filtercontains'] = 'enthält';
+$labels['filternotcontains'] = 'enthält nicht';
+$labels['filteris'] = 'ist identisch mit';
+$labels['filterisnot'] = 'ist nicht identisch mit';
+$labels['filterexists'] = 'existiert';
+$labels['filternotexists'] = 'existiert nicht';
+$labels['filterregex'] = 'trifft auf den regulären Ausdruck zu';
+$labels['filternotregex'] = 'trifft nicht auf den regulären Ausdruck zu';
+$labels['filterunder'] = 'ist kleiner als';
+$labels['filterover'] = 'ist größer als';
+$labels['filterbefore'] = 'ist vor';
+$labels['filterafter'] = 'ist nach';
+$labels['filteradvoptions'] = 'weitere Optionen...';
+$labels['spamtest'] = 'Spam-Wahrscheinlichkeit';
+$labels['operator'] = 'Operator';
+$labels['comparator'] = 'Komparator';
+$labels['isgreaterthan'] = 'ist größer als';
+$labels['isgreaterthanequal'] = 'ist größer als oder gleich ';
+$labels['islessthan'] = 'ist kleiner als';
+$labels['islessthanequal'] = 'ist kleiner als oder gleich';
+$labels['equals'] = 'ist gleich';
+$labels['notequals'] = 'ist nicht gleich';
+$labels['countisgreaterthan'] = 'Anzahl ist größer als';
+$labels['countisgreaterthanequal'] = 'Anzahl ist mindestens';
+$labels['countislessthan'] = 'Anzahl ist kleiner';
+$labels['countislessthanequal'] = 'Anzahl ist höchstens';
+$labels['countequals'] = 'Anzahl ist gleich';
+$labels['countnotequals'] = 'Anzahl ist ungleich';
+$labels['valueisgreaterthan'] = 'Wert ist größer als';
+$labels['valueisgreaterthanequal'] = 'Wert ist mindestens';
+$labels['valueislessthan'] = 'Wert ist kleiner als';
+$labels['valueislessthanequal'] = 'Wert ist höchstens';
+$labels['valueequals'] = 'Wert ist gleich';
+$labels['valuenotequals'] = 'Wert ist ungleich';
+$labels['userpart'] = 'User-Teil gleicht';
+$labels['notuserpart'] = 'User-Teil gleicht nicht';
+$labels['detailpart'] = 'Detail-Teil gleicht';
+$labels['notdetailpart'] = 'Detail-Teil gleicht nicht';
+$labels['domainpart'] = 'Domain-Teil gleicht';
+$labels['notdomainpart'] = 'Domain-Teil gleicht nicht';
+$labels['teststring'] = 'Test-Zeichenkette';
+$labels['messagemoveto'] = 'Verschiebe Nachricht nach';
+$labels['messageredirect'] = 'Leite Nachricht weiter an';
+$labels['messageimapflags'] = 'Markiere Nachricht als';
+$labels['messagereject'] = 'Lehne Nachricht ab mit Begründung';
+$labels['messagevacation'] = 'Abwesenheitsnachricht';
+$labels['messagekeep'] = 'Behalte Nachricht';
+$labels['messagediscard'] = 'Verwerfe Nachricht';
+$labels['messagenotify'] = 'Sende Benachrichtigung';
+$labels['messagestop'] = 'Filterverarbeitung beenden';
+$labels['messagehelp'] = 'Hilfe';
+$labels['sieveorigsubj'] = 'Hänge originalen Betreff an die Antwort an';
+$labels['sievevachandle'] = 'Handle';
+$labels['method'] = 'Methode';
+$labels['options'] = 'Optionen';
+$labels['messagesrules'] = 'Filterregeln';
+$labels['messagesactions'] = 'Filteraktionen';
+$labels['sieveto'] = 'Empfänger';
+$labels['sievefrom'] = 'Absender';
+$labels['flag'] = 'Markierung';
+$labels['importancen'] = 'Keine';
+$labels['importance1'] = '1';
+$labels['importance2'] = '1';
+$labels['importance3'] = '1';
+$labels['flagread'] = 'Gelesen';
+$labels['flagdeleted'] = 'Gelöscht';
+$labels['flaganswered'] = 'Beantwortet';
+$labels['flagdraft'] = 'Entwurf';
+$labels['flagflagged'] = 'Markiert';
+$labels['addsieverule'] = 'Weitere Regel unterhalb dieser hinzufügen';
+$labels['addsieveact'] = 'Weitere Aktion unterhalb dieser hinzufügen';
+$labels['deletesieverule'] = 'Diese Regel löschen';
+$labels['deletesieveact'] = 'Diese Aktion löschen';
+$labels['envelopefrom'] = 'Envelope From';
+$labels['envelopeto'] = 'Envelope To';
+$labels['otherheader'] = 'Anderer Header';
+$labels['days'] = 'Zeitraum';
+$labels['message'] = 'Nachricht';
+$labels['sieveruleheaders'] = 'Zeige Beispiele für andere Header';
+$labels['examplefilters'] = 'Beispielfilter...';
+$labels['importfilters'] = 'Filter importieren';
+$labels['usedefaultfilter'] = 'Verwende Standardfilter';
+$labels['importfilter'] = 'Filter importieren';
+$labels['moreactions'] = 'Weitere Optionen...';
+$labels['adveditor'] = 'Erweiterter Editor';
+$labels['stdeditor'] = 'Standard-Editor';
+$labels['messageredirectcopy'] = 'Sende eine Kopie an';
+$labels['messagecopyto'] = 'Kopiere Nachricht nach';
+$labels['body'] = 'Body';
+$labels['auto'] = 'Auto';
+$labels['raw'] = 'Raw';
+$labels['text'] = 'Text';
+$labels['other'] = 'Anderes';
+$labels['bodycontentpart'] = 'Content Part';
+$labels['notchecked'] = 'nicht geprüft';
+$labels['spamlevelisgreaterthanequal'] = 'ist mindestens';
+$labels['spamlevelislessthanequal'] = 'ist höchstens';
+$labels['spamlevelequals'] = 'ist gleich';
+$labels['i;ascii-casemap'] = 'schreibungsunabhängige Zeichenfolge';
+$labels['i;octet'] = 'exakte Zeichenfolge';
+$labels['i;ascii-numeric'] = 'zahlenmäßige Übereinstimmung';
+$labels['selectruleset'] = 'Wähle Regelsatz';
+$labels['activeruleset'] = '%s (aktiv)';
+$labels['activateruleset'] = 'Aktiviere Regelsatz';
+$labels['newruleset'] = 'Erstelle Regelsatz';
+$labels['delruleset'] = 'Lösche diesen Regelsatz';
+$labels['renameruleset'] = 'Regelsatz umbenennen';
+$labels['copy'] = 'Kopieren';
+$labels['copyexistingfilter'] = 'Kopiere bestehende Filter';
+$labels['copytoruleset'] = 'Kopiere Filter in anderen Regelsatz';
+$labels['copyfromruleset'] = 'Kopiere Filter aus anderem Regelsatz';
+$labels['time'] = 'Zeit';
+$labels['weekday'] = 'Wochentag';
+$labels['virustest'] = 'Viruswahrscheinlichkeit';
+$labels['novirus'] = 'keinen Virus gefunden';
+$labels['virusremoved'] = 'Virus gefunden und entfernt';
+$labels['viruscured'] = 'Virus gefunden und kuriert';
+$labels['possiblevirus'] = 'Nachricht enthält möglicherweise einen Virus';
+$labels['definitevirus'] = 'Nachricht enthält definitiv einen Virus';
+
+$messages = array();
+$messages['nosieverules'] = 'Keine Filter gefunden.';
+$messages['filterdeleteconfirm'] = 'Bist du sicher das du diesen Filter löschen möchtest?';
+$messages['ruledeleteconfirm'] = 'Bist du sicher das du diese Regel löschen möchtest?';
+$messages['actiondeleteconfirm'] = 'Bist du sicher das du diese Aktion löschen möchtest?';
+$messages['filterunknownerror'] = 'Unbekannter Serverfehler';
+$messages['filterconnerror'] = 'Konnte keine Verbindung zum Sieve-Server aufbauen';
+$messages['filterdeleteerror'] = 'Konnte Filter nicht löschen. Serverfehler';
+$messages['filterdeleted'] = 'Filter erfolgreich gelöscht';
+$messages['filtersaved'] = 'Filter erfolgreich gespeichert';
+$messages['filtersaveerror'] = 'Konnte Filter nicht speichern. Serverfehler';
+$messages['vacdaysexp'] = 'Zeitraum in Anzahl Tagen, in dem die Abwesenheitsnachricht nicht erneut an den selben Absender gesendet wird.<br /><br />Beispiel: Wenn Joe dir am Montag eine Mail schickt und der Zeitraum beträgt 7, bekommt Joe sofort eine Abwesenheitsnachricht gesendet, dann aber bis zum darauffolgenden Montag keine mehr, egal wie häufig er weitere Mails sendet.';
+$messages['vachandleexp'] = 'Ein Handle kann genutzt werden um verschiedene Abwesenheitsnachrichten zu koppeln, so dass im Zeitraum keine weiteren Abwesenheitsnachrichten gesendet werden die das selbe Handle besitzen.';
+$messages['vactoexp'] = 'Liste zusätzlicher Empfängeradressen, für die ebenfalls eine Abwesenheitsnachricht gesendet wird. Gehen Mails ein, deren Empfänger nicht die Hauptadresse ist und die nicht in dieser Liste stehen, wird keine Abwesenheitsnachricht gesendet.';
+$messages['vactoexp_adv'] = 'Trenne mehrere Adressen mit einem Komma (,). Zum Beispiel: test1@example.com,test2@example.com,test3@example.com';
+$messages['vactoexp_err'] = 'Fehler: Mehrere Adressen müssen durch ein Komma (,) getrennt werden';
+$messages['norulename'] = 'Bitte gib einen Namen für diesen Filter ein';
+$messages['ruleexists'] = 'Ein Filter mit diesem Namen existiert bereits. Wähle einen anderen';
+$messages['noheader'] = 'Bitte gib den Namen des zu testenden Headers ein';
+$messages['headerbadchars'] = 'Fehler: Header enthält unzulässige Zeichen';
+$messages['noheadervalue'] = 'Bitte gib den Wert ein, gegen den der Header getestet werden soll';
+$messages['sizewrongformat'] = 'Fehler: Nachrichtengröße muss numerisch sein';
+$messages['noredirect'] = 'Bitte gib eine E-Mail Adresse zur Weiterleitung ein';
+$messages['redirectaddresserror'] = 'Fehler: E-Mail Adresse ungültig';
+$messages['noreject'] = 'Bitte gib eine Nachricht als Begründung für die Abweisung der Mail ein';
+$messages['vacnodays'] = 'Bitte gib die Anzahl Tage ein, währendessen die Abwesenheitsnachricht nicht erneut an den selben Absender gesendet wird.';
+$messages['vacdayswrongformat'] = 'Fehler: Der Zeitraum muss numerisch größer gleich 1 sein';
+$messages['vacnomsg'] = 'Bitte gib einen Text für deine Nachricht ein';
+$messages['notifynomethod'] = 'Bitte gibt eine Methode an mit der Benachrichtigungen versendet werden sollen.';
+$messages['notifynomsg'] = 'Bitte gebe einen Text für die Nachricht ein';
+$messages['sieveruleexp'] = 'Bitte erstelle eine oder mehrere Regeln gegen die jede Nachricht getestet werden soll. Filter werden in der Reihenfolge durchlaufen, in der sie links gelistet sind. Wenn ein Filter zutrifft, werden keine weiteren Filter durchlaufen.';
+$messages['sieveruleexp_stop'] = 'Bitte wähle mindestens eine Regel, die auf die Nachrichten angewandt werden soll. Filter werden in der Reihenfolge abgearbeitet, wie sie auf der linken Seite dargestellt sind bis eine \'Stop\'-Regel zutrifft.';
+$messages['sieveactexp'] = 'Bitte wähle eine von den unten gelisteten Optionen. Diese Aktionen werden für jede Nachricht ausgeführt, die auf obige Filterregel(n) passt.';
+$messages['sieveheadershlp'] = 'Unten werden einige Header als Beispiel für mögliche Header angezeigt. Wähle einen oder füge oben einen eigenen Header hinzu.';
+$messages['movingfilter'] = 'Verschiebe Filter...';
+$messages['noexistingfilters'] = 'Keine vorhandenen Filter gefunden!';
+$messages['importdefault'] = '<b>Verwende Standardfilter:</b> Es sind eine Reihe von Standardfiltern verfügbar. Möchtest Du diese verwenden?';
+$messages['importother'] = '<b>Filter importieren:</b> EIne Reihe von Filtern von %s wurden gefunden. Möchtest Du diese Filter Deinen Filtern hinzufügen?';
+$messages['switchtoadveditor'] = 'Die verwendung des erweiterten Editors ermöglicht es, die Sieve-Filter direkt zu bearbeiten. Alle Änderungen sind für den normalen Editor unlesbar und werden verworfen wenn eine Regel mit dem normalen Editor gespeichert wird. Möchtest Du fortfahren?';
+$messages['filterimported'] = 'Filterimport erfolgreich';
+$messages['filterimporterror'] = 'Fehler beim Filterimport. Serverfehler.';
+$messages['notifyinvalidmethod'] = 'Die Methode scheint ein ungültiges Format zu haben. Es muss eine URI sein, z. B.: `mailto:alert@example.com`.';
+$messages['nobodycontentpart'] = 'Bitte gib den zu testenden Bereich des Inhalts an';
+$messages['badoperator'] = 'Der gewählte Operator kann in dieser Regel nicht verwendet werden';
+$messages['filteractionerror'] = 'Die gewünschte Aktion wird vom Server nicht unterstützt';
+$messages['filtermissingerror'] = 'Die angeforderte Regel konnte nicht gefunden werden';
+$messages['contentpartexp'] = 'Der MIME-Typ oder der Teil der Nachricht, der getestet werden soll. Zum Beispiel: `message/rfc822`, `text/html`, `audio/mp3` oder `image`.';
+$messages['delrulesetconf'] = 'Soll dieser Regelsatz wirklich gelöscht werden?';
+$messages['rulesetexists'] = 'Ein Regelsatz mit diesem Namen existiert bereits. Bitte wähle einen anderen Namen.';
+$messages['copyexisting'] = 'Kopiere bestehenden Regelsatz: Sollen die Filter von einem bestehenden Regelsatz in den akutellen Regelsatz kopiert werden?';
+$messages['filtercopied'] = 'Filter erfolgreich kopiert.';
+$messages['nosieverulesets'] = 'Keine Regelsätze gefunden.';
+$messages['baddateformat'] = 'Fehler: Bitte das Datum im Format JJJJ-MM-TT eingeben.';
+$messages['badtimeformat'] = 'Fehler: Bitte die Uhrzeit im Format HH:MM:SS eingeben.';
+$messages['missingfoldername'] = 'Fehler: Bitte ein Verzeichnisnamen eingeben.';
+
+?> \ No newline at end of file
diff --git a/plugins/sieverules/localization/en_GB.inc b/plugins/sieverules/localization/en_GB.inc
new file mode 100644
index 000000000..bdb0a15f4
--- /dev/null
+++ b/plugins/sieverules/localization/en_GB.inc
@@ -0,0 +1,205 @@
+<?php
+/* Author: Philip Weir */
+
+$labels = array();
+$labels['filters'] = 'Filters';
+$labels['filtersname'] = 'Filters ($name)';
+$labels['managefilters'] = 'Manage message filters';
+$labels['filtername'] = 'Filter name';
+$labels['disablerule'] = 'Disable rule';
+$labels['disabled'] = 'Disabled';
+$labels['newfilter'] = 'New filter';
+$labels['moveup'] = 'Move up';
+$labels['movedown'] = 'Move down';
+$labels['filterallof'] = 'matching all of the following rules';
+$labels['filteranyof'] = 'matching any of the following rules';
+$labels['filterany'] = 'all messages';
+$labels['filtercontains'] = 'contains';
+$labels['filternotcontains'] = 'does not contain';
+$labels['filteris'] = 'is equal to';
+$labels['filterisnot'] = 'is not equal to';
+$labels['filterexists'] = 'exists';
+$labels['filternotexists'] = 'does not exist';
+$labels['filterregex'] = 'matches regular expression';
+$labels['filternotregex'] = 'does not match regular expression';
+$labels['filterunder'] = 'is less than';
+$labels['filterover'] = 'is more than';
+$labels['filterbefore'] = 'is before';
+$labels['filterafter'] = 'is after';
+$labels['filteradvoptions'] = 'more options...';
+$labels['spamtest'] = 'Spam Probability';
+$labels['operator'] = 'Operator';
+$labels['comparator'] = 'Comparator';
+$labels['isgreaterthan'] = 'is greater than';
+$labels['isgreaterthanequal'] = 'is greater than or equal to';
+$labels['islessthan'] = 'is less than';
+$labels['islessthanequal'] = 'is less than or equal to';
+$labels['equals'] = 'is equal to';
+$labels['notequals'] = 'does not equal';
+$labels['countisgreaterthan'] = 'count is greater than';
+$labels['countisgreaterthanequal'] = 'count is greater than or equal to';
+$labels['countislessthan'] = 'count is less than';
+$labels['countislessthanequal'] = 'count is less than or equal to';
+$labels['countequals'] = 'count is equal to';
+$labels['countnotequals'] = 'count does not equal';
+$labels['valueisgreaterthan'] = 'value is greater than';
+$labels['valueisgreaterthanequal'] = 'value is greater than or equal to';
+$labels['valueislessthan'] = 'value is less than';
+$labels['valueislessthanequal'] = 'value is less than or equal to';
+$labels['valueequals'] = 'value is equal to';
+$labels['valuenotequals'] = 'value does not equal';
+$labels['userpart'] = 'user part equals';
+$labels['notuserpart'] = 'user part does not equal';
+$labels['detailpart'] = 'detail part equals';
+$labels['notdetailpart'] = 'detail part does not equal';
+$labels['domainpart'] = 'domain part equals';
+$labels['notdomainpart'] = 'domain part does not equal';
+$labels['teststring'] = 'Test string';
+$labels['messagemoveto'] = 'Move message to';
+$labels['messageredirect'] = 'Redirect message to';
+$labels['messageimapflags'] = 'Mark message as';
+$labels['messagereject'] = 'Reject with message';
+$labels['messagevacation'] = 'Out of Office Message';
+$labels['messagekeep'] = 'Keep message';
+$labels['messagediscard'] = 'Discard message';
+$labels['messagenotify'] = 'Send notification';
+$labels['messagestop'] = 'Stop processing filters';
+$labels['messagehelp'] = 'What is this?';
+$labels['sieveorigsubj'] = 'Append original subject to response';
+$labels['sievevachandle'] = 'Handle';
+$labels['method'] = 'Method';
+$labels['options'] = 'Options';
+$labels['messagesrules'] = 'Filter Rules';
+$labels['messagesactions'] = 'Filter Actions';
+$labels['sieveto'] = 'Aliases';
+$labels['sievefrom'] = 'From';
+$labels['flag'] = 'Importance';
+$labels['importancen'] = 'None';
+$labels['importance1'] = 'High';
+$labels['importance2'] = 'Normal';
+$labels['importance3'] = 'Low';
+$labels['flagread'] = 'Read';
+$labels['flagdeleted'] = 'Deleted';
+$labels['flaganswered'] = 'Answered';
+$labels['flagdraft'] = 'Draft';
+$labels['flagflagged'] = 'Flagged';
+$labels['addsieverule'] = 'Add another rule, below this one';
+$labels['addsieveact'] = 'Add another action, below this one';
+$labels['deletesieverule'] = 'Delete this rule';
+$labels['deletesieveact'] = 'Delete this action';
+$labels['envelopefrom'] = 'Envelope From';
+$labels['envelopeto'] = 'Envelope To';
+$labels['otherheader'] = 'Other header';
+$labels['days'] = 'Period';
+$labels['message'] = 'Message';
+$labels['sieveruleheaders'] = 'View examples of other headers';
+$labels['examplefilters'] = 'Example Filters';
+$labels['importfilters'] = 'Import Filters';
+$labels['usedefaultfilter'] = 'Use default filters';
+$labels['importfilter'] = 'Import filters';
+$labels['moreactions'] = 'More options...';
+$labels['adveditor'] = 'Advanced editor';
+$labels['stdeditor'] = 'Standard editor';
+$labels['messageredirectcopy'] = 'Send a copy to';
+$labels['messagecopyto'] = 'Copy message to';
+$labels['body'] = 'Body';
+$labels['auto'] = 'Auto';
+$labels['raw'] = 'Raw';
+$labels['text'] = 'Text';
+$labels['other'] = 'Other';
+$labels['bodycontentpart'] = 'Content Part';
+$labels['notchecked'] = 'not checked';
+$labels['spamlevelisgreaterthanequal'] = 'is greater than or equal to';
+$labels['spamlevelislessthanequal'] = 'is less than or equal to';
+$labels['spamlevelequals'] = 'is equal to';
+$labels['i;ascii-casemap'] = 'case-insensitive string match';
+$labels['i;octet'] = 'exact string match';
+$labels['i;ascii-numeric'] = 'numeric match';
+$labels['selectruleset'] = 'Select ruleset';
+$labels['activeruleset'] = '%s (active)';
+$labels['activateruleset'] = 'Activate this ruleset';
+$labels['isactive'] = 'Active ruleset';
+$labels['isinactive'] = 'Inactive ruleset';
+$labels['newruleset'] = 'Create a new ruleset';
+$labels['delruleset'] = 'Delete this ruleset';
+$labels['renameruleset'] = 'Rename this ruleset';
+$labels['copy'] = 'Copy';
+$labels['copyexistingfilter'] = 'Copy existing filters';
+$labels['copytoruleset'] = 'Copy filter to another ruleset';
+$labels['copyfromruleset'] = 'Copy filters from existing ruleset';
+$labels['time'] = 'Time';
+$labels['weekday'] = 'Weekday';
+$labels['virustest'] = 'Virus Probability';
+$labels['novirus'] = 'no virus found';
+$labels['virusremoved'] = 'virus found and removed';
+$labels['viruscured'] = 'virus found and cured';
+$labels['possiblevirus'] = 'message possibly contains a virus';
+$labels['definitevirus'] = 'message defiantly contains a virus';
+$labels['addheader'] = 'Add header';
+$labels['removeheader'] = 'Remove header';
+$labels['headername'] = 'Header name';
+$labels['headervalue'] = 'Header value';
+$labels['headerappend'] = 'Append to existing message header.';
+$labels['headerindex'] = 'Header index';
+$labels['headerdelall'] = 'all occurrences';
+$labels['last'] = 'last';
+
+$messages = array();
+$messages['nosieverules'] = 'No filters found.';
+$messages['filterdeleteconfirm'] = 'Are you sure you want to delete this filter?';
+$messages['ruledeleteconfirm'] = 'Are you sure you want to delete this rule?';
+$messages['actiondeleteconfirm'] = 'Are you sure you want to delete this action?';
+$messages['filterunknownerror'] = 'Unknown server error';
+$messages['filterconnerror'] = 'Unable to connect to sieve server';
+$messages['filterdeleteerror'] = 'Unable to delete filter. Server error occurred';
+$messages['filterdeleted'] = 'Filter deleted successfully';
+$messages['filtersaved'] = 'Filter saved successfully';
+$messages['filtersaveerror'] = 'Unable to save filter. Server error occurred';
+$messages['vacdaysexp'] = 'The period is the number of days during which the message will not be resent to the same user, no matter how many times they contact you.<br /><br />For example: If Joe emails you on Monday and the period is set to 7 then Joe will receive an out of office message on Monday but will not get another one until the following Monday, no matter how many emails he sends an email during the week.';
+$messages['vachandleexp'] = 'A handle can be used to link different out of office messages together, once one message has been sent no other message with the same handle will be resent in that period.';
+$messages['vactoexp'] = 'List of additional recipient addresses which are included in the auto replying. If a mail\'s recipient is not your main address and it\'s not on this list, no message will be sent.';
+$messages['vactoexp_adv'] = 'Separate multiple aliases with a comma (,). For Example: test1@example.com,test2@example.com,test3@example.com';
+$messages['vactoexp_err'] = 'Error: Multiple aliases should be separated with a comma (,)';
+$messages['norulename'] = 'Please enter a name for this filter';
+$messages['ruleexists'] = 'A filter with this name already exists. Please enter another';
+$messages['noheader'] = 'Please enter the name of the header to test';
+$messages['headerbadchars'] = 'Error: Header contains forbidden characters';
+$messages['noheadervalue'] = 'Please enter a value to test the header against';
+$messages['sizewrongformat'] = 'Error: Message size must be numeric';
+$messages['noredirect'] = 'Please enter an email address to redirect messages to';
+$messages['redirectaddresserror'] = 'Error: Address appears invalid';
+$messages['noreject'] = 'Please enter a message to send with rejected email';
+$messages['vacnodays'] = 'Please enter a number of days for the period in which the message will not be resent to the same person';
+$messages['vacdayswrongformat'] = 'Error: The period must be a number greater than or equal to 1';
+$messages['vacnomsg'] = 'Please enter some text for your message';
+$messages['notifynomethod'] = 'Please enter a method by which the notification should be sent';
+$messages['notifynomsg'] = 'Please enter some text for your message';
+$messages['sieveruleexp'] = 'Please define one or more rules against which each message will be tested. Filters are run in the order in which they appear on the left of this screen, if a match is found no further filters will be tested.';
+$messages['sieveruleexp_stop'] = 'Please define one or more rules against which each message will be tested. Filters are run in the order in which they appear on the left of this screen until a \'Stop\' action is met.';
+$messages['sieveactexp'] = 'Please select from the options below. These actions will be performed for any message matching the above rule(s).';
+$messages['sieveheadershlp'] = 'Below are some examples of other headers that can be tested by the filters. Select a header to add it to the rule or enter a custom one in the box above.';
+$messages['movingfilter'] = 'Moving filter...';
+$messages['noexistingfilters'] = 'No existing filters detected!';
+$messages['importdefault'] = '<b>Use default filters:</b> There is a set of default filters available. Would you like to use these filters?';
+$messages['importother'] = '<b>Import filters:</b> Another set of filters from %s has been found. Would you like to import these filters into your current set?';
+$messages['switchtoadveditor'] = 'Switching to the advanced editor allows you to edit the sieve file directly. Any changes here may be unreadable in the normal editor and may be lost when filters are saved using the normal editor. Do you wish to continue?';
+$messages['filterimported'] = 'Filter imported successfully';
+$messages['filterimporterror'] = 'Unable to import filter. Server error occurred';
+$messages['notifyinvalidmethod'] = 'The method does not appear to be written in a valid format, it must be a URI. For example: `mailto:alert@example.com`.';
+$messages['nobodycontentpart'] = 'Please enter a content part to test';
+$messages['badoperator'] = 'Sorry the operator you selected cannot be used in this rule';
+$messages['filteractionerror'] = 'The action you requested is not supported by the server';
+$messages['filtermissingerror'] = 'Unable to find the rule requested';
+$messages['contentpartexp'] = 'The MIME-type or specific part of the message which should be tested. For example: `message/rfc822`, `text/html`, `audio/mp3` or `image`.';
+$messages['delrulesetconf'] = 'Are you sure you want to delete this ruleset?';
+$messages['rulesetexists'] = 'A ruleset with this name already exists. Please enter another';
+$messages['copyexisting'] = '<b>Copy exiting ruleset:</b> Would you like to copy filters from an existing ruleset into your current set?';
+$messages['filtercopied'] = 'Filter copied successfully';
+$messages['nosieverulesets'] = 'No rulesets found.';
+$messages['baddateformat'] = 'Error: Please enter the date in the format YYYY-MM-DD';
+$messages['badtimeformat'] = 'Error: Please enter the time in the format HH:MM:SS';
+$messages['missingfoldername'] = 'Error: Please enter a folder name';
+$messages['eheadernoname'] = 'Error: Please enter a header name';
+$messages['eheadernoval'] = 'Error: Please enter a header value';
+
+?> \ No newline at end of file
diff --git a/plugins/sieverules/localization/en_US.inc b/plugins/sieverules/localization/en_US.inc
new file mode 100644
index 000000000..6049eeb73
--- /dev/null
+++ b/plugins/sieverules/localization/en_US.inc
@@ -0,0 +1,205 @@
+<?php
+/* Author: Philip Weir */
+
+$labels = array();
+$labels['filters'] = 'Filters';
+$labels['filtersname'] = 'Filters ($name)';
+$labels['managefilters'] = 'Manage message filters';
+$labels['filtername'] = 'Filter name';
+$labels['disablerule'] = 'Disable rule';
+$labels['disabled'] = 'Disabled';
+$labels['newfilter'] = 'New filter';
+$labels['moveup'] = 'Move up';
+$labels['movedown'] = 'Move down';
+$labels['filterallof'] = 'matching all of the following rules';
+$labels['filteranyof'] = 'matching any of the following rules';
+$labels['filterany'] = 'all messages';
+$labels['filtercontains'] = 'contains';
+$labels['filternotcontains'] = 'does not contain';
+$labels['filteris'] = 'is equal to';
+$labels['filterisnot'] = 'is not equal to';
+$labels['filterexists'] = 'exists';
+$labels['filternotexists'] = 'does not exist';
+$labels['filterregex'] = 'matches regular expression';
+$labels['filternotregex'] = 'does not match regular expression';
+$labels['filterunder'] = 'is less than';
+$labels['filterover'] = 'is more than';
+$labels['filterbefore'] = 'is before';
+$labels['filterafter'] = 'is after';
+$labels['filteradvoptions'] = 'more options...';
+$labels['spamtest'] = 'Spam Probability';
+$labels['operator'] = 'Operator';
+$labels['comparator'] = 'Comparator';
+$labels['isgreaterthan'] = 'is greater than';
+$labels['isgreaterthanequal'] = 'is greater than or equal to';
+$labels['islessthan'] = 'is less than';
+$labels['islessthanequal'] = 'is less than or equal to';
+$labels['equals'] = 'is equal to';
+$labels['notequals'] = 'does not equal';
+$labels['countisgreaterthan'] = 'count is greater than';
+$labels['countisgreaterthanequal'] = 'count is greater than or equal to';
+$labels['countislessthan'] = 'count is less than';
+$labels['countislessthanequal'] = 'count is less than or equal to';
+$labels['countequals'] = 'count is equal to';
+$labels['countnotequals'] = 'count does not equal';
+$labels['valueisgreaterthan'] = 'value is greater than';
+$labels['valueisgreaterthanequal'] = 'value is greater than or equal to';
+$labels['valueislessthan'] = 'value is less than';
+$labels['valueislessthanequal'] = 'value is less than or equal to';
+$labels['valueequals'] = 'value is equal to';
+$labels['valuenotequals'] = 'value does not equal';
+$labels['userpart'] = 'user part equals';
+$labels['notuserpart'] = 'user part does not equal';
+$labels['detailpart'] = 'detail part equals';
+$labels['notdetailpart'] = 'detail part does not equal';
+$labels['domainpart'] = 'domain part equals';
+$labels['notdomainpart'] = 'domain part does not equal';
+$labels['teststring'] = 'Test string';
+$labels['messagemoveto'] = 'Move message to';
+$labels['messageredirect'] = 'Redirect message to';
+$labels['messageimapflags'] = 'Mark message as';
+$labels['messagereject'] = 'Reject with message';
+$labels['messagevacation'] = 'Out of Office Message';
+$labels['messagekeep'] = 'Keep message';
+$labels['messagediscard'] = 'Discard message';
+$labels['messagenotify'] = 'Send notification';
+$labels['messagestop'] = 'Stop processing filters';
+$labels['messagehelp'] = 'What is this?';
+$labels['sieveorigsubj'] = 'Append original subject to response';
+$labels['sievevachandle'] = 'Handle';
+$labels['method'] = 'Method';
+$labels['options'] = 'Options';
+$labels['messagesrules'] = 'Filter Rules';
+$labels['messagesactions'] = 'Filter Actions';
+$labels['sieveto'] = 'Aliases';
+$labels['sievefrom'] = 'From';
+$labels['flag'] = 'Importance';
+$labels['importancen'] = 'None';
+$labels['importance1'] = 'High';
+$labels['importance2'] = 'Normal';
+$labels['importance3'] = 'Low';
+$labels['flagread'] = 'Read';
+$labels['flagdeleted'] = 'Deleted';
+$labels['flaganswered'] = 'Answered';
+$labels['flagdraft'] = 'Draft';
+$labels['flagflagged'] = 'Flagged';
+$labels['addsieverule'] = 'Add another rule, below this one';
+$labels['addsieveact'] = 'Add another action, below this one';
+$labels['deletesieverule'] = 'Delete this rule';
+$labels['deletesieveact'] = 'Delete this action';
+$labels['envelopefrom'] = 'Envelope From';
+$labels['envelopeto'] = 'Envelope To';
+$labels['otherheader'] = 'Other header';
+$labels['days'] = 'Period';
+$labels['message'] = 'Message';
+$labels['sieveruleheaders'] = 'View examples of other headers';
+$labels['examplefilters'] = 'Example Filters';
+$labels['importfilters'] = 'Import Filters';
+$labels['usedefaultfilter'] = 'Use default filters';
+$labels['importfilter'] = 'Import filters';
+$labels['moreactions'] = 'More options...';
+$labels['adveditor'] = 'Advanced editor';
+$labels['stdeditor'] = 'Standard editor';
+$labels['messageredirectcopy'] = 'Send a copy to';
+$labels['messagecopyto'] = 'Copy message to';
+$labels['body'] = 'Body';
+$labels['auto'] = 'Auto';
+$labels['raw'] = 'Raw';
+$labels['text'] = 'Text';
+$labels['other'] = 'Other';
+$labels['bodycontentpart'] = 'Content Part';
+$labels['notchecked'] = 'not checked';
+$labels['spamlevelisgreaterthanequal'] = 'is greater than or equal to';
+$labels['spamlevelislessthanequal'] = 'is less than or equal to';
+$labels['spamlevelequals'] = 'is equal to';
+$labels['i;ascii-casemap'] = 'case-insensitive string match';
+$labels['i;octet'] = 'exact string match';
+$labels['i;ascii-numeric'] = 'numeric match';
+$labels['selectruleset'] = 'Select ruleset';
+$labels['activeruleset'] = '%s (active)';
+$labels['activateruleset'] = 'Activate this ruleset';
+$labels['isactive'] = 'Active ruleset';
+$labels['isinactive'] = 'Inactive ruleset';
+$labels['newruleset'] = 'Create a new ruleset';
+$labels['delruleset'] = 'Delete this ruleset';
+$labels['renameruleset'] = 'Rename this ruleset';
+$labels['copy'] = 'Copy';
+$labels['copyexistingfilter'] = 'Copy existing filters';
+$labels['copytoruleset'] = 'Copy filter to another ruleset';
+$labels['copyfromruleset'] = 'Copy filters from existing ruleset';
+$labels['time'] = 'Time';
+$labels['weekday'] = 'Weekday';
+$labels['virustest'] = 'Virus Probability';
+$labels['novirus'] = 'no virus found';
+$labels['virusremoved'] = 'virus found and removed';
+$labels['viruscured'] = 'virus found and cured';
+$labels['possiblevirus'] = 'message possibly contains a virus';
+$labels['definitevirus'] = 'message possibly defiantly a virus';
+$labels['addheader'] = 'Add header';
+$labels['removeheader'] = 'Remove header';
+$labels['headername'] = 'Header name';
+$labels['headervalue'] = 'Header value';
+$labels['headerappend'] = 'Append to existing message header.';
+$labels['headerindex'] = 'Header index';
+$labels['headerdelall'] = 'all occurrences';
+$labels['last'] = 'last';
+
+$messages = array();
+$messages['nosieverules'] = 'No filters found.';
+$messages['filterdeleteconfirm'] = 'Are you sure you want to delete this filter?';
+$messages['ruledeleteconfirm'] = 'Are you sure you want to delete this rule?';
+$messages['actiondeleteconfirm'] = 'Are you sure you want to delete this action?';
+$messages['filterunknownerror'] = 'Unknown server error';
+$messages['filterconnerror'] = 'Unable to connect to sieve server';
+$messages['filterdeleteerror'] = 'Unable to delete filter. Server error occurred';
+$messages['filterdeleted'] = 'Filter deleted successfully';
+$messages['filtersaved'] = 'Filter saved successfully';
+$messages['filtersaveerror'] = 'Unable to save filter. Server error occurred';
+$messages['vacdaysexp'] = 'The period is the number of days during which the message will not be resent to the same user, no matter how many times they contact you.<br /><br />For example: If Joe emails you on Monday and the period is set to 7 then Joe will receive an out of office message on Monday but will not get another one until the following Monday, no matter how many emails he sends an email during the week.';
+$messages['vachandleexp'] = 'A handle can be used to link different out of office messages together, once one message has been sent no other message with the same handle will be resent in that period.';
+$messages['vactoexp'] = 'List of additional recipient addresses which are included in the auto replying. If a mail\'s recipient is not your main address and it\'s not on this list, no message will be sent.';
+$messages['vactoexp_adv'] = 'Separate multiple aliases with a comma (,). For Example: test1@example.com,test2@example.com,test3@example.com';
+$messages['vactoexp_err'] = 'Error: Multiple aliases should be separated with a comma (,)';
+$messages['norulename'] = 'Please enter a name for this filter';
+$messages['ruleexists'] = 'A filter with this name already exists. Please enter another';
+$messages['noheader'] = 'Please enter the name of the header to test';
+$messages['headerbadchars'] = 'Error: Header contains forbidden characters';
+$messages['noheadervalue'] = 'Please enter a value to test the header against';
+$messages['sizewrongformat'] = 'Error: Message size must be numeric';
+$messages['noredirect'] = 'Please enter an email address to redirect messages to';
+$messages['redirectaddresserror'] = 'Error: Address appears invalid';
+$messages['noreject'] = 'Please enter a message to send with rejected email';
+$messages['vacnodays'] = 'Please enter a number of days for the period in which the message will not be resent to the same person';
+$messages['vacdayswrongformat'] = 'Error: The period must be a number greater than or equal to 1';
+$messages['vacnomsg'] = 'Please enter some text for your message';
+$messages['notifynomethod'] = 'Please enter a method by which the notification should be sent';
+$messages['notifynomsg'] = 'Please enter some text for your message';
+$messages['sieveruleexp'] = 'Please define one or more rules against which each message will be tested. Filters are run in the order in which they appear on the left of this screen, if a match is found no further filters will be tested.';
+$messages['sieveruleexp_stop'] = 'Please define one or more rules against which each message will be tested. Filters are run in the order in which they appear on the left of this screen until a \'Stop\' action is met.';
+$messages['sieveactexp'] = 'Please select from the options below. These actions will be performed for any message matching the above rule(s).';
+$messages['sieveheadershlp'] = 'Below are some examples of other headers that can be tested by the filters. Select a header to add it to the rule or enter a custom one in the box above.';
+$messages['movingfilter'] = 'Moving filter...';
+$messages['noexistingfilters'] = 'No existing filters detected!';
+$messages['importdefault'] = '<b>Use default filters:</b> There is a set of default filters available. Would you like to use these filters?';
+$messages['importother'] = '<b>Import filters:</b> Another set of filters from %s has been found. Would you like to import these filters into your current set?';
+$messages['switchtoadveditor'] = 'Switching to the advanced editor allows you to edit the sieve file directly. Any changes here may be unreadable in the normal editor and may be lost when filters are saved using the normal editor. Do you wish to continue?';
+$messages['filterimported'] = 'Filter imported successfully';
+$messages['filterimporterror'] = 'Unable to import filter. Server error occurred';
+$messages['notifyinvalidmethod'] = 'The method does not appear to be written in a valid format, it must be a URI. For example: `mailto:alert@example.com`.';
+$messages['nobodycontentpart'] = 'Please enter a content part to test';
+$messages['badoperator'] = 'Sorry the operator you selected cannot be used in this rule';
+$messages['filteractionerror'] = 'The action you requested is not supported by the server';
+$messages['filtermissingerror'] = 'Unable to find the rule requested';
+$messages['contentpartexp'] = 'The MIME-type or specific part of the message which should be tested. For example: `message/rfc822`, `text/html`, `audio/mp3` or `image`.';
+$messages['delrulesetconf'] = 'Are you sure you want to delete this ruleset?';
+$messages['rulesetexists'] = 'A ruleset with this name already exists. Please enter another';
+$messages['copyexisting'] = '<b>Copy exiting ruleset:</b> Would you like to copy filters from an existing ruleset into your current set?';
+$messages['filtercopied'] = 'Filter copied successfully';
+$messages['nosieverulesets'] = 'No rulesets found.';
+$messages['baddateformat'] = 'Error: Please enter the date in the format YYYY-MM-DD';
+$messages['badtimeformat'] = 'Error: Please enter the time in the format HH:MM:SS';
+$messages['missingfoldername'] = 'Error: Please enter a folder name';
+$messages['eheadernoname'] = 'Error: Please enter a header name';
+$messages['eheadernoval'] = 'Error: Please enter a header value';
+
+?> \ No newline at end of file
diff --git a/plugins/sieverules/localization/es_AR.inc b/plugins/sieverules/localization/es_AR.inc
new file mode 100644
index 000000000..b57e223a4
--- /dev/null
+++ b/plugins/sieverules/localization/es_AR.inc
@@ -0,0 +1,140 @@
+<?php
+/* Author: Alejandro Vargas */
+
+$labels = array();
+$labels['filters'] = 'Filtros';
+$labels['managefilters'] = 'Manejo de filtros';
+$labels['filtername'] = 'Nombre del filtro';
+$labels['disablerule'] = 'Desactivar regla';
+$labels['disabled'] = 'Desactivada';
+$labels['newfilter'] = 'Nuevo filtro';
+$labels['moveup'] = 'Mover arriba';
+$labels['movedown'] = 'Mover abajo';
+$labels['filterallof'] = 'concuerda con TODAS las reglas siguientes';
+$labels['filteranyof'] = 'concuerda con ALGUNA de las reglas siguientes';
+$labels['filterany'] = 'todos los mensajes';
+$labels['filtercontains'] = 'contiene';
+$labels['filternotcontains'] = 'no contiene';
+$labels['filteris'] = 'es igual a';
+$labels['filterisnot'] = 'es distinto de';
+$labels['filterexists'] = 'existe';
+$labels['filternotexists'] = 'no existe';
+$labels['filterregex'] = 'concuerda con la expresion regular';
+$labels['filternotregex'] = 'no concuerda con la expresion regular';
+$labels['filterunder'] = 'es menos que';
+$labels['filterover'] = 'es mas que';
+$labels['filteradvoptions'] = 'mas opciones...';
+$labels['operator'] = 'Operador';
+$labels['comparator'] = 'Comparador';
+$labels['isgreaterthan'] = 'es mayor que';
+$labels['isgreaterthanequal'] = 'es mayor o igual que';
+$labels['islessthan'] = 'es menor que';
+$labels['islessthanequal'] = 'es menor o igual que';
+$labels['equals'] = 'es igual a';
+$labels['notequals'] = 'es distinto de';
+$labels['countisgreaterthan'] = 'cantidad es mayor que';
+$labels['countisgreaterthanequal'] = 'cantidad es mayor o igual que';
+$labels['countislessthan'] = 'cantidad es menor que';
+$labels['countislessthanequal'] = 'cantidad es menor o igual que';
+$labels['countequals'] = 'cantidad es igual a';
+$labels['countnotequals'] = 'cantidad es distinto de';
+$labels['valueisgreaterthan'] = 'valor es mayor que';
+$labels['valueisgreaterthanequal'] = 'valor es mayor o igual que';
+$labels['valueislessthan'] = 'valor es menor que';
+$labels['valueislessthanequal'] = 'valor es menor o igual que';
+$labels['valueequals'] = 'valor es igual a';
+$labels['valuenotequals'] = 'valor es distinto de';
+$labels['userpart'] = 'la parte del usuario es igual a';
+$labels['notuserpart'] = 'la parte del usuario es distinta de';
+$labels['detailpart'] = 'la parte del detalle es igual a';
+$labels['notdetailpart'] = 'la parte del detalle es distinta de';
+$labels['domainpart'] = 'la parte del dominio es igual a';
+$labels['notdomainpart'] = 'la parte del dominio es distinta de';
+$labels['teststring'] = 'Iniciando prueba';
+$labels['messagemoveto'] = 'Mover mensaje a';
+$labels['messageredirect'] = 'Redirigir mensaje a';
+$labels['messageimapflags'] = 'Marcar mensaje como';
+$labels['messagereject'] = 'Rechazar con aviso';
+$labels['messagevacation'] = 'Mensaje de vacaciones';
+$labels['messagekeep'] = 'Mantener mensaje';
+$labels['messagediscard'] = 'Descartar mensaje';
+$labels['messagenotify'] = 'Enviar notificacion';
+$labels['messagestop'] = 'Dejar de procesar filtros';
+$labels['messagehelp'] = 'Que es esto?';
+$labels['sieveorigsubj'] = 'Agregar asunto iriginal a la respuesta';
+$labels['sievevachandle'] = 'Manejador';
+$labels['method'] = 'Metodo';
+$labels['options'] = 'Opciones';
+$labels['messagesrules'] = 'Reglas de filtrado';
+$labels['messagesactions'] = 'Acciones del filtro';
+$labels['sieveto'] = 'Alias';
+$labels['sievefrom'] = 'De';
+$labels['flag'] = 'Marca';
+$labels['importancen'] = 'Ninguno';
+$labels['importance1'] = '1';
+$labels['importance2'] = '2';
+$labels['importance3'] = '3';
+$labels['flagread'] = 'Leido';
+$labels['flagdeleted'] = 'Borrado';
+$labels['flaganswered'] = 'Respondido';
+$labels['flagdraft'] = 'Borrador';
+$labels['flagflagged'] = 'Marcado';
+$labels['addsieverule'] = 'Agregar otra regla despues de esta';
+$labels['addsieveact'] = 'Agregar otra accion despues de esta';
+$labels['deletesieverule'] = 'Borrar esta regla';
+$labels['deletesieveact'] = 'Borrar esta accion';
+$labels['envelopefrom'] = 'Remitente en la cabecera';
+$labels['envelopeto'] = 'Destinatario en la cabecera';
+$labels['otherheader'] = 'Otra cabecera';
+$labels['days'] = 'Periodo';
+$labels['message'] = 'Mensaje';
+$labels['sieveruleheaders'] = 'Ver ejemplos de otras cabeceras';
+$labels['examplefilters'] = 'Filtros de ejemplo';
+$labels['importfilters'] = 'Importar filtros';
+$labels['usedefaultfilter'] = 'Usar filtros por defecto';
+$labels['importfilter'] = 'Importar filtro';
+$labels['adveditor'] = 'Editor avanzado';
+$labels['spamlevelisgreaterthanequal'] = 'es mayor o igual que';
+$labels['spamlevelislessthanequal'] = 'es menor o igual que';
+$labels['spamlevelequals'] = 'es igual a';
+
+$messages = array();
+$messages['nosieverules'] = 'No se han encontrado filtros.';
+$messages['filterdeleteconfirm'] = '¿Está seguro de que quiere borrar este filtro?';
+$messages['ruledeleteconfirm'] = '¿Está seguro de que quiere borrar esta regla?';
+$messages['actiondeleteconfirm'] = '¿Está seguro de que quiere borrar esta acción?';
+$messages['filterunknownerror'] = 'Error desconocido en el servidor';
+$messages['filterconnerror'] = 'Imposible conectar con el servidor sieve';
+$messages['filterdeleteerror'] = 'No se pudo borrar el filtro. Error del servidor';
+$messages['filterdeleted'] = 'Filtro borrado';
+$messages['filtersaved'] = 'Filtro grabado';
+$messages['filtersaveerror'] = 'Incapaz de grabar filtro. Error en el servidor';
+$messages['vacdaysexp'] = 'El periodo es el numero de dias que el mensaje no será reenviado al mismo usuario, sin importar cuantas veces intente contactar con usted<br /><br />Por ejemplo, si Juan le manda un mensaje, unlunes, y tiene el periodo fijado en 7, Juan recibirá un aviso de vacaciones el lunes pero no recibirá otro hasta el siguiente lunes, sin importar cuántos emails le envíe durente la semana.';
+$messages['vachandleexp'] = 'Se puede usar un manejador para vincular diferentes mensajes de vacaciones todos juntos, una vez se envio un mensaje, no se enviará otro que tenga el mismo manejador durante el periodo definido.';
+$messages['vactoexp'] = 'Lista de destinatarios adicionales que será incluida en la auto respuesta. Si un destinatario no es su dirección principal, y no está en esta lista, no se le enviarán mensajes.';
+$messages['norulename'] = 'Debe asignar un nombre al filtro';
+$messages['ruleexists'] = 'Ya hay un filtro con ese nombre. Elija otro';
+$messages['noheader'] = 'Debe ingresar el nombre de la cabecera a verificar';
+$messages['headerbadchars'] = 'Error: La cabecera contiene caracteres no permitidos';
+$messages['noheadervalue'] = 'Ingrese un valor contra el cual comparar la cabecera';
+$messages['sizewrongformat'] = 'Error: El tamaño del mensaje debe ser numérico';
+$messages['noredirect'] = 'Ingrese una dirección de email a la cual redirigir los mensajes';
+$messages['redirectaddresserror'] = 'Error: Dirección inválida';
+$messages['noreject'] = 'Ingrese el texto a enviar con los mensajes rechazados';
+$messages['vacnodays'] = 'Ingrese el numero de dias para el periodo que el mensaje no será reenviado a la misma persona';
+$messages['vacdayswrongformat'] = 'Error: El periodo debe ser 1 o más dias';
+$messages['vacnomsg'] = 'Ingrese un texto para el mensaje';
+$messages['notifynomethod'] = 'Ingrese el método por el cual se enviará la notificación';
+$messages['notifynomsg'] = 'Ingrese un texto para su mensaje';
+$messages['sieveruleexp'] = 'Debe definir una o más reglas contra las que se comprobarán los mensajes. Los filtros son ejecutados en el orden e nque aparecen a la izquierda de esta pantalla. Si se encuentra una coincidencia los demás filtros no se comprueban.';
+$messages['sieveactexp'] = 'Seleccione una de las opciones que figuran abajo. Esta acción será ejecutada por cada mensaje que concuerden con las reglas que figuran arriba.';
+$messages['sieveheadershlp'] = 'Debajo hay algunos ejemplos de cabeceras que pueden verificarse con filtros. Seleccione una cabecera para agregar a la regla o increse una propia en el cuadro de arriba.';
+$messages['movingfilter'] = 'Moviendo filtro...';
+$messages['noexistingfilters'] = '¡No se detectan filtros!';
+$messages['importdefault'] = '<b>Usar filtros por defecto:</b> Hay un juego de filtros por defecto disponibles. ¿Quiere instalar una copia de esos filtros?';
+$messages['importother'] = '<b>Importar filtros:</b> Se ha encontrado otro juego de filtros de %s. ¿Quiere importarlos a su lista de filtros?';
+$messages['switchtoadveditor'] = 'El editor avanzado le permite editar las reglas de sieve directamente. Cualquier cambio que haga será ilegible para el editor normal de reglas y se parderá si graba modificaciones con el editor normal. ¿Quiere continuar?';
+$messages['filterimported'] = 'Filtro importado correctamente';
+$messages['filterimporterror'] = 'No se pudo importar el filtro. Error en el servidor';
+
+?> \ No newline at end of file
diff --git a/plugins/sieverules/localization/es_ES.inc b/plugins/sieverules/localization/es_ES.inc
new file mode 100644
index 000000000..df9b0f24b
--- /dev/null
+++ b/plugins/sieverules/localization/es_ES.inc
@@ -0,0 +1,185 @@
+<?php
+/* Author: Alejandro Vargas */
+
+$labels = array();
+$labels['filters'] = 'Filtros';
+$labels['managefilters'] = 'Manejo de filtros';
+$labels['filtername'] = 'Nombre del filtro';
+$labels['disablerule'] = 'Desactivar regla';
+$labels['disabled'] = 'Desactivada';
+$labels['newfilter'] = 'Nuevo filtro';
+$labels['moveup'] = 'Mover arriba';
+$labels['movedown'] = 'Mover abajo';
+$labels['filterallof'] = 'concuerda con TODAS las reglas siguientes';
+$labels['filteranyof'] = 'concuerda con ALGUNA de las reglas siguientes';
+$labels['filterany'] = 'todos los mensajes';
+$labels['filtercontains'] = 'contiene';
+$labels['filternotcontains'] = 'no contiene';
+$labels['filteris'] = 'es igual a';
+$labels['filterisnot'] = 'es distinto de';
+$labels['filterexists'] = 'existe';
+$labels['filternotexists'] = 'no existe';
+$labels['filterregex'] = 'concuerda con la expresion regular';
+$labels['filternotregex'] = 'no concuerda con la expresion regular';
+$labels['filterunder'] = 'es menos que';
+$labels['filterover'] = 'es mas que';
+$labels['filterbefore'] = 'es antes que';
+$labels['filterafter'] = 'es después que';
+$labels['filteradvoptions'] = 'mas opciones...';
+$labels['spamtest'] = 'Probabilidad de Spam';
+$labels['operator'] = 'Operador';
+$labels['comparator'] = 'Comparador';
+$labels['isgreaterthan'] = 'es mayor que';
+$labels['isgreaterthanequal'] = 'es mayor o igual que';
+$labels['islessthan'] = 'es menor que';
+$labels['islessthanequal'] = 'es menor o igual que';
+$labels['equals'] = 'es igual a';
+$labels['notequals'] = 'es distinto de';
+$labels['countisgreaterthan'] = 'cantidad es mayor que';
+$labels['countisgreaterthanequal'] = 'cantidad es mayor o igual que';
+$labels['countislessthan'] = 'cantidad es menor que';
+$labels['countislessthanequal'] = 'cantidad es menor o igual que';
+$labels['countequals'] = 'cantidad es igual a';
+$labels['countnotequals'] = 'cantidad es distinto de';
+$labels['valueisgreaterthan'] = 'valor es mayor que';
+$labels['valueisgreaterthanequal'] = 'valor es mayor o igual que';
+$labels['valueislessthan'] = 'valor es menor que';
+$labels['valueislessthanequal'] = 'valor es menor o igual que';
+$labels['valueequals'] = 'valor es igual a';
+$labels['valuenotequals'] = 'valor es distinto de';
+$labels['userpart'] = 'la parte del usuario es igual a';
+$labels['notuserpart'] = 'la parte del usuario es distinta de';
+$labels['detailpart'] = 'la parte del detalle es igual a';
+$labels['notdetailpart'] = 'la parte del detalle es distinta de';
+$labels['domainpart'] = 'la parte del dominio es igual a';
+$labels['notdomainpart'] = 'la parte del dominio es distinta de';
+$labels['teststring'] = 'Iniciando prueba';
+$labels['messagemoveto'] = 'Mover mensaje a';
+$labels['messageredirect'] = 'Redirigir mensaje a';
+$labels['messageimapflags'] = 'Marcar mensaje como';
+$labels['messagereject'] = 'Rechazar con aviso';
+$labels['messagevacation'] = 'Mensaje de vacaciones';
+$labels['messagekeep'] = 'Mantener mensaje';
+$labels['messagediscard'] = 'Descartar mensaje';
+$labels['messagenotify'] = 'Enviar notificacion';
+$labels['messagestop'] = 'Dejar de procesar filtros';
+$labels['messagehelp'] = 'Que es esto?';
+$labels['sieveorigsubj'] = 'Agregar asunto iriginal a la respuesta';
+$labels['sievevachandle'] = 'Manejador';
+$labels['method'] = 'Metodo';
+$labels['options'] = 'Opciones';
+$labels['messagesrules'] = 'Reglas de filtrado';
+$labels['messagesactions'] = 'Acciones del filtro';
+$labels['sieveto'] = 'Alias';
+$labels['sievefrom'] = 'De';
+$labels['flag'] = 'Marca';
+$labels['importancen'] = 'Ninguno';
+$labels['importance1'] = '1';
+$labels['importance2'] = '2';
+$labels['importance3'] = '3';
+$labels['flagread'] = 'Leido';
+$labels['flagdeleted'] = 'Borrado';
+$labels['flaganswered'] = 'Respondido';
+$labels['flagdraft'] = 'Borrador';
+$labels['flagflagged'] = 'Marcado';
+$labels['addsieverule'] = 'Agregar otra regla despues de esta';
+$labels['addsieveact'] = 'Agregar otra accion despues de esta';
+$labels['deletesieverule'] = 'Borrar esta regla';
+$labels['deletesieveact'] = 'Borrar esta accion';
+$labels['envelopefrom'] = 'Remitente en la cabecera';
+$labels['envelopeto'] = 'Destinatario en la cabecera';
+$labels['otherheader'] = 'Otra cabecera';
+$labels['days'] = 'Periodo';
+$labels['message'] = 'Mensaje';
+$labels['sieveruleheaders'] = 'Ver ejemplos de otras cabeceras';
+$labels['examplefilters'] = 'Filtros de ejemplo';
+$labels['importfilters'] = 'Importar filtros';
+$labels['usedefaultfilter'] = 'Usar filtros por defecto';
+$labels['importfilter'] = 'Importar filtro';
+$labels['moreactions'] = 'Más opciones...';
+$labels['adveditor'] = 'Editor avanzado';
+$labels['stdeditor'] = 'Editor estándar';
+$labels['messageredirectcopy'] = 'Envia una copia a ';
+$labels['messagecopyto'] = 'Copiar mensaje a ';
+$labels['body'] = 'Cuerpo';
+$labels['auto'] = 'Auto';
+$labels['raw'] = 'Raw';
+$labels['text'] = 'Texto';
+$labels['other'] = 'Otro';
+$labels['bodycontentpart'] = 'Contenido';
+$labels['notchecked'] = 'no seleccionado';
+$labels['spamlevelisgreaterthanequal'] = 'es mayor o igual que';
+$labels['spamlevelislessthanequal'] = 'es menor o igual que';
+$labels['spamlevelequals'] = 'es igual a';
+$labels['i;ascii-casemap'] = 'no distingue mayúsculas/minúsculas';
+$labels['i;octet'] = 'coincide exactamente';
+$labels['i;ascii-numeric'] = 'coincidencia numérica';
+$labels['selectruleset'] = 'Escojer conjunto de reglas';
+$labels['activeruleset'] = '%s (activo)';
+$labels['activateruleset'] = 'Activar este conjunto de reglas';
+$labels['newruleset'] = 'Crear un nuevo conjunto de reglas.';
+$labels['delruleset'] = 'Borrar este conjunto de reglas';
+$labels['renameruleset'] = 'Renombrar este conjunto de reglas';
+$labels['copy'] = 'Copiar';
+$labels['copyexistingfilter'] = 'Copiar los filtros existentes';
+$labels['copytoruleset'] = 'Copiar filtro a otro conjunto de reglas';
+$labels['copyfromruleset'] = 'Copiar filtros desde un conjunto de reglas existente';
+$labels['time'] = 'Tiempo';
+$labels['weekday'] = 'Día de la semana';
+
+$messages = array();
+$messages['nosieverules'] = 'No se han encontrado filtros.';
+$messages['filterdeleteconfirm'] = '¿Está seguro de que quiere borrar este filtro?';
+$messages['ruledeleteconfirm'] = '¿Está seguro de que quiere borrar esta regla?';
+$messages['actiondeleteconfirm'] = '¿Está seguro de que quiere borrar esta acción?';
+$messages['filterunknownerror'] = 'Error desconocido en el servidor';
+$messages['filterconnerror'] = 'Imposible conectar con el servidor sieve';
+$messages['filterdeleteerror'] = 'No se pudo borrar el filtro. Error del servidor';
+$messages['filterdeleted'] = 'Filtro borrado';
+$messages['filtersaved'] = 'Filtro grabado';
+$messages['filtersaveerror'] = 'Incapaz de grabar filtro. Error en el servidor';
+$messages['vacdaysexp'] = 'El periodo es el numero de dias que el mensaje no será reenviado al mismo usuario, sin importar cuantas veces intente contactar con usted<br /><br />Por ejemplo, si Juan le manda un mensaje, un lunes, y tiene el periodo fijado en 7, Juan recibirá un aviso de vacaciones el lunes pero no recibirá otro hasta el siguiente lunes, sin importar cuántos emails le envíe durente la semana.';
+$messages['vachandleexp'] = 'Se puede usar un manejador para vincular diferentes mensajes de vacaciones todos juntos, una vez se envio un mensaje, no se enviará otro que tenga el mismo manejador durante el periodo definido.';
+$messages['vactoexp'] = 'Lista de destinatarios adicionales que será incluida en la auto respuesta. Si un destinatario no es su dirección principal, y no está en esta lista, no se le enviarán mensajes.';
+$messages['vactoexp_adv'] = 'Separe multiples alias con coma (,). Por ejemplo test1@ejemplo.com,test2@ejemplo.com,test3@ejemplo.com';
+$messages['vactoexp_err'] = 'Error: Los distintos alias deben separarse con coma (,)';
+$messages['norulename'] = 'Debe asignar un nombre al filtro';
+$messages['ruleexists'] = 'Ya hay un filtro con ese nombre. Elija otro';
+$messages['noheader'] = 'Debe ingresar el nombre de la cabecera a verificar';
+$messages['headerbadchars'] = 'Error: La cabecera contiene caracteres no permitidos';
+$messages['noheadervalue'] = 'Ingrese un valor contra el cual comparar la cabecera';
+$messages['sizewrongformat'] = 'Error: El tamaño del mensaje debe ser numérico';
+$messages['noredirect'] = 'Ingrese una dirección de email a la cual redirigir los mensajes';
+$messages['redirectaddresserror'] = 'Error: Dirección inválida';
+$messages['noreject'] = 'Ingrese el texto a enviar con los mensajes rechazados';
+$messages['vacnodays'] = 'Ingrese el numero de dias para el periodo que el mensaje no será reenviado a la misma persona';
+$messages['vacdayswrongformat'] = 'Error: El periodo debe ser 1 o más dias';
+$messages['vacnomsg'] = 'Ingrese un texto para el mensaje';
+$messages['notifynomethod'] = 'Ingrese el método por el cual se enviará la notificación';
+$messages['notifynomsg'] = 'Ingrese un texto para su mensaje';
+$messages['sieveruleexp'] = 'Debe definir una o más reglas contra las que se comprobarán los mensajes. Los filtros son ejecutados en el orden en que aparecen a la izquierda de esta pantalla. Si se encuentra una coincidencia los demás filtros no se comprueban.';
+$messages['sieveruleexp_stop'] = 'Debe definir una o más reglas contra las que se comprobarán los mensajes. Los filtros son ejecutados en el orden en que aparecen a la izquierda de esta pantalla, hasta que una acción \'Stop\' se cumpla.';
+$messages['sieveactexp'] = 'Seleccione una de las opciones que figuran abajo. Esta acción será ejecutada por cada mensaje que concuerden con las reglas que figuran arriba.';
+$messages['sieveheadershlp'] = 'Debajo hay algunos ejemplos de cabeceras que pueden verificarse con filtros. Seleccione una cabecera para agregar a la regla o increse una propia en el cuadro de arriba.';
+$messages['movingfilter'] = 'Moviendo filtro...';
+$messages['noexistingfilters'] = '¡No se detectan filtros!';
+$messages['importdefault'] = '<b>Usar filtros por defecto:</b> Hay un juego de filtros por defecto disponibles. ¿Quiere instalar una copia de esos filtros?';
+$messages['importother'] = '<b>Importar filtros:</b> Se ha encontrado otro juego de filtros de %s. ¿Quiere importarlos a su lista de filtros?';
+$messages['switchtoadveditor'] = 'El editor avanzado le permite editar las reglas de sieve directamente. Cualquier cambio que haga será ilegible para el editor normal de reglas y se parderá si graba modificaciones con el editor normal. ¿Quiere continuar?';
+$messages['filterimported'] = 'Filtro importado correctamente';
+$messages['filterimporterror'] = 'No se pudo importar el filtro. Error en el servidor';
+$messages['notifyinvalidmethod'] = 'El método no parece estar escrito en un formato válido, debe ser una URI. Por ejemplo: "mailto: alert@example.com".';
+$messages['nobodycontentpart'] = 'Por favor, introduzca una parte de contenido para prueba';
+$messages['badoperator'] = 'Lo sentimos, el operador que ha seleccionado no se puede usar en esta regla.';
+$messages['filteractionerror'] = 'La acción requerida no está soportada por el servidor.';
+$messages['filtermissingerror'] = 'No ha sido posible encontrar la regla solicitada.';
+$messages['contentpartexp'] = 'El tipo MIME o una parte específica del mensaje debe ser probado. Por ejemplo: `message/rfc822`, `text/html`, `audio/mp3` or `image`.';
+$messages['delrulesetconf'] = 'Está seguro de querer borrar este conjunto de reglas?';
+$messages['rulesetexists'] = 'Ya existe un conjunto de reglas con ese nombre. Por favor, escoja otro.';
+$messages['copyexisting'] = '<b> Copia el siguiente conjunto de reglas:</b> ¿Quiere importar los filtros de un conjunto de reglas existente al conjunto actual?';
+$messages['filtercopied'] = 'Filtro copiado correctamente';
+$messages['nosieverulesets'] = 'No se han encontrado reglas.';
+$messages['baddateformat'] = 'Error: Por favor, introduzca la fecha en el formato AAAA-MM-DD';
+$messages['badtimeformat'] = 'Error: Por favor, introduzca la hora en el formato HH:MM:SS';
+
+?> \ No newline at end of file
diff --git a/plugins/sieverules/localization/et_EE.inc b/plugins/sieverules/localization/et_EE.inc
new file mode 100644
index 000000000..980097d14
--- /dev/null
+++ b/plugins/sieverules/localization/et_EE.inc
@@ -0,0 +1,79 @@
+<?php
+/* Author: Andi Lõhmus */
+
+$labels = array();
+$labels['filters'] = 'Filtrid';
+$labels['managefilters'] = 'Halda sisenevate kirjade filtreid';
+$labels['filtername'] = 'Filtri nimi';
+$labels['disablerule'] = 'Keela filter';
+$labels['disabled'] = 'Keelatud';
+$labels['newfilter'] = 'Uus filter';
+$labels['moveup'] = 'Liiguta ülesse';
+$labels['movedown'] = 'Liiguta alla';
+$labels['filterallof'] = 'vastab kõikidele järgnevatele reeglitele';
+$labels['filteranyof'] = 'vastab mõnele järgnevatest reeglitest';
+$labels['filterany'] = 'kõik kirjad';
+$labels['filtercontains'] = 'sisaldab';
+$labels['filternotcontains'] = 'ei sisalda';
+$labels['filteris'] = 'on võrdne kui';
+$labels['filterisnot'] = 'ei ole võrdne kui';
+$labels['filterexists'] = 'on olemas';
+$labels['filternotexists'] = 'pole olemas';
+$labels['filterregex'] = 'vastab regulaaravaldisele';
+$labels['filternotregex'] = 'ei vasta regulaaravaldisele';
+$labels['filterunder'] = 'on vähem kui';
+$labels['filterover'] = 'on rohkem kui';
+$labels['filteradvoptions'] = 'rohkem valikuid';
+$labels['spamtest'] = 'Spammi tõenäosus';
+$labels['operator'] = 'Operaator';
+$labels['comparator'] = 'Komparaator';
+$labels['isgreaterthan'] = 'on suurem kui';
+$labels['isgreaterthanequal'] = 'on suurem või samaväärne ';
+$labels['islessthan'] = 'on vähem kui';
+$labels['islessthanequal'] = 'on vähem või võrdne kui';
+$labels['equals'] = 'on võrdne';
+$labels['notequals'] = 'ei ole võrdne';
+$labels['countisgreaterthan'] = 'arv on suurem kui';
+$labels['countisgreaterthanequal'] = 'arv on suurem või võrdne kui';
+$labels['countislessthan'] = 'arv on väiksem kui';
+$labels['countislessthanequal'] = 'arv on väiksem või võrdne kui';
+$labels['countequals'] = 'arv on võrdne';
+$labels['countnotequals'] = 'arv ei ole võrdne';
+$labels['valueisgreaterthan'] = 'väärtus on suurem kui';
+$labels['valueisgreaterthanequal'] = 'väärtus on suurem või võrdne kui';
+$labels['valueislessthan'] = 'väärtus on võiksem kui';
+$labels['valueislessthanequal'] = 'väärtus on väiksem või võrdne kui';
+$labels['valueequals'] = 'väärtus on võrdne';
+$labels['valuenotequals'] = 'väärtus ei ole võrdne';
+$labels['userpart'] = 'kasutajanimi (enne "@" või "+" märki) on võrdne';
+$labels['notuserpart'] = 'kasutajanimi (enne "@" või "+" märki) ei ole võrdne';
+$labels['detailpart'] = 'nime osa peale "+" märki on võrdne';
+$labels['notdetailpart'] = 'nime osa peale "+" märki ei ole võrdne';
+$labels['domainpart'] = 'domeeninimi (peale "@") on võrdne';
+$labels['notdomainpart'] = 'domeeninimi (peale "@") ei ole võrdne';
+$labels['teststring'] = 'Võrdle reaga';
+$labels['messagemoveto'] = 'Liiguta kiri';
+$labels['messageredirect'] = 'Suuna teisele aadressile';
+$labels['messageimapflags'] = 'Märgi kiri';
+$labels['messagereject'] = 'Keeldu';
+$labels['messagevacation'] = 'Saada kontorist väljas teade';
+$labels['messagekeep'] = 'Säilita kiri';
+$labels['messagediscard'] = 'Kustuta kiri ära';
+$labels['messagenotify'] = 'Saada teadaanne';
+$labels['messagestop'] = 'Lõpeta filtrite töö';
+$labels['messagehelp'] = 'Mis see on?';
+$labels['sieveorigsubj'] = 'Lisa originaal vastusele';
+$labels['sievevachandle'] = 'Käsitle';
+$labels['method'] = 'Meetod';
+$labels['options'] = 'Valikud';
+$labels['messagesrules'] = 'Filtri reeglid';
+$labels['messagesactions'] = 'Filtri toimingud';
+$labels['sievefrom'] = 'Saatja';
+$labels['flag'] = 'Tähtsus';
+$labels['importancen'] = 'Mitte ükski';
+$labels['importance1'] = 'Kõrge';
+$labels['importance2'] = 'Normaalne';
+
+$messages = array();
+
+?> \ No newline at end of file
diff --git a/plugins/sieverules/localization/fi_FI.inc b/plugins/sieverules/localization/fi_FI.inc
new file mode 100644
index 000000000..9114f4adc
--- /dev/null
+++ b/plugins/sieverules/localization/fi_FI.inc
@@ -0,0 +1,186 @@
+<?php
+/* Author: Samu Juvonen */
+
+$labels = array();
+$labels['filters'] = 'Suotimet';
+$labels['managefilters'] = 'Hallitse viestisuotimia';
+$labels['filtername'] = 'Suotimen nimi';
+$labels['disablerule'] = 'Poista käytöstä';
+$labels['disabled'] = 'Ei käytössä';
+$labels['newfilter'] = 'Uusi suodin';
+$labels['moveup'] = 'Siirrä ylös';
+$labels['movedown'] = 'Siirrä alas';
+$labels['filterallof'] = 'täsmää kaikkiin sääntöihin';
+$labels['filteranyof'] = 'täsmää johonkin säännöistä';
+$labels['filterany'] = 'kaikki viestit';
+$labels['filtercontains'] = 'Sisältää';
+$labels['filternotcontains'] = 'Ei sisällä';
+$labels['filteris'] = 'Sama kuin';
+$labels['filterisnot'] = 'Ei ole sama kuin';
+$labels['filterexists'] = 'On olemassa';
+$labels['filternotexists'] = 'Ei ole olemassa';
+$labels['filterregex'] = 'Täsmää säännölliseen lausekkeeseen';
+$labels['filternotregex'] = 'Ei täsmää säännölliseen lausekkeeseen';
+$labels['filterunder'] = 'Vähemmän kuin';
+$labels['filterover'] = 'Enemmän kuin';
+$labels['filterbefore'] = 'Ennen';
+$labels['filterafter'] = 'Jälkeen';
+$labels['filteradvoptions'] = 'Lisää vaihtoehtoja...';
+$labels['spamtest'] = 'Spammin todennäköisyys';
+$labels['operator'] = 'Operaattori';
+$labels['comparator'] = 'Vertailu';
+$labels['isgreaterthan'] = 'Suurempi kuin';
+$labels['isgreaterthanequal'] = 'Suurempi tai yhtä suuri kuin';
+$labels['islessthan'] = 'Vähemmän kuin';
+$labels['islessthanequal'] = 'Vähemmän tai yhtä suuri kuin';
+$labels['equals'] = 'Yhtä suuri kuin';
+$labels['notequals'] = 'Ei ole yhtä suuri';
+$labels['countisgreaterthan'] = 'Lukumäärä suurempi';
+$labels['countisgreaterthanequal'] = 'Lukumäärä suurempi tai yhtä suuri';
+$labels['countislessthan'] = 'Lukumäärä pienempi';
+$labels['countislessthanequal'] = 'Lukumäärä pienempi tai yhtä suuri';
+$labels['countequals'] = 'Lukumäärä yhtä suuri';
+$labels['countnotequals'] = 'Lukumäärä erisuuri';
+$labels['valueisgreaterthan'] = 'Arvo suurempi';
+$labels['valueisgreaterthanequal'] = 'Arvo suurempi tai yhtä suuri';
+$labels['valueislessthan'] = 'Arvo pienempi';
+$labels['valueislessthanequal'] = 'Arvo pienempi tai yhtä suuri';
+$labels['valueequals'] = 'Arvo on yhtä suuri';
+$labels['valuenotequals'] = 'Arvo on eri suuri';
+$labels['userpart'] = 'Käyttäjäosa täsmää';
+$labels['notuserpart'] = 'Käyttäjäosa ei täsmää';
+$labels['detailpart'] = 'Lisätiedot täsmäävät';
+$labels['notdetailpart'] = 'Lisätiedot eivät täsmää';
+$labels['domainpart'] = 'Domain täsmää';
+$labels['notdomainpart'] = 'Domain ei täsmää';
+$labels['teststring'] = 'Verrattava arvo';
+$labels['messagemoveto'] = 'Siirrä viesti kansioon';
+$labels['messageredirect'] = 'Uudelleenohjaa osoitteeseen';
+$labels['messageimapflags'] = 'Vaihda viestin tila';
+$labels['messagereject'] = 'Hylkää viestillä';
+$labels['messagevacation'] = 'Poissaoloviesti';
+$labels['messagekeep'] = 'Säilytä viesti';
+$labels['messagediscard'] = 'Hylkää viesti';
+$labels['messagenotify'] = 'Lähetä ilmoitus';
+$labels['messagestop'] = 'Keskeytä suotimien suoritus';
+$labels['messagehelp'] = 'Mikä tämä on?';
+$labels['sieveorigsubj'] = 'Lisää alkuperäinen otsikko vastauksen loppuun';
+$labels['sievevachandle'] = 'Handle';
+$labels['method'] = 'Method';
+$labels['options'] = 'Asetukset';
+$labels['messagesrules'] = 'Suotimen säännöt';
+$labels['messagesactions'] = 'Suotimen toiminnot';
+$labels['sieveto'] = 'Aliakset';
+$labels['sievefrom'] = 'Lähettäjä';
+$labels['flag'] = 'Tärkeys';
+$labels['importancen'] = 'Ei mitään';
+$labels['importance1'] = 'Korkea';
+$labels['importance2'] = 'Tavallinen';
+$labels['importance3'] = 'Alhainen';
+$labels['flagread'] = 'Luettu';
+$labels['flagdeleted'] = 'Poistettu';
+$labels['flaganswered'] = 'Vastattu';
+$labels['flagdraft'] = 'Luonnos';
+$labels['flagflagged'] = 'Merkitty';
+$labels['addsieverule'] = 'Lisää uusi sääntö alle';
+$labels['addsieveact'] = 'Lisää uusi toiminto alle';
+$labels['deletesieverule'] = 'Poista sääntö';
+$labels['deletesieveact'] = 'Poista toiminto';
+$labels['envelopefrom'] = 'Lähettäjä (envelope)';
+$labels['envelopeto'] = 'Vastaanottaja (envelope)';
+$labels['otherheader'] = 'Muu otsikkotieto';
+$labels['days'] = 'Aikaväli';
+$labels['message'] = 'Viesti';
+$labels['sieveruleheaders'] = 'Katso esimerkkejä muista otsikkotiedoista';
+$labels['examplefilters'] = 'Esimerkkejä';
+$labels['importfilters'] = 'Tuo suotimet';
+$labels['usedefaultfilter'] = 'Käytä oletussuotimia';
+$labels['importfilter'] = 'Tuo suotimet';
+$labels['moreactions'] = 'Lisää asetuksia...';
+$labels['adveditor'] = 'Laajennettu editori';
+$labels['stdeditor'] = 'Tavallinen editori';
+$labels['messageredirectcopy'] = 'Lähetä kopio osoitteeseen';
+$labels['messagecopyto'] = 'Kopioi viesti kansioon';
+$labels['body'] = 'Viesti';
+$labels['auto'] = 'Auto';
+$labels['raw'] = 'Raaka';
+$labels['text'] = 'Teksti';
+$labels['other'] = 'Muu';
+$labels['bodycontentpart'] = 'Sisältöosa';
+$labels['spamnotchecked'] = 'Ei tarkistettu';
+$labels['spamlevelisgreaterthanequal'] = 'Korkeampi tai yhtä korkea kuin';
+$labels['spamlevelislessthanequal'] = 'Matalampi tai yhtä korkea kuin';
+$labels['spamlevelequals'] = 'Yhtä korkea';
+$labels['i;ascii-casemap'] = 'Kirjainkoosta riippumaton merkkijonovertailu';
+$labels['i;octet'] = 'Täydellinen merkkijonon vastaavuus';
+$labels['i;ascii-numeric'] = 'Numeerinen vastaavuus';
+$labels['selectruleset'] = 'Valitse säännöstö';
+$labels['activeruleset'] = '%s (aktiivinen)';
+$labels['activateruleset'] = 'Ota säännöstö käyttöön';
+$labels['newruleset'] = 'Luo uusi säännöstö';
+$labels['delruleset'] = 'Poista säännöstö';
+$labels['renameruleset'] = 'Nimeä säännöstö uudelleen';
+$labels['copy'] = 'Kopioi';
+$labels['copyexistingfilter'] = 'Kopioi nykyiset suotimet';
+$labels['copytoruleset'] = 'Kopioi suodin uuteen säännöstöön';
+$labels['copyfromruleset'] = 'Kopioi suotimia vanhasta säännöstöstä';
+$labels['time'] = 'Aika';
+$labels['weekday'] = 'Viikonpäivä';
+
+$messages = array();
+$messages['nosieverules'] = 'Suotimia ei löytynyt.';
+$messages['filterdeleteconfirm'] = 'Haluatko varmasti poistaa tämän suotimen?';
+$messages['ruledeleteconfirm'] = 'Haluatko varmasti poistaa tämän säännön?';
+$messages['actiondeleteconfirm'] = 'Haluatko varmasti poistaa tämän toiminnon?';
+$messages['filterunknownerror'] = 'Tuntematon palvelinvirhe';
+$messages['filterconnerror'] = 'Unable to connect to sieve server';
+$messages['filterdeleteerror'] = 'Palvelinvirhe. Suodinta ei poistettu.';
+$messages['filterdeleted'] = 'Suodin poistettu onnistuneesti';
+$messages['filtersaved'] = 'Suodin tallennettu onnistuneesti';
+$messages['filtersaveerror'] = 'Palvelinvirhe. Suodinta ei tallennettu.';
+$messages['vacdaysexp'] = 'Aikaväli on päivien määrä, jona aikana viestiä ei lähetetä samalle käyttäjälle välittämättä siitä, kuinka usein he ottavat sinuun yhteyttä.<br/><br/>Esimerkki: Jaakko lähettää sinulle sähköpostia maanantaina ja aikaväliksi on valittu 7 päivää. Jaakko saa poissaoloviestisi maanantaina, mutta jos hän lähettää sinulle samalla viikolla lisää viestejä, uutta ilmoitusta ei lähetetä ennen seuraavaa maanantaita.';
+$messages['vachandleexp'] = 'Ryhmittelyä voidaan käyttää yhdistämään eri poissaoloviestit toisiinsa. Kun yksi viesti on lähetetty, muita saman ryhmittelyn viestejä ei lähetetä kyseisen aikavälin aikana.';
+$messages['vactoexp'] = 'Lista muista vastaanottajien sähköpostiosoitteista, jotka liitetään automaattivastaukseen. Mikäli viestin vastaanottaja ei ole pääosoitteesi eikä löydy tältä listalta, mitään viestiä ei lähetetä.';
+$messages['vactoexp_adv'] = 'Erottele aliakset pilkulla (,). Esimerkki: testi1@esimerkki.fi,testi2@esimerkki.fi,testi3@esimerkki.fi';
+$messages['vactoexp_err'] = 'Virhe: aliakset tulee erotella pilkulla (,)';
+$messages['norulename'] = 'Anna suotimelle nimi';
+$messages['ruleexists'] = 'Tällä nimellä on jo suodin. Anna uusi nimi';
+$messages['noheader'] = 'Anna testattavan otsikkotiedon nimi';
+$messages['headerbadchars'] = 'Virhe: otsikkotiedossa on kiellettyjä merkkejä';
+$messages['noheadervalue'] = 'Anna arvo, jolla otsikkotietoa testataan';
+$messages['sizewrongformat'] = 'Virhe: viestin koon täytyy olla numeerinen';
+$messages['noredirect'] = 'Anna osoite, johon viestit ohjataan';
+$messages['redirectaddresserror'] = 'Virhe: osoite ei ole kelvollinen';
+$messages['noreject'] = 'Anna viesti, joka liitetään hylättyyn sähköpostiin';
+$messages['vacnodays'] = 'Ilmoita aikaväli (päivien määrä), jona samalle henkilölle ei lähetetä uutta viestiä.';
+$messages['vacdayswrongformat'] = 'Virhe: aikavälin täytyy olla suurempi tai yhtä suuri luku kuin 1';
+$messages['vacnomsg'] = 'Kirjoita viestiisi jotain sisältöä';
+$messages['notifynomethod'] = 'Määrittele metodi, jota käyttäen ilmoitus lähetetään.';
+$messages['notifynomsg'] = 'Kirjoita viestiisi jotain sisältöä';
+$messages['sieveruleexp'] = 'Määrittele yksi tai useampia sääntöjä, joihin jokaista viestiä testataan. Suotimet suoritetaan siinä järjestyksessä, jossa ne esiintyvät vasemmalla olevalla listalla. Kun jokin suotimista täsmää, loppuja suotimia ei suoriteta.';
+$messages['sieveruleexp_stop'] = 'Määrittele yksi tai useampia sääntöjä, joihin jokaista viestiä testataan. Suotimet suoritetaan siinä järjestyksessä, jossa ne esiintyvät vasemmalla olevalla listalla, kunnes keskeytyssääntö tavataan.';
+$messages['sieveactexp'] = 'Valitse jokin alla olevista vaihtoehdoista. Toiminnot suoritetaan kaikille viesteille, jotka täsmäävät yllä oleviin sääntöihin.';
+$messages['sieveheadershlp'] = 'Alla on esimerkkejä otsikkotiedoista, joita voidaan testata suotimilla. Valitse jokin otsikkotieto listasta tai määrittele muu otsikkotieto yllä olevaan kenttään.';
+$messages['movingfilter'] = 'Siirretään suodinta...';
+$messages['noexistingfilters'] = 'Suotimia ei löytynyt!';
+$messages['importdefault'] = '<b>Käytä oletussuotimia:</b> Suotimia on saatavilla. Haluatko käyttää näitä suotimia?';
+$messages['importother'] = '<b>Tuo suotimia:</b> Suotimia löydettiin palvelusta %s. Haluatko lisätä nämä suotimet nykyisiin suotimiin?';
+$messages['switchtoadveditor'] = 'Laajennetulla editorilla voit muokata seulatiedostoa suoraan. Tehdyt muutokset eivät välttämättä ole luettavissa tavallisessa editorissa ja saattavat hävitä, jos suotimia muokataan tavallisella editorilla. Haluatko jatkaa?';
+$messages['filterimported'] = 'Suodin lisätty onnistuneesti';
+$messages['filterimporterror'] = 'Palvelinvirhe. Suotimia ei lisätty';
+$messages['notifyinvalidmethod'] = 'Metodi ei ole kelvollisessa muodossa. Sen täytyy olla osoite. Esimerkki: mailto:virhe@esimerkki.fi';
+$messages['nobodycontentpart'] = 'Anna testattava sisältöosa';
+$messages['badoperator'] = 'Valitsemaasi operaattoria ei voida käyttää tässä säännössä';
+$messages['filteractionerror'] = 'Palvelin ei tue valitsemaasi toimintoa';
+$messages['filtermissingerror'] = 'Valittua sääntöä ei löytynyt';
+$messages['contentpartexp'] = 'MIME-tyyppi tai tietty viestin osa, jota testataan. Esimerkki: "message/rfc822", "text/html", "audio/mp3" tai "image"';
+$messages['delrulesetconf'] = 'Haluatko varmasti poistaa tämän säännöstön?';
+$messages['rulesetexists'] = 'Tällä nimellä on jo säännöstö. Anna uusi nimi';
+$messages['copyexisting'] = '<b>Kopioi säännöstö:</b> Haluatko kopioida toisen säännöstön nykyisiin sääntöihisi?';
+$messages['filtercopied'] = 'Suodin kopioitu onnistuneesti';
+$messages['nosieverulesets'] = 'Säännöstöä ei löytynyt.';
+$messages['baddateformat'] = 'Virhe: anna päivämäärä muodossa VVVV-KK-PP';
+$messages['badtimeformat'] = 'Virhe: anna aika muodossa TT:MM:SS';
+$messages['missingfoldername'] = 'Virhe: anna kansiolle nimi';
+
+?> \ No newline at end of file
diff --git a/plugins/sieverules/localization/fr_FR.inc b/plugins/sieverules/localization/fr_FR.inc
new file mode 100644
index 000000000..fb9f6d430
--- /dev/null
+++ b/plugins/sieverules/localization/fr_FR.inc
@@ -0,0 +1,185 @@
+<?php
+/* Author: Aymeric Peuch */
+
+$labels = array();
+$labels['filters'] = 'Filtres';
+$labels['managefilters'] = 'Gestion des filtres sur les mails entrants';
+$labels['filtername'] = 'Nom du filtre';
+$labels['disablerule'] = 'Désactiver le filtre';
+$labels['disabled'] = 'Désactivé';
+$labels['newfilter'] = 'Nouveau filtre';
+$labels['moveup'] = 'Monter';
+$labels['movedown'] = 'Descendre';
+$labels['filterallof'] = 'valident toutes les conditions suivantes';
+$labels['filteranyof'] = 'valident au moins une des conditions suivantes';
+$labels['filterany'] = 'tous les messages';
+$labels['filtercontains'] = 'contient';
+$labels['filternotcontains'] = 'ne contient pas';
+$labels['filteris'] = 'est';
+$labels['filterisnot'] = 'n\'est pas';
+$labels['filterexists'] = 'existe';
+$labels['filternotexists'] = 'n\'existe pas';
+$labels['filterregex'] = 'valide l\'expression régulière';
+$labels['filternotregex'] = 'ne valide pas l\'expression régulière';
+$labels['filterunder'] = 'est inférieur à';
+$labels['filterover'] = 'est supérieur à';
+$labels['filterbefore'] = 'antérieur(e) à';
+$labels['filterafter'] = 'postérieur(e) à';
+$labels['filteradvoptions'] = 'plus d\'options...';
+$labels['spamtest'] = 'Probabilité de spam';
+$labels['operator'] = 'Opérateur';
+$labels['comparator'] = 'Comparateur';
+$labels['isgreaterthan'] = 'plus grande que';
+$labels['isgreaterthanequal'] = 'plus grande ou égale à';
+$labels['islessthan'] = 'plus petite que';
+$labels['islessthanequal'] = 'plus petite ou égale à';
+$labels['equals'] = 'est égale à';
+$labels['notequals'] = 'n\'est pas égale à';
+$labels['countisgreaterthan'] = 'longueur plus grande que';
+$labels['countisgreaterthanequal'] = 'longueur plus grande ou égale à';
+$labels['countislessthan'] = 'longueur plus petite que';
+$labels['countislessthanequal'] = 'longueur plus petite ou égale à';
+$labels['countequals'] = 'longueur est égale à';
+$labels['countnotequals'] = 'longueur n\'est pas égale à';
+$labels['valueisgreaterthan'] = 'valeur plus grande que';
+$labels['valueisgreaterthanequal'] = 'valeur plus grande ou égale à';
+$labels['valueislessthan'] = 'valeur plus petite que';
+$labels['valueislessthanequal'] = 'valeur plus petite ou égale à';
+$labels['valueequals'] = 'valeur est égale à';
+$labels['valuenotequals'] = 'valeur n\'est pas égale à';
+$labels['userpart'] = 'partie utilisateur égale à';
+$labels['notuserpart'] = 'partie utilisateur n\'est pas égale à';
+$labels['detailpart'] = 'partie détaillée égale à';
+$labels['notdetailpart'] = 'partie détaillée n\'est pas égale à';
+$labels['domainpart'] = 'partie domaine égale à';
+$labels['notdomainpart'] = 'partie domaine n\'est pas égale à';
+$labels['teststring'] = 'Chaîne de test';
+$labels['messagemoveto'] = 'Déplacer le message vers';
+$labels['messageredirect'] = 'Rediriger le message à';
+$labels['messageimapflags'] = 'Marquer le message comme';
+$labels['messagereject'] = 'Rejeter le message';
+$labels['messagevacation'] = 'Message d\'absence';
+$labels['messagekeep'] = 'Garder le message';
+$labels['messagediscard'] = 'Refuser le message';
+$labels['messagenotify'] = 'Envoyer la notification';
+$labels['messagestop'] = 'Arrêter les filtres en cours';
+$labels['messagehelp'] = 'Qu\'est-ce que c\'est ?';
+$labels['sieveorigsubj'] = 'Ajouter le sujet original à la réponse';
+$labels['sievevachandle'] = 'Traiter';
+$labels['method'] = 'Méthode';
+$labels['options'] = 'Options';
+$labels['messagesrules'] = 'Règles du filtre';
+$labels['messagesactions'] = 'Actions du filtre';
+$labels['sieveto'] = 'Alias';
+$labels['sievefrom'] = 'De';
+$labels['flag'] = 'Importance';
+$labels['importancen'] = 'Aucune';
+$labels['importance1'] = 'Haute';
+$labels['importance2'] = 'Normale';
+$labels['importance3'] = 'Basse';
+$labels['flagread'] = 'Lu';
+$labels['flagdeleted'] = 'Supprimé';
+$labels['flaganswered'] = 'Répondu';
+$labels['flagdraft'] = 'Brouillon';
+$labels['flagflagged'] = 'Suivi';
+$labels['addsieverule'] = 'Ajouter une autre règle en dessous de celle-ci';
+$labels['addsieveact'] = 'Ajouter une autre action en dessous de celle-ci';
+$labels['deletesieverule'] = 'Effacer cette règle';
+$labels['deletesieveact'] = 'Effacer cette action';
+$labels['envelopefrom'] = 'Enveloppe De';
+$labels['envelopeto'] = 'Enveloppe Pour';
+$labels['otherheader'] = 'Autre entête';
+$labels['days'] = 'Période';
+$labels['message'] = 'Message';
+$labels['sieveruleheaders'] = 'Voir des exemples d\'autres entêtes';
+$labels['examplefilters'] = 'Exemple de filtres';
+$labels['importfilters'] = 'Importer des filtres';
+$labels['usedefaultfilter'] = 'Utiliser les filtres par défaut';
+$labels['importfilter'] = 'Importer des filtres';
+$labels['moreactions'] = 'Plus d\'options';
+$labels['adveditor'] = 'Editeur avancé';
+$labels['stdeditor'] = 'Editeur par défaut';
+$labels['messageredirectcopy'] = 'Envoyé une copie à';
+$labels['messagecopyto'] = 'Copier le message vers';
+$labels['body'] = 'Corps';
+$labels['auto'] = 'Auto';
+$labels['raw'] = 'Brut';
+$labels['text'] = 'Texte';
+$labels['other'] = 'Autre';
+$labels['bodycontentpart'] = 'Contenu';
+$labels['notchecked'] = 'non coché';
+$labels['spamlevelisgreaterthanequal'] = 'plus grande ou égale à';
+$labels['spamlevelislessthanequal'] = 'plus petite ou égale à';
+$labels['spamlevelequals'] = 'est égale à';
+$labels['i;ascii-casemap'] = 'insensible à la casse';
+$labels['i;octet'] = 'correspondance exacte';
+$labels['i;ascii-numeric'] = 'correspondance numérique';
+$labels['selectruleset'] = 'Sélectionner un groupe de règles';
+$labels['activeruleset'] = '%s (actif)';
+$labels['activateruleset'] = 'Activer ce groupe de règles';
+$labels['newruleset'] = 'Créer un nouveau groupe de règles';
+$labels['delruleset'] = 'Effacer ce groupe de règles';
+$labels['renameruleset'] = 'Renomer ce groupe de règles';
+$labels['copy'] = 'Copier';
+$labels['copyexistingfilter'] = 'Copier les filtres éxistants';
+$labels['copytoruleset'] = 'Copier le filtre dans un autre groupe de règles';
+$labels['copyfromruleset'] = 'Copier des filtres depuis un autre groupe de règles';
+$labels['time'] = 'Heure';
+$labels['weekday'] = 'Jour de la semaine';
+
+$messages = array();
+$messages['nosieverules'] = 'Aucun filtre trouvé.';
+$messages['filterdeleteconfirm'] = 'Etes-vous sûr de vouloir effacer ce filtre ?';
+$messages['ruledeleteconfirm'] = 'Etes-vous sûr de vouloir effacer cette règle ?';
+$messages['actiondeleteconfirm'] = 'Etes-vous sûr de vouloir effacer cette action ?';
+$messages['filterunknownerror'] = 'Erreur serveur inconnue';
+$messages['filterconnerror'] = 'Impossible de se connecter au serveur sieve';
+$messages['filterdeleteerror'] = 'Impossible de supprimer le filtre. Une erreur serveur a eu lieu';
+$messages['filterdeleted'] = 'Suppression du filtre effectuée.';
+$messages['filtersaved'] = 'Sauvegarde du filtre effectuée.';
+$messages['filtersaveerror'] = 'Impossible d\'enregistrer le filtre. Une erreur serveur a eu lieu';
+$messages['vacdaysexp'] = 'La période est le nombre de jours pendant lesquels le message ne sera pas renvoyé à l\'utilisateur, peu importe le nombre de fois où il vous contacte. <br /> <br /> Par exemple: Si Joe vous contacte le lundi et la période est définie à 7, alors Joe va recevoir un message d\'absence du bureau le lundi, mais n\'en aura pas de nouveaux avant le lundi suivant, peu importe le nombre d\'emails qu\'il envoie au cours de la semaine.';
+$messages['vachandleexp'] = 'Un traitement peut être utilisé pour lier différents messages d\'absence ensemble ; une fois qu\'un message a été envoyé, aucun autre message autre avec le même traitement sera renvoyé durant la période.';
+$messages['vactoexp'] = 'Liste de destinataires supplémentaires qui sont inclus dans l\'auto réponse. Si le destinataire de l\'email n\'est pas votre adresse principale et qu\'elle n\'est pas dans la liste, aucun message ne sera envoyé.';
+$messages['vactoexp_adv'] = 'Séparez plusieurs adresses avec une virgule (,). Par exemple: test1@example.com,test2@example.com,test3@example.com';
+$messages['vactoexp_err'] = 'Erreur: Plusieurs adresses doivent être séparées par une virgule (,)';
+$messages['norulename'] = 'Veuillez entrer un nom pour le filtre';
+$messages['ruleexists'] = 'Un filtre avec le même nom existe déjà. Veuillez en choisir un autre';
+$messages['noheader'] = 'Veuillez entrer le nom de l\'entête à tester';
+$messages['headerbadchars'] = 'Erreur : L\'entête contient des caractères interdits.';
+$messages['noheadervalue'] = 'Veuillez entrer une valeur à tester pour l\'entête';
+$messages['sizewrongformat'] = 'Erreur : La taile du message doit être un nombre';
+$messages['noredirect'] = 'Veuillez entrer une adresse email pour la redirection du message';
+$messages['redirectaddresserror'] = 'Erreur : L\'adresse email semble invalide';
+$messages['noreject'] = 'Veuillez entrer un message à envoyer pour les emails rejetés';
+$messages['vacnodays'] = 'Veuillez entrer un nombre de jours pour la période durant laquelle le message ne sera pas renvoyé à la même personne.';
+$messages['vacdayswrongformat'] = 'Erreur : La période doit être un nombre supérieir à 1';
+$messages['vacnomsg'] = 'Veuillez entrer du texte pour votre message';
+$messages['notifynomethod'] = 'Veuillez entrer la méthode par laquellela notification doit être envoyé';
+$messages['notifynomsg'] = 'veuillez entrer du texte pour votre message';
+$messages['sieveruleexp'] = 'Veuillez définir une ou plusieurs règles pour le filtre. Les filtres sont exécutés dans l\'ordre dans lequel ils apparaissent sur la gauche de l\'écran. Si un filtre est exécuté, plus aucun autre filtre ne sera testé.';
+$messages['sieveruleexp_stop'] = 'Veuillez définir une ou plusieurs règles pour le filtre. Les filtres sont exécutés dans l\'ordre dans lequel ils apparaissent sur la gauche de l\'écran, et ce, jusqu\'à ce qu\'une action d\'arrêt des filtres soit exécutée.';
+$messages['sieveactexp'] = 'Veuillez définir une ou plusieurs actions ci-dessous. Ces actions seront exécutés pour chaque message qui correspondra au règles ci-dessus.';
+$messages['sieveheadershlp'] = 'Voici ci-dessous une liste d\'exemple d\'entête que vous pouvez utilisez dans votre règle. Sélectionnez-en une pour l\'ajouter à la règle ou entrez-en une manuellement dans le champs texte ci-dessous.';
+$messages['movingfilter'] = 'Déplacement du filtre...';
+$messages['noexistingfilters'] = 'Aucun filtre détecté!';
+$messages['importdefault'] = '<b>Utiliser les filtres par défaut : </b>Il y a des filtres disponibles. Voulez-vous utiliser ces filtres ?';
+$messages['importother'] = '<b>Importer des filtres : </b>Un autre set de filtres de %s a été trouvé. Voulez-vous importer ces filtres dans votre profil ?';
+$messages['switchtoadveditor'] = 'Changer pour l\'éditeur avancé vous permet de modifier le fichier sieve directement. Tout changement ici peut le rendre illisible pour l\'édteur normal et peut être perdu quand les filtres sont enregistré avec l\'édteur normal. Voulez-vous continuer ?';
+$messages['filterimported'] = 'Importation des filtres effectuée.';
+$messages['filterimporterror'] = 'Impossible d\'importer les filtres. Une erreur serveur a eu lieu';
+$messages['notifyinvalidmethod'] = 'La méthode ne semble pas être écrite dans un format valide, elle doit être une URI. Par exemple : \'mailto:alert@exemple.com\'';
+$messages['nobodycontentpart'] = 'Veuillez entrer un contenu à tester';
+$messages['badoperator'] = 'Désolé, l\'opérateur que vous avez sélectionner ne peut pas être utilisé pour cette règle';
+$messages['filteractionerror'] = 'L\'action demandée n\'est pas supportée par le serveur';
+$messages['filtermissingerror'] = 'Impossible de trouver la règle demandée';
+$messages['contentpartexp'] = 'Le MIME-type our la partie spécifique du message qui doit être testé. Par exemple : `message/rfc822`, `text/html`, `audio/mp3` ou `image`.';
+$messages['delrulesetconf'] = 'Êtes vous sûr de vouloir effacer ce groupe de règles ?';
+$messages['rulesetexists'] = 'Un groupe de règles porte déjà ce nom. Veuillez en choisir un autre.';
+$messages['copyexisting'] = '<b>Copie d\'un groupe de règles éxistant :</b> Voulez vous copier les filtres d\'un groupe de règles éxistant dans le groupe courant ?';
+$messages['filtercopied'] = 'Filtre copié avec succès';
+$messages['nosieverulesets'] = 'Aucun groupe de règles trouvé.';
+$messages['baddateformat'] = 'Erreur: Veuillez entrer une date sous la forme AAAA-MM-JJ';
+$messages['badtimeformat'] = 'Erreur: Veuillez entrer une heure sous la forme HH:MM:SS';
+
+?> \ No newline at end of file
diff --git a/plugins/sieverules/localization/hu_HU.inc b/plugins/sieverules/localization/hu_HU.inc
new file mode 100644
index 000000000..21addfbcf
--- /dev/null
+++ b/plugins/sieverules/localization/hu_HU.inc
@@ -0,0 +1,171 @@
+<?php
+/* Author: Tamas P */
+
+$labels = array();
+$labels['filters'] = 'Szűrők';
+$labels['managefilters'] = 'Szűrők kezelése';
+$labels['filtername'] = 'Szűrő neve';
+$labels['disablerule'] = 'Szabály kikapcsolása';
+$labels['disabled'] = 'Kikapcsolva';
+$labels['newfilter'] = 'Új szűrő';
+$labels['moveup'] = 'Fennebb';
+$labels['movedown'] = 'Lennebb';
+$labels['filterallof'] = 'illeszkedik az összes következő szabályra';
+$labels['filteranyof'] = 'illeszkedik valamely szabályra';
+$labels['filterany'] = 'összes üzenet';
+$labels['filtercontains'] = 'tartalmazza';
+$labels['filternotcontains'] = 'nem tartalmazza';
+$labels['filteris'] = 'egyenlő';
+$labels['filterisnot'] = 'nem egyenlő';
+$labels['filterexists'] = 'létezik';
+$labels['filternotexists'] = 'nem létezik';
+$labels['filterregex'] = 'illeszkedik reguláris kifejezésre';
+$labels['filternotregex'] = 'nem illeszkedik reguláris kifejezésre';
+$labels['filterunder'] = 'kevesebb mint';
+$labels['filterover'] = 'több mint';
+$labels['filteradvoptions'] = 'több beállítás...';
+$labels['spamtest'] = 'Spam valószínűség';
+$labels['operator'] = 'számítás';
+$labels['comparator'] = 'Összehasonlító';
+$labels['isgreaterthan'] = 'nagyobb mint';
+$labels['isgreaterthanequal'] = 'nagyobb vagy egyenlő';
+$labels['islessthan'] = 'kissebb mint';
+$labels['islessthanequal'] = 'kissebb vagy egyenlő';
+$labels['equals'] = 'egyenlő';
+$labels['notequals'] = 'nem egyenlő';
+$labels['countisgreaterthan'] = 'számítás nagyobb mint';
+$labels['countisgreaterthanequal'] = 'számítás nagyobb vagy egyenlő';
+$labels['countislessthan'] = 'számítás kissebb mint';
+$labels['countislessthanequal'] = 'számítás kissebb vagy egyenlő';
+$labels['countequals'] = 'számítás egyenlő';
+$labels['countnotequals'] = 'számítás nem egyenlő';
+$labels['valueisgreaterthan'] = 'érték nagyobb mint';
+$labels['valueisgreaterthanequal'] = 'érték nagyobb vagy egyenlő';
+$labels['valueislessthan'] = 'érték kissebb mint';
+$labels['valueislessthanequal'] = 'érték kissebb vagy egyenlő';
+$labels['valueequals'] = 'érték egyenlő';
+$labels['valuenotequals'] = 'érték nem egyenlő';
+$labels['userpart'] = 'felhasználó része egyenlő';
+$labels['notuserpart'] = 'felhasználó része nem egyenlő';
+$labels['detailpart'] = 'részlet része egyenlő';
+$labels['notdetailpart'] = 'részlet része nem egyenlő';
+$labels['domainpart'] = 'domain része egyenlő';
+$labels['notdomainpart'] = 'domain része nem egyenlő';
+$labels['teststring'] = 'Teszt szöveg';
+$labels['messagemoveto'] = 'Üzenet áthelyezése';
+$labels['messageredirect'] = 'Üzenet átirányítása';
+$labels['messageimapflags'] = 'Megjelőlés mint';
+$labels['messagereject'] = 'Elutasítás, üzenettel';
+$labels['messagevacation'] = 'Irodán kivűl üzenet';
+$labels['messagekeep'] = 'Megtartás';
+$labels['messagediscard'] = 'Üzenet eldobása';
+$labels['messagenotify'] = 'Értesítés küldése';
+$labels['messagestop'] = 'Szűrők feldolgozásának leállítása';
+$labels['messagehelp'] = 'Mi ez?';
+$labels['sieveorigsubj'] = 'Az eredeti tárgy hozzáfűzése a válaszhoz';
+$labels['sievevachandle'] = 'Kezel';
+$labels['method'] = 'Módszer';
+$labels['options'] = 'Feltételek';
+$labels['messagesrules'] = 'Szűrő szabályok';
+$labels['messagesactions'] = 'Szűrő akció';
+$labels['sieveto'] = 'Aliaszok';
+$labels['sievefrom'] = 'Feladó';
+$labels['flag'] = 'Jelőlés';
+$labels['importancen'] = 'Egyik sem';
+$labels['importance1'] = '1';
+$labels['importance2'] = '2';
+$labels['importance3'] = '3';
+$labels['flagread'] = 'Olvasott';
+$labels['flagdeleted'] = 'Törölt';
+$labels['flaganswered'] = 'Megválaszolt';
+$labels['flagdraft'] = 'Piszkozat';
+$labels['flagflagged'] = 'Megjelőlve';
+$labels['addsieverule'] = 'Új szabály hozzáadása, ez alá';
+$labels['addsieveact'] = 'Új akció hozzáadása, ez alá';
+$labels['deletesieverule'] = 'Szabály törlése';
+$labels['deletesieveact'] = 'Akció törlése';
+$labels['envelopefrom'] = 'Boríték, Küldő';
+$labels['envelopeto'] = 'Boríték, Cimzett';
+$labels['otherheader'] = 'Más fejléc';
+$labels['days'] = 'Időszak';
+$labels['message'] = 'Üzenet';
+$labels['sieveruleheaders'] = 'Fejléc minták megtekintése';
+$labels['examplefilters'] = 'Szűrő minták';
+$labels['importfilters'] = 'Szűrők importálása';
+$labels['usedefaultfilter'] = 'Alapértelmezett szűrők használata';
+$labels['importfilter'] = 'Szűrők importálása';
+$labels['moreactions'] = 'Tobábbi opciók...';
+$labels['adveditor'] = 'Haladó szerkesztő';
+$labels['stdeditor'] = 'Egyszerű szerkesztő';
+$labels['messageredirectcopy'] = 'Másolat küldése';
+$labels['auto'] = 'Auto';
+$labels['text'] = 'Szöveg';
+$labels['other'] = 'Egyéb';
+$labels['spamlevelisgreaterthanequal'] = 'nagyobb vagy egyenlő';
+$labels['spamlevelislessthanequal'] = 'kissebb vagy egyenlő';
+$labels['spamlevelequals'] = 'egyenlő';
+$labels['i;ascii-casemap'] = 'kis/nagybetű nem számít';
+$labels['i;octet'] = 'pontos egyezés';
+$labels['selectruleset'] = 'Szabálycsoport kiválasztása';
+$labels['activateruleset'] = 'Szabálycsoport aktiválása';
+$labels['newruleset'] = 'Új szabálycsoport létrehozása';
+$labels['delruleset'] = 'Szabálycsoport törlése';
+$labels['renameruleset'] = 'Szabálycsoport átnevezése';
+$labels['copy'] = 'Másol';
+$labels['copyexistingfilter'] = 'Létező szűrők másolása';
+$labels['copytoruleset'] = 'Szűrő másolása másik szabálycsoportba';
+$labels['copyfromruleset'] = 'Szűrő(k) másolása másik szabálycsoportból';
+$labels['time'] = 'Idő';
+$labels['weekday'] = 'Hétköznap';
+
+$messages = array();
+$messages['nosieverules'] = 'Nem található szűrő';
+$messages['filterdeleteconfirm'] = 'Biztosan törölni akarod ezt a szűrőt?';
+$messages['ruledeleteconfirm'] = 'Biztosan törölni akarod ezt a szabályt?';
+$messages['actiondeleteconfirm'] = 'Biztosan törölni akarod ezt az akciót?';
+$messages['filterunknownerror'] = 'Ismeretlen szerverhiba';
+$messages['filterconnerror'] = 'Nem sikerült kapcsolódni a sieve szerverhez';
+$messages['filterdeleteerror'] = 'Nem lehet törölni a szűrőt. Szerver hiba';
+$messages['filterdeleted'] = 'A szűrő sikeresen törölve';
+$messages['filtersaved'] = 'Szűrő elmentve';
+$messages['filtersaveerror'] = 'Nem sikerült elmenteni a szűrőt. Szerver hiba';
+$messages['vacdaysexp'] = 'Az dőszak, azon napok száma míg egy üzenet nem lesz újraküldve ugyanannak a címzettnek, függetlenül attól hányszolt lépett önnel kapcsolatba.<br /><br />Pédául: Ha János üzenetet küld Hétfőn és az időszak 7, válaszul kap egy Irodán kívül üzenetet ami nem lesz neki újraküldve a következő Hétfőig, bármennyi üzenetet is küld János ebben az időszakban.';
+$messages['vachandleexp'] = 'A mutató arra használható, hogy összekapcsoljon külömböző Irodán kívül üzeneteket. Ha egy ilyen üzenet el lett küldve, másik ilyen mutatóju üzenet nem lesz elküldve megadott időszakban';
+$messages['vactoexp'] = 'A többi címzett listája akiknek az automatikus válasz el lesz küldve. Ha egy címzett nem a fő cím én nincs ebben a listában, nem lesz neki üzenet küldve.';
+$messages['vactoexp_adv'] = 'Több álnevet vesszővel (,) lehet elválasztani. Pl. teszt1@pelda.hu, teszt2@pelda.hu, teszt3@pelda.hu';
+$messages['vactoexp_err'] = 'Hiba! Több álnév esetén vesszőt (,) kell használni';
+$messages['norulename'] = 'Irjon be egy nevet a szűrőnek';
+$messages['ruleexists'] = 'Ez a szűrőnév már létezik. Kérem irjon be másikat';
+$messages['noheader'] = 'Kérem irja be a fejléc nevét a teszthez';
+$messages['headerbadchars'] = 'Hiba: A fejléc illegális karaktert tartalmaz';
+$messages['noheadervalue'] = 'Kérem irjon be egy értéket a fejléc teszteléséhez';
+$messages['sizewrongformat'] = 'Hiba: az üzenet mérete szám kell legyen';
+$messages['noredirect'] = 'Kérem irjon be egy e-mail címet az átirányításhoz';
+$messages['redirectaddresserror'] = 'Hiba: A cím nem megfelelő';
+$messages['noreject'] = 'Írja be az üzenetet amit válaszolni szeretne a visszadobott üzenetre';
+$messages['vacnodays'] = 'Írja be a napok számát arra az időszakra mig az üzenet nem lesz újraküldve ugyanannak a címzettnek';
+$messages['vacdayswrongformat'] = 'Hiba: az időszak 1-nél nagyobb vagy egyenlő lehet';
+$messages['vacnomsg'] = 'Írja be az üzenet szövegét';
+$messages['notifynomethod'] = 'Írja be a módszert, melyel az értesitést eloküldjük';
+$messages['notifynomsg'] = 'Írja be az üzenet szövegét';
+$messages['sieveruleexp'] = 'Kérem határozzon meg egy vagy több szabályt mellyel az üzenetek szelve lesznek. A szűrők olyan sorrendben futnak le, ahogyan megjelennek a baloldalon. Ha egy szűrőnek megfelel az üzenet, több szűrő nem hajtodik végre.';
+$messages['sieveactexp'] = 'Kérem válasszon a következő lehetőségekből. ezek minden üzenetnre végrehajtódnak, melyek megfelelnek a szabálynak.';
+$messages['sieveheadershlp'] = 'Alább néhány példa más fejlécre melyek tesztelhetőek a szűrőkkel. Válassza ki a fejlécet, adja hozzá a szűrőhőz vagy írjon be egyénit az alábbi szövegmezőbe.';
+$messages['movingfilter'] = 'Szűrő áthelyezése...';
+$messages['noexistingfilters'] = 'Nem találhatók szűrők';
+$messages['importdefault'] = '<b>Alapértelmezett szűrők használata:</b> Alapértelmezett szűrők léteznek. Szeretné használni ezeket a szűrőket?';
+$messages['importother'] = '<b>Szűrők importálása:</b> Egy másik szűrőcsoport %s től létezik. Be szeretné tölteni ezt a szűrőcsoportot?';
+$messages['switchtoadveditor'] = 'ÿtváltás halado szerkesztőre, mellyel Ön direktbe szerkesztheti a sieve fájlt. Az itt végzett változtatások nem lesznek olvashatóak a norlál szerkesztöben és elvesznek ha a szűrők mentésre kerülnek a normál szerkesztőben. Szeretné folytatni?';
+$messages['filterimported'] = 'A szűrő sikeresen importálva';
+$messages['filterimporterror'] = 'Nem sikerült a szűrő importálása. Szerver hiba';
+$messages['filteractionerror'] = 'A kért műveletet nem támogatja a szerver';
+$messages['filtermissingerror'] = 'Nem találom a keresett szabályt';
+$messages['delrulesetconf'] = 'Biztosan törölni szeretné ezt a szabálycsoportot?';
+$messages['rulesetexists'] = 'Már létezik ilyen nevű szabálycsoport. Írjon be másikat!';
+$messages['filtercopied'] = 'Szűrő sikeresen átmásolva';
+$messages['nosieverulesets'] = 'Nincs ilyen szabálycsoport.';
+$messages['baddateformat'] = 'Hiba: a dátumot ÉÉÉÉ-HH-NN formátumban kell megadni.';
+$messages['badtimeformat'] = 'Hiba: az időt ÓÓ:PP:MP fromátumban kell megadni';
+$messages['missingfoldername'] = 'Hiba! Írjon be egy mappanevet.';
+
+?> \ No newline at end of file
diff --git a/plugins/sieverules/localization/it_IT.inc b/plugins/sieverules/localization/it_IT.inc
new file mode 100644
index 000000000..a5a7bc484
--- /dev/null
+++ b/plugins/sieverules/localization/it_IT.inc
@@ -0,0 +1,202 @@
+<?php
+/* Author: Alessio Cecchi */
+
+$labels = array();
+$labels['filters'] = 'Filtri';
+$labels['managefilters'] = 'Gestisci filtri';
+$labels['filtername'] = 'Nome del filtro';
+$labels['disablerule'] = 'Disabilita regola';
+$labels['disabled'] = 'Disabilitata';
+$labels['newfilter'] = 'Nuovo filtro';
+$labels['moveup'] = 'Muovi su';
+$labels['movedown'] = 'Muovi giù';
+$labels['filterallof'] = 'soddisfa tutte le seguenti regole';
+$labels['filteranyof'] = 'soddisfa una qualunque delle seguenti regole';
+$labels['filterany'] = 'tutti i messaggi';
+$labels['filtercontains'] = 'contiene';
+$labels['filternotcontains'] = 'non contiene';
+$labels['filteris'] = 'è uguale a';
+$labels['filterisnot'] = 'non è uguale a';
+$labels['filterexists'] = 'esiste';
+$labels['filternotexists'] = 'non esiste';
+$labels['filterregex'] = 'soddisfa espressione regolare';
+$labels['filternotregex'] = 'non soddisfa espressione regolare';
+$labels['filterunder'] = 'è minore di';
+$labels['filterover'] = 'è maggiore di';
+$labels['filterbefore'] = 'prima';
+$labels['filterafter'] = 'dopo';
+$labels['filteradvoptions'] = 'altre opzioni...';
+$labels['spamtest'] = 'Probabilità Spam';
+$labels['operator'] = 'Operatore';
+$labels['comparator'] = 'Comparatore';
+$labels['isgreaterthan'] = 'è maggiore di';
+$labels['isgreaterthanequal'] = 'è maggiore o uguale a';
+$labels['islessthan'] = 'è minore di';
+$labels['islessthanequal'] = 'è minore o uguale a';
+$labels['equals'] = 'è uguale a';
+$labels['notequals'] = 'è diverso da';
+$labels['countisgreaterthan'] = 'numero di occorrenze maggiore di';
+$labels['countisgreaterthanequal'] = 'numero di occorrenze maggiore o uguale a';
+$labels['countislessthan'] = 'numero di occorrenze minore di';
+$labels['countislessthanequal'] = 'numero di occorrenze minore o uguale a';
+$labels['countequals'] = 'numero di occorrenze uguale a';
+$labels['countnotequals'] = 'numero di occorrenze diverso da';
+$labels['valueisgreaterthan'] = 'valore maggiore di';
+$labels['valueisgreaterthanequal'] = 'valore maggiore o uguale a';
+$labels['valueislessthan'] = 'valore minore di';
+$labels['valueislessthanequal'] = 'valore minore o uguale a';
+$labels['valueequals'] = 'valore uguale a';
+$labels['valuenotequals'] = 'valore diverso da';
+$labels['userpart'] = 'parte utente dell\'indirizzo uguale a';
+$labels['notuserpart'] = 'parte utente dell\'indirizzo diversa da';
+$labels['detailpart'] = 'parte del dettaglio dell\'indirizzo uguale a';
+$labels['notdetailpart'] = 'parte del dettaglio dell\'indirizzo diverso da';
+$labels['domainpart'] = 'dominio uguale a';
+$labels['notdomainpart'] = 'dominio diverso da';
+$labels['teststring'] = 'Stringa di test';
+$labels['messagemoveto'] = 'Sposta il messaggio in';
+$labels['messageredirect'] = 'Reindirizza il messaggio in';
+$labels['messageimapflags'] = 'Contrassegna il messaggio come';
+$labels['messagereject'] = 'Respingi con il seguente messaggio';
+$labels['messagevacation'] = 'Messaggio di assenza';
+$labels['messagekeep'] = 'Conserva il messaggio';
+$labels['messagediscard'] = 'Scarta il messaggio';
+$labels['messagenotify'] = 'Invia notifica';
+$labels['messagestop'] = 'Smetti di processare i filtri';
+$labels['messagehelp'] = 'Cos\'è questo?';
+$labels['sieveorigsubj'] = 'Appendi l\'oggetto originale alla risposta';
+$labels['sievevachandle'] = 'Gestisci';
+$labels['method'] = 'Metodo';
+$labels['options'] = 'Opzioni';
+$labels['messagesrules'] = 'Regole del filtro';
+$labels['messagesactions'] = 'Azioni del filtro';
+$labels['sieveto'] = 'Alias';
+$labels['sievefrom'] = 'Da';
+$labels['flag'] = 'Importanza';
+$labels['importancen'] = 'Nessuna';
+$labels['importance1'] = 'Alta';
+$labels['importance2'] = 'Normale';
+$labels['importance3'] = 'Bassa';
+$labels['flagread'] = 'Letto';
+$labels['flagdeleted'] = 'Cancellato';
+$labels['flaganswered'] = 'Risposto';
+$labels['flagdraft'] = 'Bozza';
+$labels['flagflagged'] = 'Etichettati';
+$labels['addsieverule'] = 'Aggiungi un\'altra regola sotto';
+$labels['addsieveact'] = 'Aggiungi un\'altra azione sotto';
+$labels['deletesieverule'] = 'Cancella questa regola';
+$labels['deletesieveact'] = 'Cancella questa azione';
+$labels['envelopefrom'] = 'Envelope Da';
+$labels['envelopeto'] = 'Envelope A';
+$labels['otherheader'] = 'Altra intestazione';
+$labels['days'] = 'Periodo';
+$labels['message'] = 'Messaggio';
+$labels['sieveruleheaders'] = 'Vedi esempi di altre intestazioni';
+$labels['examplefilters'] = 'Filtri di esempio';
+$labels['importfilters'] = 'Importa Filtri';
+$labels['usedefaultfilter'] = 'Usa i filtri predefiniti';
+$labels['importfilter'] = 'Importa filtri';
+$labels['moreactions'] = 'Altre opzioni...';
+$labels['adveditor'] = 'Editor avanzato';
+$labels['stdeditor'] = 'Editor semplice';
+$labels['messageredirectcopy'] = 'Invia una copia a';
+$labels['messagecopyto'] = 'Copia il messaggio in';
+$labels['body'] = 'Corpo';
+$labels['auto'] = 'Auto';
+$labels['raw'] = 'Raw';
+$labels['text'] = 'Testo';
+$labels['other'] = 'Altro';
+$labels['bodycontentpart'] = 'Contenuto del corpo';
+$labels['notchecked'] = 'non etichettato';
+$labels['spamlevelisgreaterthanequal'] = 'è maggiore o uguale a';
+$labels['spamlevelislessthanequal'] = 'è minore o uguale a';
+$labels['spamlevelequals'] = 'è uguale a';
+$labels['i;ascii-casemap'] = 'corrispondenza non sensibile alle maiuscole';
+$labels['i;octet'] = 'corrispondenza esatta';
+$labels['i;ascii-numeric'] = 'corrispondenza numerica';
+$labels['selectruleset'] = 'Seleziona set di regole';
+$labels['activeruleset'] = '%s (attivo)';
+$labels['activateruleset'] = 'Attiva questo set di regole';
+$labels['newruleset'] = 'Crea un nuovo set di regole';
+$labels['delruleset'] = 'Cancella questo set di regole';
+$labels['renameruleset'] = 'Rinomina questo set di regole';
+$labels['copy'] = 'Copia';
+$labels['copyexistingfilter'] = 'Copia i filtri esistenti';
+$labels['copytoruleset'] = 'Copia il filtro in un altro set di regole';
+$labels['copyfromruleset'] = 'Copia i filtri da un set di regole esistente';
+$labels['time'] = 'Ora';
+$labels['weekday'] = 'Giorno della settimana';
+$labels['virustest'] = 'Probabilità Virus';
+$labels['novirus'] = 'nessun virus trovato';
+$labels['virusremoved'] = 'virus trovato e rimosso';
+$labels['viruscured'] = 'virus trovato e curato';
+$labels['possiblevirus'] = 'il messaggio potrebbe contenere un virus';
+$labels['definitevirus'] = 'il messaggio potrebbe essere certamente un virus';
+$labels['addheader'] = 'Aggiungi un header';
+$labels['removeheader'] = 'Rimuovi un header';
+$labels['headername'] = 'Nome header';
+$labels['headervalue'] = 'Contenuto header';
+$labels['headerappend'] = 'Accoda ad un header esistente';
+$labels['headerindex'] = 'Indice header';
+$labels['headerdelall'] = 'Tutte le occorrenze';
+$labels['last'] = 'ultimo';
+
+$messages = array();
+$messages['nosieverules'] = 'Nessun filtro trovato.';
+$messages['filterdeleteconfirm'] = 'Sei sicuro/a di di voler cancellare questo filtro?';
+$messages['ruledeleteconfirm'] = 'Sei sicuro/a di voler cancellare questa regola?';
+$messages['actiondeleteconfirm'] = 'Sei sicuro/a di voler cancellare questa azione?';
+$messages['filterunknownerror'] = 'Errore sconosciuto del server';
+$messages['filterconnerror'] = 'Impossibile connettersi al server sieve';
+$messages['filterdeleteerror'] = 'Impossibile cancellare il filtro. Errore del server';
+$messages['filterdeleted'] = 'Filtro cancellato con successo';
+$messages['filtersaved'] = 'Filtro salvato con successo';
+$messages['filtersaveerror'] = 'Impossibile salvare il filtro. Errore del server';
+$messages['vacdaysexp'] = 'Il periodo è il numero di giorni durante i quali il messaggio non sarà più spedito allo stesso utente, a prescindere da quante volte ti abbiano contattato.<br /><br />Per esempio: Se Marco ti scrive una email lunedì e il periodo è impostato a 7, Marco riceverà un messaggio di assenza lunedì ma non ne riceverà altri fino al lunedì successivo, indipendentemente dal n. di email che invia durante la settimana.';
+$messages['vachandleexp'] = 'Un handle può essere usato per collegare diversi messaggi di assenza insieme, una volta che un messaggio è stato inviato nessun altro con lo stesso handle sarà rispedito in quel periodo.';
+$messages['vactoexp'] = 'Lista degli indirizzi dei destinatari aggiuntivi che sono inclusi nella risposta automatica. Se un destinatario non è il tuo indirizzo principale e non è in questa lista, nessun messaggio sarà inviato.';
+$messages['vactoexp_adv'] = 'Separare i diversi indirizzi con una virgola. Per esempio: test1@example.com,test2@example.com,test3@example.com';
+$messages['vactoexp_err'] = 'Errore: i diversi indirizzi devono essere separati da virgole';
+$messages['norulename'] = 'Inserire un nome per il filtro';
+$messages['ruleexists'] = 'Un filtro con questo nome esiste già. Per favore scegline un altro.';
+$messages['noheader'] = 'Inserire il nome dell\'intestazione da testare';
+$messages['headerbadchars'] = 'Errore: L\'intestazione contiene caratteri proibiti';
+$messages['noheadervalue'] = 'Inserire un valore con cui testare l\'intestazione';
+$messages['sizewrongformat'] = 'Errore: Le dimensioni del messaggio devono essere espresse in formato numerico';
+$messages['noredirect'] = 'Inserire un indirizzo email a cui reindirizzare i messaggi';
+$messages['redirectaddresserror'] = 'Errore: L\'indirizzo non è valido';
+$messages['noreject'] = 'Inserire un messaggio da inviare con le email respinte';
+$messages['vacnodays'] = 'Inserire il numero di giorni per il periodo in cui il messaggio non sarà reinviato alla stessa persona';
+$messages['vacdayswrongformat'] = 'Errore: Il periodo deve essere un numero maggiore o uguale a 1';
+$messages['vacnomsg'] = 'Inserire un testo per il messaggio';
+$messages['notifynomethod'] = 'Inserire un metodo con cui la notifica dovrà essere inviata';
+$messages['notifynomsg'] = 'Inserire un testo per il messaggio';
+$messages['sieveruleexp'] = 'Definire una o più regole con cui ogni messaggio sarà testato. I filtri sono lanciati nell\'ordine in cui essi appaiono nella sinistra della schermata. Se una regola viene soddisfatta nessun altro filtro viene valutato.';
+$messages['sieveruleexp_stop'] = 'Definire una o più regole con le quali testare i messaggi. I filtri sono lanciati nell\'ordine in cui appaiono nella sinistra della schermata fintanto che non viene eseguita un\'azione di \'Stop\'.';
+$messages['sieveactexp'] = 'Selezionare una delle opzioni. Queste azioni saranno eseguite per ogni messaggio che soddiferà le regole qui sopra.';
+$messages['sieveheadershlp'] = 'Questi sono alcuni esempi di intestazioni che possono essere testate dal filtro. Scegliere un\'intestazione per aggiungerla alla regola, o scriverne una personalizzata nella casella qui sopra.';
+$messages['movingfilter'] = 'Sto spostando il filtro...';
+$messages['noexistingfilters'] = 'Nessun filtro esistente rilevato!';
+$messages['importdefault'] = '<b>Usa i filtri predefiniti:</b> C\'è un set predefinito di filtri disponibile. Vuoi usare questi filtri?';
+$messages['importother'] = '<b>Importa filtri:</b> è stato trovato un altro set di filtri da %s. Vuoi importare questi filtri nel tuo set corrente?';
+$messages['switchtoadveditor'] = 'Passare all\'editor avanzato ti consente di editare il \'file sieve\' direttamente. Ogni cambiamento qui potrà risultare illeggibile nell\'editor normale e può essere perso quando i filtri sono salvati usando l\'editor normale. Vuoi continuare?';
+$messages['filterimported'] = 'Filtro importato con successo';
+$messages['filterimporterror'] = 'Impossibile importare il filtro. Errore del server.';
+$messages['notifyinvalidmethod'] = 'Il metodo non sembra essere scritto in un formato valido, deve essere un URI, per esempio: `mailto:alert@example.com`.';
+$messages['nobodycontentpart'] = 'Inserire una parte di contenuto da testare';
+$messages['badoperator'] = 'Spiacente, l\'operatore che hai selezionato non può essere usato in questa regola';
+$messages['filteractionerror'] = 'L\'azione che hai richiesto non è supportata dal server';
+$messages['filtermissingerror'] = 'Impossibile trovare la regola richiesta';
+$messages['contentpartexp'] = 'Il MIME-type o la parte specifica del messaggio che dovrebbe essere testato. Per esempio: `message/rfc822`, `text/html`, `audio/mp3` o `image`.';
+$messages['delrulesetconf'] = 'Sei sicuro di voler cancellare questo set di regole?';
+$messages['rulesetexists'] = 'Un set di regole con questo nome esiste già. Inseriscine un altro.';
+$messages['copyexisting'] = '<b>Copia del set di regole:</b> Vuoi copiare i filtri dal set di regole esistente nel set corrente?';
+$messages['filtercopied'] = 'Filtro copiato con successo';
+$messages['nosieverulesets'] = 'Nessun set di regole trovato.';
+$messages['baddateformat'] = 'Errore: Inserire la data nel formato YYYY-MM-DD';
+$messages['badtimeformat'] = 'Errore: Inserire l\'ora nel formato HH:MM:SS';
+$messages['missingfoldername'] = 'Errore: Per favore inserisci il nome di una cartella';
+$messages['eheadernoname'] = 'Errore: Per favore inserisci il nome di un header';
+$messages['eheadernoval'] = 'Errore: Per favore inserisci il contenuto di un header';
+
+?> \ No newline at end of file
diff --git a/plugins/sieverules/localization/nl_NL.inc b/plugins/sieverules/localization/nl_NL.inc
new file mode 100644
index 000000000..ccdeeb7c4
--- /dev/null
+++ b/plugins/sieverules/localization/nl_NL.inc
@@ -0,0 +1,205 @@
+<?php
+/* Author: Beheer */
+
+$labels = array();
+$labels['filters'] = 'Filters';
+$labels['filtersname'] = 'Filters ($name)';
+$labels['managefilters'] = 'Beheer inkomende mail filters';
+$labels['filtername'] = 'Filternaam';
+$labels['disablerule'] = 'Regel uitschakelen';
+$labels['disabled'] = 'Uitgeschakeld';
+$labels['newfilter'] = 'Nieuw filter';
+$labels['moveup'] = 'Omhoog';
+$labels['movedown'] = 'Omlaag';
+$labels['filterallof'] = 'die voldoen aan alle volgende regels';
+$labels['filteranyof'] = 'die voldoen aan een van de volgende regels';
+$labels['filterany'] = 'alle berichten';
+$labels['filtercontains'] = 'bevat';
+$labels['filternotcontains'] = 'bevat niet';
+$labels['filteris'] = 'is gelijk aan';
+$labels['filterisnot'] = 'is niet gelijk aan';
+$labels['filterexists'] = 'bestaat';
+$labels['filternotexists'] = 'bestaat niet';
+$labels['filterregex'] = 'voldoet aan reguliere expressie';
+$labels['filternotregex'] = 'voldoet niet aan reguliere expressie';
+$labels['filterunder'] = 'onder';
+$labels['filterover'] = 'over';
+$labels['filterbefore'] = 'is voor';
+$labels['filterafter'] = 'is na';
+$labels['filteradvoptions'] = 'meer opties...';
+$labels['spamtest'] = 'Spam waarschijnlijkheid';
+$labels['operator'] = 'Operator';
+$labels['comparator'] = 'Vergelijker';
+$labels['isgreaterthan'] = 'is groter dan';
+$labels['isgreaterthanequal'] = 'is groter dan of gelijk aan';
+$labels['islessthan'] = 'is minder dan';
+$labels['islessthanequal'] = 'is minder dan of gelijk aan';
+$labels['equals'] = 'is gelijk aan';
+$labels['notequals'] = 'is niet gelijk aan';
+$labels['countisgreaterthan'] = 'aantal is groter dan';
+$labels['countisgreaterthanequal'] = 'aantal is groter dan of gelijk aan';
+$labels['countislessthan'] = 'aantal is kleiner dan';
+$labels['countislessthanequal'] = 'aantal is kleiner dan of gelijk aan';
+$labels['countequals'] = 'aantal is gelijk aan';
+$labels['countnotequals'] = 'aantal is niet gelijk aan';
+$labels['valueisgreaterthan'] = 'waarde is groter dan';
+$labels['valueisgreaterthanequal'] = 'waarde is groter dan of gelijk aan';
+$labels['valueislessthan'] = 'waarde is minder dan';
+$labels['valueislessthanequal'] = 'waarde is minder dan of gelijk aan';
+$labels['valueequals'] = 'waarde is gelijk aan';
+$labels['valuenotequals'] = 'waarde is niet gelijk aan';
+$labels['userpart'] = 'gebruikersdeel is gelijk aan';
+$labels['notuserpart'] = 'gebruikersdeel is niet gelijk aan';
+$labels['detailpart'] = 'detaildeel is gelijk aan';
+$labels['notdetailpart'] = 'detaildeel is niet gelijk aan';
+$labels['domainpart'] = 'domeindeel is gelijk aan';
+$labels['notdomainpart'] = 'domeindeel is niet gelijk aan';
+$labels['teststring'] = 'Testwaarde';
+$labels['messagemoveto'] = 'Verplaats bericht naar';
+$labels['messageredirect'] = 'Verstuur bericht door naar';
+$labels['messageimapflags'] = 'Markeer bericht als';
+$labels['messagereject'] = 'Weiger met bericht';
+$labels['messagevacation'] = 'Afwezigheidsbericht';
+$labels['messagekeep'] = 'Bericht behouden';
+$labels['messagediscard'] = 'Ontdoen van bericht';
+$labels['messagenotify'] = 'Verstuur notificatie';
+$labels['messagestop'] = 'Stop filterverwerking';
+$labels['messagehelp'] = 'Wat is dit?';
+$labels['sieveorigsubj'] = 'Voeg origineel onderwerp toe aan reactie';
+$labels['sievevachandle'] = 'Reactienaam (\'handle\')';
+$labels['method'] = 'Methode';
+$labels['options'] = 'Opties';
+$labels['messagesrules'] = 'Filterregels';
+$labels['messagesactions'] = 'Filteracties';
+$labels['sieveto'] = 'Aliassen';
+$labels['sievefrom'] = 'Van';
+$labels['flag'] = 'Belangrijkheid';
+$labels['importancen'] = 'Geen';
+$labels['importance1'] = 'Hoog';
+$labels['importance2'] = 'Normaal';
+$labels['importance3'] = 'Laag';
+$labels['flagread'] = 'Gelezen';
+$labels['flagdeleted'] = 'Verwijderd';
+$labels['flaganswered'] = 'Beantwoord';
+$labels['flagdraft'] = 'Concept';
+$labels['flagflagged'] = 'Gemarkeerd';
+$labels['addsieverule'] = 'Nieuwe regel onder deze';
+$labels['addsieveact'] = 'Nieuwe actie onder deze';
+$labels['deletesieverule'] = 'Verwijder deze regel';
+$labels['deletesieveact'] = 'Verwijder deze actie';
+$labels['envelopefrom'] = 'Envelop Van';
+$labels['envelopeto'] = 'Envelop Aan';
+$labels['otherheader'] = 'Andere header';
+$labels['days'] = 'Periode';
+$labels['message'] = 'Bericht';
+$labels['sieveruleheaders'] = 'Bekijk voorbeelden van andere headers';
+$labels['examplefilters'] = 'Voorbeelden filters';
+$labels['importfilters'] = 'Importeer filters';
+$labels['usedefaultfilter'] = 'Gebruik standaardfilters';
+$labels['importfilter'] = 'Importeer filters';
+$labels['moreactions'] = 'Meer opties...';
+$labels['adveditor'] = 'Geavanceerde editor';
+$labels['stdeditor'] = 'Standaard editor';
+$labels['messageredirectcopy'] = 'Verstuur kopie naar';
+$labels['messagecopyto'] = 'Kopie bericht naar';
+$labels['body'] = 'Bericht';
+$labels['auto'] = 'Automatisch';
+$labels['raw'] = 'Bron';
+$labels['text'] = 'Tekst';
+$labels['other'] = 'Anders';
+$labels['bodycontentpart'] = 'Inhoudsgedeelte';
+$labels['notchecked'] = 'niet gecontroleerd';
+$labels['spamlevelisgreaterthanequal'] = 'is groter dan of gelijk aan';
+$labels['spamlevelislessthanequal'] = 'is kleiner dan of gelijk aan';
+$labels['spamlevelequals'] = 'is gelijk aan';
+$labels['i;ascii-casemap'] = 'hoofdlettergevoelige vergelijking';
+$labels['i;octet'] = 'exacte vergelijking';
+$labels['i;ascii-numeric'] = 'numerieke vergelijking';
+$labels['selectruleset'] = 'Selecteer regelset';
+$labels['activeruleset'] = '%s (actief)';
+$labels['activateruleset'] = 'Activeer deze regelset';
+$labels['isactive'] = 'Actieve regelset';
+$labels['isinactive'] = 'Inactieve regelset';
+$labels['newruleset'] = 'Maak een nieuwe regelset';
+$labels['delruleset'] = 'Verwijder deze regelset';
+$labels['renameruleset'] = 'Hernoem deze regelset';
+$labels['copy'] = 'Kopie';
+$labels['copyexistingfilter'] = 'Kopieer bestaande filters';
+$labels['copytoruleset'] = 'Kopieer filter naar een andere regelset';
+$labels['copyfromruleset'] = 'Kopieer filters van bestaande regelset';
+$labels['time'] = 'Tijd';
+$labels['weekday'] = 'Weekdag';
+$labels['virustest'] = 'Virus waarschijnlijkheid';
+$labels['novirus'] = 'geen virus gevonden';
+$labels['virusremoved'] = 'virus gevonden en verwijderd';
+$labels['viruscured'] = 'virus gevonden en genezen';
+$labels['possiblevirus'] = 'bericht bevat mogelijk een virus';
+$labels['definitevirus'] = 'bericht bevat hoogstwaarschijnlijk een virus';
+$labels['addheader'] = 'Header toevoegen';
+$labels['removeheader'] = 'Header verwijderen';
+$labels['headername'] = 'Header naam';
+$labels['headervalue'] = 'Header waarde';
+$labels['headerappend'] = 'Toevoegen aan bestaande header.';
+$labels['headerindex'] = 'Header index';
+$labels['headerdelall'] = 'allen';
+$labels['last'] = 'laatste';
+
+$messages = array();
+$messages['nosieverules'] = 'Geen filters gevonden.';
+$messages['filterdeleteconfirm'] = 'Weet u zeker dat u dit filter wilt verwijderen?';
+$messages['ruledeleteconfirm'] = 'Weet u zeker dat u deze regel wilt verwijderen?';
+$messages['actiondeleteconfirm'] = 'Weet u zeker dat u deze actie wilt verwijderen?';
+$messages['filterunknownerror'] = 'Onbekende serverfout';
+$messages['filterconnerror'] = 'Kan geen verbinding maken met de managesieve server';
+$messages['filterdeleteerror'] = 'Kan filter niet verwijderen. Er is een fout opgetreden';
+$messages['filterdeleted'] = 'Filter succesvol verwijderd';
+$messages['filtersaved'] = 'Filter succesvol opgeslagen';
+$messages['filtersaveerror'] = 'Kan filter niet opslaan. Er is een fout opgetreden.';
+$messages['vacdaysexp'] = 'De periode is het aantal dagen dat een bericht niet opnieuw wordt verzonden naar dezelfde ontvanger, ongeacht het aantal keer dat deze contact opneemt.<br /><br />Voorbeeld: Als Jan u op maandag emailt en de periode is op 7 ingesteld dan zal Jan op maandag een afwezigheidsbericht ontvangen, maar geen andere tot de daaropvolgende maandag, ongeacht het aantal emails welke hij gedurende de week verstuurt.';
+$messages['vachandleexp'] = 'Een reactienaam of handle kan verschillende afwezigheidsberichten groeperen, zodat er binnen een periode slechts een enkel afwezigheidsbericht met dezelfde reactienaam wordt verstuurd.';
+$messages['vactoexp'] = 'Lijst van extra adressen welke bij een afwezigsheidmelding gebruikt worden. Meldingen worden alleen verzonden als het bericht aan het standaard adres of een adres in deze lijst gericht is.';
+$messages['vactoexp_adv'] = 'Scheid meerdere aliases met een komma (,). Bijvoorbeeld: test1@example.com,test2@example.com,test3@example.com';
+$messages['vactoexp_err'] = 'Fout: Meerdere aliases moeten met een komma (,) worden gescheiden';
+$messages['norulename'] = 'Vul een naam in voor dit filter';
+$messages['ruleexists'] = 'Deze naam is al in gebruik voor een ander filter, voer a.u.b. een andere in';
+$messages['noheader'] = 'Vul een naam voor de kop in om te testen';
+$messages['headerbadchars'] = 'Fout: de kop bevat ongeldige tekens';
+$messages['noheadervalue'] = 'Vul een waarde in om met de kop te testen';
+$messages['sizewrongformat'] = 'Fout: berichtgrootte is niet numeriek';
+$messages['noredirect'] = 'Vul een e-mailadres in om berichten naar door te sturen';
+$messages['redirectaddresserror'] = 'Fout: ongeldig e-mailadres';
+$messages['noreject'] = 'Vul een bericht in om mee te zenden met geweigerde e-mail';
+$messages['vacnodays'] = 'Vul het aantal dagen in voor de periode waarin het bericht niet opnieuw naar dezelfde persoon wordt verzonden';
+$messages['vacdayswrongformat'] = '\'Fout: De periode moet groter dan of gelijk aan 1 zijn';
+$messages['vacnomsg'] = 'Vul tekst in voor uw bericht';
+$messages['notifynomethod'] = 'Kies een verzendmethode voor de notificatie';
+$messages['notifynomsg'] = 'Vul tekst in voor uw melding';
+$messages['sieveruleexp'] = 'Maak een of meer regels waaraan een bericht moet voldoen. Filters worden uitgevoerd in de volgorde zoals deze links op het scherm zijn te zien. Als aan een regel wordt voldaan dan worden eventuele volgende regels genegeerd.';
+$messages['sieveruleexp_stop'] = 'Maak een of meer regels waaraan een bericht moet voldoen. Filters worden uitgevoerd in de volgorde zoals deze links op het scherm zijn te zien totdat een \'Stop\' aktie optreedt';
+$messages['sieveactexp'] = '\'Maak een keuze uit onderstaande opties. Deze acties worden uitgevoerd voor elk bericht dat aan bovenstaande regels voldoet.';
+$messages['sieveheadershlp'] = 'Hieronder staan voorbeelden van andere koppen die kunnen worden getest door de filters. Kies een kop om toe te voegen aan de regel of vul een kop in in het invoerveld.';
+$messages['movingfilter'] = 'Bezig met filter verplaatsen...';
+$messages['noexistingfilters'] = 'Geen bestaande filters gevonden!';
+$messages['importdefault'] = '\'<b>Gebruik standaardfilters:</b> Er is een set van standaardfilters beschikbaar. Wilt u deze filters gebruiken?';
+$messages['importother'] = '<b>Import filters:</b> Er is een andere set filters van %s gevonden. Wilt u deze filters in uw huidige set importeren?';
+$messages['switchtoadveditor'] = 'U kunt het \'Sieve\' bestand rechtstreeks wijzigen via de geavanceerde editor. Veranderingen zijn mogelijk onleesbaar in de standaardeditor en kunnen verloren gaan als filters via de standaardeditor worden opgeslagen. Wilt u doorgaan?';
+$messages['filterimported'] = 'Filter succesvol geimporteerd';
+$messages['filterimporterror'] = 'Kan filter niet importeren. Er is een fout opgetreden.';
+$messages['notifyinvalidmethod'] = 'De methode is in een ongeldig formaat (URI) geschreven. Voorbeeld: `mailto:alert@example.com`.';
+$messages['nobodycontentpart'] = 'Vul een inhoudsgedeelte in om te testen';
+$messages['badoperator'] = 'De gekozen operator kan niet in deze regel worden gebruikt';
+$messages['filteractionerror'] = 'De server ondersteund deze actie niet';
+$messages['filtermissingerror'] = 'Regel niet gevonden';
+$messages['contentpartexp'] = 'Het MIME-type of specifiek gedeelte van het bericht welke getest moet worden. Bijvoorbeeld: `message/rfc822`, `text/html`, `audio/mp3` or `image`.';
+$messages['delrulesetconf'] = 'Weet u zeker dat u deze regelset wilt verwijderen?';
+$messages['rulesetexists'] = 'Er is al een regelset met deze naam, voer a.u.b. een andere in';
+$messages['copyexisting'] = '<b>Bestaande regelset kopie&euml;ren:</b> Wilt u filters van een bestaande regelset naar u huidige regelset kopie&euml;ren?';
+$messages['filtercopied'] = 'Filter succesvol gekopieerd';
+$messages['nosieverulesets'] = 'Geen regelsets gevonden.';
+$messages['baddateformat'] = 'Fout: Vul de datum in het JJJJ-MM-DD in';
+$messages['badtimeformat'] = 'Fout: Vul de tijd in het format UU:MM:SS in';
+$messages['missingfoldername'] = 'Fout: Vul een mapnaam in';
+$messages['eheadernoname'] = 'Fout: Vul een header naam in';
+$messages['eheadernoval'] = 'Fout: Vul een header waarde in';
+
+?> \ No newline at end of file
diff --git a/plugins/sieverules/localization/pl_PL.inc b/plugins/sieverules/localization/pl_PL.inc
new file mode 100644
index 000000000..4f1de93f8
--- /dev/null
+++ b/plugins/sieverules/localization/pl_PL.inc
@@ -0,0 +1,205 @@
+<?php
+/* Author: Bartosz Mierzwiak */
+
+$labels = array();
+$labels['filters'] = 'Filtry';
+$labels['filtersname'] = 'Filtry ($name)';
+$labels['managefilters'] = 'Zarządzaj filtrami';
+$labels['filtername'] = 'Nazwa reguły:';
+$labels['disablerule'] = 'Wyłącz regułę';
+$labels['disabled'] = 'Wyłączona';
+$labels['newfilter'] = 'Nowy filtr';
+$labels['moveup'] = 'Przenieś wyżej';
+$labels['movedown'] = 'Przenieś niżej';
+$labels['filterallof'] = 'spełniające wszystkie poniższe kryteria';
+$labels['filteranyof'] = 'spełniające dowolne z poniższych kryteriów';
+$labels['filterany'] = 'wszystkie wiadomości';
+$labels['filtercontains'] = 'zawiera';
+$labels['filternotcontains'] = 'nie zawiera';
+$labels['filteris'] = 'jest równa';
+$labels['filterisnot'] = 'nie jest równa';
+$labels['filterexists'] = 'istnieje';
+$labels['filternotexists'] = 'nie istnieje';
+$labels['filterregex'] = 'pasuje do wyrażenia regularnego';
+$labels['filternotregex'] = 'nie pasuje do wyrażenia regularnego ';
+$labels['filterunder'] = 'jest mniejsza niż';
+$labels['filterover'] = 'jest większa niż';
+$labels['filterbefore'] = 'jest wcześniejsza';
+$labels['filterafter'] = 'jest późniejsza';
+$labels['filteradvoptions'] = 'więcej opcji...';
+$labels['spamtest'] = 'Przypuszczalnie Spam';
+$labels['operator'] = 'Operator';
+$labels['comparator'] = 'Komparator';
+$labels['isgreaterthan'] = 'jest większe od';
+$labels['isgreaterthanequal'] = 'jest większa lub równa';
+$labels['islessthan'] = 'jest mniejsza niż';
+$labels['islessthanequal'] = 'jest mniejsza lub równa';
+$labels['equals'] = 'jest równy';
+$labels['notequals'] = 'nie równa się';
+$labels['countisgreaterthan'] = 'liczba jest większa niż';
+$labels['countisgreaterthanequal'] = 'liczba jest większa lub równa';
+$labels['countislessthan'] = 'liczba jest równa';
+$labels['countislessthanequal'] = 'liczba jest mniejsza niż';
+$labels['countequals'] = 'liczba jest równa';
+$labels['countnotequals'] = 'liczba jest inna niż';
+$labels['valueisgreaterthan'] = 'wartość jest wyższa niż';
+$labels['valueisgreaterthanequal'] = 'wartość jest większa lub równa';
+$labels['valueislessthan'] = 'wartość jest mniejsza niż';
+$labels['valueislessthanequal'] = 'wartość jest mniejsza lub równa';
+$labels['valueequals'] = 'wartość jest równa';
+$labels['valuenotequals'] = 'wartość jest inna niż';
+$labels['userpart'] = 'część użytkowników jest równa';
+$labels['notuserpart'] = 'część użytkowników jest inna niż';
+$labels['detailpart'] = 'część szczegółów jest równa';
+$labels['notdetailpart'] = 'część szczegółów jest inna niż';
+$labels['domainpart'] = 'część domeny zawiera';
+$labels['notdomainpart'] = 'część domeny nie zawiera';
+$labels['teststring'] = 'Łańcuch testowy';
+$labels['messagemoveto'] = 'Przenieś wiadomość do';
+$labels['messageredirect'] = 'Przekierowanie wiadomości';
+$labels['messageimapflags'] = 'Oznacz wiadomość jako';
+$labels['messagereject'] = 'Odrzuć wiadomość';
+$labels['messagevacation'] = 'Automatyczna odpowiedź';
+$labels['messagekeep'] = 'Zachowaj wiadomość';
+$labels['messagediscard'] = 'Odrzuć wiadomość';
+$labels['messagenotify'] = 'Wyślij zgłoszenie';
+$labels['messagestop'] = 'Nie sprawdzaj kolejnych filtrów';
+$labels['messagehelp'] = 'Co to jest?';
+$labels['sieveorigsubj'] = 'Dołącz oryginalny przedmiot odpowiedzi';
+$labels['sievevachandle'] = 'Obsłuż';
+$labels['method'] = 'Metoda';
+$labels['options'] = 'Opcje';
+$labels['messagesrules'] = 'Reguły filtra';
+$labels['messagesactions'] = 'Filtr działania';
+$labels['sieveto'] = 'alians';
+$labels['sievefrom'] = 'Z';
+$labels['flag'] = 'Ważność';
+$labels['importancen'] = 'Najwyższa';
+$labels['importance1'] = 'Wysoka';
+$labels['importance2'] = 'Normalna';
+$labels['importance3'] = 'Niska';
+$labels['flagread'] = 'Odebrane';
+$labels['flagdeleted'] = 'Usunięto';
+$labels['flaganswered'] = 'Odpowiedział';
+$labels['flagdraft'] = 'Projekt';
+$labels['flagflagged'] = 'Oflagowane';
+$labels['addsieverule'] = 'Dodaj nowy przepis, poniżej tej jednej';
+$labels['addsieveact'] = 'Dodaj kolejne działania, pod tym jednym';
+$labels['deletesieverule'] = 'Usuń tę regułę';
+$labels['deletesieveact'] = 'Usuń to działanie';
+$labels['envelopefrom'] = 'Adres Nadawcy';
+$labels['envelopeto'] = 'Adres Odbiorcy';
+$labels['otherheader'] = 'Inny nagłówek';
+$labels['days'] = 'Liczba dni';
+$labels['message'] = 'Wiadomość';
+$labels['sieveruleheaders'] = 'Pokaż przykłady innych nagłówków';
+$labels['examplefilters'] = 'Przykłady filtrów';
+$labels['importfilters'] = 'Importuj filtry';
+$labels['usedefaultfilter'] = 'Użyj domyślnych filtrów';
+$labels['importfilter'] = 'Importuj filtr';
+$labels['moreactions'] = 'Więcej opcji...';
+$labels['adveditor'] = 'Zaawansowana edycja';
+$labels['stdeditor'] = 'Edytor standardowy';
+$labels['messageredirectcopy'] = 'Wyślij kopię wiadomości do:';
+$labels['messagecopyto'] = 'Kopiuj wiadomość do:';
+$labels['body'] = 'Cała wiadomość';
+$labels['auto'] = 'Auto';
+$labels['raw'] = 'Raw';
+$labels['text'] = 'Text';
+$labels['other'] = 'Inny';
+$labels['bodycontentpart'] = 'Zawartość części';
+$labels['notchecked'] = 'nie sprawdza';
+$labels['spamlevelisgreaterthanequal'] = 'jest większa lub równa';
+$labels['spamlevelislessthanequal'] = 'jest mniejsza lub równa';
+$labels['spamlevelequals'] = 'jest równa';
+$labels['i;ascii-casemap'] = 'przypadek-ignorowania łańcucha dopasowania';
+$labels['i;octet'] = 'dopasowanie łańcucha';
+$labels['i;ascii-numeric'] = 'numeryczne dopasowanie';
+$labels['selectruleset'] = 'Zaznacz zestaw reguł';
+$labels['activeruleset'] = '%s (aktywna)';
+$labels['activateruleset'] = 'Aktywuj zestaw reguł';
+$labels['isactive'] = 'Aktywny zestaw reguł';
+$labels['isinactive'] = 'Niekatywny zestaw reguł';
+$labels['newruleset'] = 'Utwórz nowy zestaw reguł';
+$labels['delruleset'] = 'Usuń ten zestaw reguł';
+$labels['renameruleset'] = 'Zmień nazwę tego zestawu reguł';
+$labels['copy'] = 'Kopiuj';
+$labels['copyexistingfilter'] = 'Kopiuj istniejące filtry';
+$labels['copytoruleset'] = 'Kopiuj filtr do innego zestawu reguł';
+$labels['copyfromruleset'] = 'Kopiuj filtry z istniejącego zestawu reguł';
+$labels['time'] = 'Czas';
+$labels['weekday'] = 'Dzień tygodnia';
+$labels['virustest'] = 'Prawdopodobieństwo wirusa';
+$labels['novirus'] = 'nie znaleziono wirusa';
+$labels['virusremoved'] = 'wirus znaleziony i usunięty';
+$labels['viruscured'] = 'wirus znaleziony i zneutralizowany';
+$labels['possiblevirus'] = 'wiadomość może zawierać wirusa';
+$labels['definitevirus'] = 'wiadomość może zawierać groźnego wirusa';
+$labels['addheader'] = 'Dodaj nagłówek';
+$labels['removeheader'] = 'Usuń nagłówek';
+$labels['headername'] = 'Nazwa nagłówka';
+$labels['headervalue'] = 'Wartość nagłówka';
+$labels['headerappend'] = 'Dodaj do istniejącego nagłówka wiadomości';
+$labels['headerindex'] = 'Indeks nagłówka';
+$labels['headerdelall'] = 'wszystkie zdarzenia';
+$labels['last'] = 'ostatni';
+
+$messages = array();
+$messages['nosieverules'] = 'Nie znaleziono filtrów.';
+$messages['filterdeleteconfirm'] = 'Czy na pewno chcesz usunąć ten filtr?';
+$messages['ruledeleteconfirm'] = 'Czy na pewno chcesz usunąć tę regułę?';
+$messages['actiondeleteconfirm'] = 'Czy na pewno chcesz usunąć tę zasadę działania? ';
+$messages['filterunknownerror'] = 'Nieznany błąd serwera.';
+$messages['filterconnerror'] = 'Nie można się połączyć z serwerem filtrów';
+$messages['filterdeleteerror'] = 'Nie można usunąć filtru. Błąd serwera!';
+$messages['filterdeleted'] = 'Filtr został usunięty';
+$messages['filtersaved'] = 'Filtr zapisany';
+$messages['filtersaveerror'] = 'Nie można zapisać filtra - Błąd serwera!';
+$messages['vacdaysexp'] = 'Okres to liczba dni, podczas których wiadomość nie zostanie wysłana ponownie do tego samego użytkownika, bez względu na to ile razy próbował się z tobą skontaktować. Na przykład: Jeśli Jasio wyśle wiadomości e-mail w poniedziałek, a okres ten zostanie ustawiony na 7 dni, Małgosia otrzyma automatyczną odpowiedź w poniedziałek, ale nie będzie dostawała kolejnych do następnego poniedziałku, bez względu na liczbę wiadomości e-mail wysłanych w ciągu tygodnia.';
+$messages['vachandleexp'] = 'Uchwyt może być stosowany do łączenia różnych komunikatów razem, gdy jedna wiadomość została wysłana, żadne inne wiadomości nie bedą wysyłane w tym okresie.';
+$messages['vactoexp'] = 'Lista dodatkowych adresów odbiorców, które są zawarte w automatycznej odpowiedzi.';
+$messages['vactoexp_adv'] = 'Rozdziel adresy aliasów przecinkiem (,). Na przykład: test1@example.com,test2@example.com,test3@example.com';
+$messages['vactoexp_err'] = 'Błąd: Adresy aliasów muszą być rodzielone przecinkiem (,)';
+$messages['norulename'] = 'Proszę podać nazwę tego filtru';
+$messages['ruleexists'] = 'Filtr o takiej nazwie już istnieje. Proszę podać inną nazwę!';
+$messages['noheader'] = 'Proszę wprowadzić nazwę nagłówka do badania';
+$messages['headerbadchars'] = 'Błąd: Nagłówek zawiera zakazane znaki!';
+$messages['noheadervalue'] = 'Proszę wprowadzić wartość do badań nagłówka.';
+$messages['sizewrongformat'] = 'Błąd: Rozmiar wiadomości musi być określony numeryczne';
+$messages['noredirect'] = 'Proszę podać adres e-mail aby przekierować wiadomości';
+$messages['redirectaddresserror'] = 'Błąd: Adres wydaje się nieprawidłowy';
+$messages['noreject'] = 'Proszę wprowadzić treść wiadomości, aby wysłać e-mail z komunikatem odrzucenia';
+$messages['vacnodays'] = 'Proszę podać liczbę dni w okresie, w którym wiadomość nie zostanie wysłana ponownie do tej samej osoby';
+$messages['vacdayswrongformat'] = 'Błąd: Okres ten musi być liczbą większą lub równą 1 ';
+$messages['vacnomsg'] = 'Proszę wprowadzić treść do Twojej wiadomości generowanej automatycznie';
+$messages['notifynomethod'] = 'Proszę wprowadzić metodę, dzięki której zgłoszenie powinno być wysłane';
+$messages['notifynomsg'] = 'Proszę wprowadzić treść do Twojej wiadomości';
+$messages['sieveruleexp'] = 'Proszę określić jedną lub więcej reguł z których każda wiadomość będzie testowane. Filtry są uruchamiane w kolejności, w jakiej znajdują się na lewo od ekranu, jeśli nie zostaną znalezione żadne dodatkowe, filtry zostaną przetestowane.';
+$messages['sieveruleexp_stop'] = 'Proszę podać jedną lub więcej reguł jakimi testowana będzie wiadomość. Filtry będą używane w kolejności w jakiej widnieją po lewej stronie tego ekranu, do momentu dotarcia do akcji \'Stop\'.';
+$messages['sieveactexp'] = 'Proszę wybrać jedną z poniższych opcji. Działania te będą wykonywane dla wszystkich wiadomości pasujących do reguł(y).';
+$messages['sieveheadershlp'] = 'Poniżej kilka przykładów innych nagłówków, które mogą być badane przez filtry. Wybierz nagłówek, aby dodać go do przepisu lub wprowadź własny w polu powyżej.';
+$messages['movingfilter'] = 'Przemieszczanie filtra...';
+$messages['noexistingfilters'] = 'Nie znaleziono istniejących filtrów!';
+$messages['importdefault'] = 'Użyj domyślnego zestawu filtrów: Nie ma domyślnie dostępnego zestawu filtrów. Chcesz używać tych filtrów? ';
+$messages['importother'] = 'Importuj filtry: Kolejny zestaw filtrów %s zostało znalezione. Czy chcesz zaimportować te filtry do bieżącego zestawu?';
+$messages['switchtoadveditor'] = 'Przełącz na zaawansowany edytor pozwala na edycję plików bezpośrednio sito. Wszelkie zmiany w tym względzie może być nieczytelne w normalnym edytorze i mogą zostać utracone, gdy filtry są zapisywane przy użyciu normalnego edytora. Czy chcesz kontynuować? ';
+$messages['filterimported'] = 'Filtr zaimportowany';
+$messages['filterimporterror'] = 'Nie można zaimportować filtra. Błąd serwera!';
+$messages['notifyinvalidmethod'] = 'Ta metoda ma nieprawidłowy format, podaj URI. Na przykład: "mailto: alert@example.com".';
+$messages['nobodycontentpart'] = 'Proszę wprowadzić zawartość strony do testowania';
+$messages['badoperator'] = 'Przepraszamy, wybrany operator nie może być stosowany w tej regule.';
+$messages['filteractionerror'] = 'Żądane działanie nie jest obsługiwane przez serwer!';
+$messages['filtermissingerror'] = 'Nie można znaleźć treści reguły';
+$messages['contentpartexp'] = 'Typ MIME lub określonej części wiadomości, które powinny być badane. Na przykład: "message/rfc822`, `text/html`, `audio/mp3` lub `image`.';
+$messages['delrulesetconf'] = 'Czy na pewno chcesz usunąć ten zestaw reguł?';
+$messages['rulesetexists'] = 'Reguła o takiej nazwie już istnieje. Proszę podać inną nazwę';
+$messages['copyexisting'] = 'Kopiowanie istniejącego zestawu reguł: Czy chcesz skopiować filtry z istniejącego zestawu reguł do bieżącego zestawu?';
+$messages['filtercopied'] = 'Filtr przekopiowany';
+$messages['nosieverulesets'] = 'Nie znaleziono zestawu filtrów.';
+$messages['baddateformat'] = 'Błąd: Podaj datę w formacie YYYY-MM-DD';
+$messages['badtimeformat'] = 'Błąd: Podaj czas w formacie HH:MM:SS';
+$messages['missingfoldername'] = 'Błąd: Podaj nazwę folderu';
+$messages['eheadernoname'] = 'Błąd: Podaj nazwę nagłówka';
+$messages['eheadernoval'] = 'Błąd: Podaj wartość nagłówka';
+
+?> \ No newline at end of file
diff --git a/plugins/sieverules/localization/pt_BR.inc b/plugins/sieverules/localization/pt_BR.inc
new file mode 100644
index 000000000..1cf68551a
--- /dev/null
+++ b/plugins/sieverules/localization/pt_BR.inc
@@ -0,0 +1,183 @@
+<?php
+/* Author: Pedro Padron */
+
+$labels = array();
+$labels['filters'] = 'Filtros';
+$labels['managefilters'] = 'Gerenciar filtros';
+$labels['filtername'] = 'Nome do filtro';
+$labels['disablerule'] = 'Desativar regra';
+$labels['disabled'] = 'Desativado';
+$labels['newfilter'] = 'Novo filtro';
+$labels['moveup'] = 'Mover para cima';
+$labels['movedown'] = 'Mover para baixo';
+$labels['filterallof'] = 'corresponde a todas as seguintes regras';
+$labels['filteranyof'] = 'corresponde a uma das seguintes regras';
+$labels['filterany'] = 'todas as mensagens';
+$labels['filtercontains'] = 'contém';
+$labels['filternotcontains'] = 'não contém';
+$labels['filteris'] = 'é igual a';
+$labels['filterisnot'] = 'é diferente de';
+$labels['filterexists'] = 'existe';
+$labels['filternotexists'] = 'não existe';
+$labels['filterregex'] = 'corresponde à expressão';
+$labels['filternotregex'] = 'não corresponde à expressão';
+$labels['filterunder'] = 'é inferior a';
+$labels['filterover'] = 'é superior a';
+$labels['filterbefore'] = 'é antes';
+$labels['filterafter'] = 'é depois';
+$labels['filteradvoptions'] = 'mais opções...';
+$labels['spamtest'] = 'Probabilidade de Spam';
+$labels['operator'] = 'Operador';
+$labels['comparator'] = 'Comparador';
+$labels['isgreaterthan'] = 'é maior que';
+$labels['isgreaterthanequal'] = 'é maior ou igual a';
+$labels['islessthan'] = 'é menor que';
+$labels['islessthanequal'] = 'é menor ou igual a';
+$labels['equals'] = 'é igual a';
+$labels['notequals'] = 'é diferente de';
+$labels['countisgreaterthan'] = 'contagem é maior que';
+$labels['countisgreaterthanequal'] = 'contagem é maior ou igual a';
+$labels['countislessthan'] = 'contagem é menor que';
+$labels['countislessthanequal'] = 'contagem é menor ou igual a';
+$labels['countequals'] = 'contagem é igual a';
+$labels['countnotequals'] = 'contagem é diferente de';
+$labels['valueisgreaterthan'] = 'valor é maior que';
+$labels['valueisgreaterthanequal'] = 'valor é maior ou igual a';
+$labels['valueislessthan'] = 'valor é menor que';
+$labels['valueislessthanequal'] = 'valor é menor ou igual a';
+$labels['valueequals'] = 'valor é igual a';
+$labels['valuenotequals'] = 'valor diferente de';
+$labels['userpart'] = 'parte do utilizador igual a';
+$labels['notuserpart'] = 'parte do utilizador diferente de';
+$labels['detailpart'] = 'parte do detalhe igual a';
+$labels['notdetailpart'] = 'parte do detalhe diferente de';
+$labels['domainpart'] = 'parte do domínio igual a';
+$labels['notdomainpart'] = 'parte do domínio diferente de';
+$labels['teststring'] = 'Texto de teste';
+$labels['messagemoveto'] = 'Mover mensagem para';
+$labels['messageredirect'] = 'Redirecionar mensagem para';
+$labels['messageimapflags'] = 'Marcar mensagem como';
+$labels['messagereject'] = 'Rejeitar com a mensagem';
+$labels['messagevacation'] = 'Mensagem de Fora do Escritório';
+$labels['messagekeep'] = 'Manter mensagem';
+$labels['messagediscard'] = 'Rejeitar mensagem';
+$labels['messagenotify'] = 'Enviar notificação';
+$labels['messagestop'] = 'Parar o processamento de filtros';
+$labels['messagehelp'] = 'O que é isto?';
+$labels['sieveorigsubj'] = 'Acrescentar assunto original à resposta';
+$labels['sievevachandle'] = 'Identificador';
+$labels['method'] = 'Método';
+$labels['options'] = 'Opções';
+$labels['messagesrules'] = 'Regras para Filtros';
+$labels['messagesactions'] = 'Ações para Filtros';
+$labels['sieveto'] = 'Alias';
+$labels['sievefrom'] = 'De';
+$labels['flag'] = 'Importância';
+$labels['importancen'] = 'Nenhum';
+$labels['importance1'] = 'Alta';
+$labels['importance2'] = 'Normal';
+$labels['importance3'] = 'Baixa';
+$labels['flagread'] = 'Lida';
+$labels['flagdeleted'] = 'Eliminada';
+$labels['flaganswered'] = 'Respondida';
+$labels['flagdraft'] = 'Rascunho';
+$labels['flagflagged'] = 'Marcada';
+$labels['addsieverule'] = 'Adicionar outra regra, depois desta';
+$labels['addsieveact'] = 'Adicionar outra ação, depois desta';
+$labels['deletesieverule'] = 'Eliminar esta regra';
+$labels['deletesieveact'] = 'Eliminar esta ação';
+$labels['envelopefrom'] = 'Envelope De';
+$labels['envelopeto'] = 'Envelope Para';
+$labels['otherheader'] = 'Outro cabeçalho';
+$labels['days'] = 'Periodo';
+$labels['message'] = 'Mensagem';
+$labels['sieveruleheaders'] = 'Ver exemplos de outros cabecalhos';
+$labels['examplefilters'] = 'Exemplo de Filtros';
+$labels['importfilters'] = 'Importar Filtros';
+$labels['usedefaultfilter'] = 'Usar filtros predefinidos';
+$labels['importfilter'] = 'Importar filtros';
+$labels['moreactions'] = 'Mais opções...';
+$labels['adveditor'] = 'Editor avançado';
+$labels['stdeditor'] = 'Editor padrão';
+$labels['messageredirectcopy'] = 'Enviar cópia para';
+$labels['messagecopyto'] = 'Copiar mensagem para';
+$labels['body'] = 'Corpo';
+$labels['auto'] = 'Auto';
+$labels['raw'] = 'Raw';
+$labels['text'] = 'Texto';
+$labels['other'] = 'Outro';
+$labels['bodycontentpart'] = 'Parte Conteúdo';
+$labels['notchecked'] = 'não verificado';
+$labels['spamlevelisgreaterthanequal'] = 'é maior ou igual a';
+$labels['spamlevelislessthanequal'] = 'é menor ou igual a';
+$labels['spamlevelequals'] = 'é igual a';
+$labels['i;ascii-casemap'] = 'correspondência de texto indeferente a maiúsculas e minúsculas';
+$labels['i;octet'] = 'correspondência exata do texto';
+$labels['i;ascii-numeric'] = 'correspondência numérica';
+$labels['selectruleset'] = 'Selecionar conjunto de regras';
+$labels['activeruleset'] = '%s (ativo)';
+$labels['activateruleset'] = 'Ativar este conjunto de regras';
+$labels['newruleset'] = 'Criar um no grupo de regras';
+$labels['delruleset'] = 'Eliminar este conjunto de regras';
+$labels['renameruleset'] = 'Renomear este conjunto de regras';
+$labels['copy'] = 'Copiar';
+$labels['copyexistingfilter'] = 'Copiar filtros existentes';
+$labels['copytoruleset'] = 'Copiar o filtro para outro conjunto de regras';
+$labels['copyfromruleset'] = 'Copiar filtros de um conjunto regras existente';
+$labels['time'] = 'Tempo';
+$labels['weekday'] = 'dia da semana';
+
+$messages = array();
+$messages['nosieverules'] = 'Nenhum filtro encontrado.';
+$messages['filterdeleteconfirm'] = 'Tem a certeza que pretende eliminar este filtro?';
+$messages['ruledeleteconfirm'] = 'Tem a certeza que pretende eliminar esta regra?';
+$messages['actiondeleteconfirm'] = 'Tem a certeza que pretende eliminar esta ação?';
+$messages['filterunknownerror'] = 'Erro de servidor desconhecido';
+$messages['filterconnerror'] = 'Não foi possível conectar ao servidor Sieve';
+$messages['filterdeleteerror'] = 'Não foi possível eliminar o filtro. Erro no servidor';
+$messages['filterdeleted'] = 'Filtro eliminado com sucesso';
+$messages['filtersaved'] = 'Filtro salvo com sucesso';
+$messages['filtersaveerror'] = 'Não foi possível salvar o filtro. Erro no servidor';
+$messages['vacdaysexp'] = 'O período é o número de dias durante o qual a mensagem não será reenviada para o mesmo remetente, não importando quantas vezes ele entre contato.<br/><br/>Por exemplo: Se João lhe enviar e-mails na segunda-feira e o período estiver definido para 7 dias, João irá receber uma mensagem de Fora do Escritório na segunda-feira, mas não irá receber mais nenhuma até à segunda-feira seguinte, não importando quantos e-mails ele lhe envie durante a semana.';
+$messages['vachandleexp'] = 'Um identificador pode ser usado para ligar as diferentes mensagens de Fora do Escritório em conjunto, uma vez que uma mensagem foi enviada nenhuma outra com o mesmo identificador será enviada.';
+$messages['vactoexp'] = 'Lista de endereços de destinatários adicionais que estão incluídos na resposta automática. Se um destinatário de e-mail não for seu endereço principal e não estiver nesta lista, nenhuma mensagem será enviada.';
+$messages['norulename'] = 'Por favor, indique um nome para este filtro';
+$messages['ruleexists'] = 'Já existe um filtro com este nome. Por favor, indique outro';
+$messages['noheader'] = 'Por favor, indique o nome do cabeçalho para testar';
+$messages['headerbadchars'] = 'Erro: O cabeçalho contém caracteres proibidos';
+$messages['noheadervalue'] = 'Por favor indique um valor para testar o cabeçalho contra';
+$messages['sizewrongformat'] = 'Erro: O tamanho da mensagem deve ser numérico';
+$messages['noredirect'] = 'Indique um endereço de e-mail para redirecionar as mensagens';
+$messages['redirectaddresserror'] = 'Erro: O endereço de e-mail parece ser inválido';
+$messages['noreject'] = 'Indique uma mensagem para enviar juntamente com o e-mail rejeitado';
+$messages['vacnodays'] = 'Por favor insira um número de dias para o período em que a mensagem não será reenviado para a mesma pessoa';
+$messages['vacdayswrongformat'] = 'Erro: O período deve ser um número maior ou igual a 1';
+$messages['vacnomsg'] = 'Insira o texto para a sua mensagem';
+$messages['notifynomethod'] = 'Por favor, indique um método pelo qual a notificação deve ser enviada';
+$messages['notifynomsg'] = 'Insira o texto para a sua mensagem';
+$messages['sieveruleexp'] = 'Por favor, defina uma ou mais regras sobre as quais cada mensagem será testada. Os filtros são executados na ordem em que aparecem à esquerda da tela, se for encontrada uma correspondência mais nenhum filtro será testado.';
+$messages['sieveruleexp_stop'] = 'Por favor, defina uma ou mais regras sobre as quais cada mensagem será testada. Os filtros são executados na ordem em que aparecem à esquerda da tela até uma ação de \'Stop\' ser encontrada.';
+$messages['sieveactexp'] = 'Por favor, selecione uma das opções abaixo. Essas ações serão realizadas para qualquer mensagem correspondente à(s) regra(s) acima.';
+$messages['sieveheadershlp'] = 'Abaixo estão alguns exemplos de outros cabeçalhos que podem ser testados pelos filtros. Selecione um cabeçalho para adicioná-lo à regra, ou introduza um personalizado na caixa acima.';
+$messages['movingfilter'] = 'Movendo filtro...';
+$messages['noexistingfilters'] = 'Não foi detectado nenhum filtro existente!';
+$messages['importdefault'] = '<b>Usar filtros predefinidos:</b> Há um conjunto de filtros predefinidos disponíveis. Gostaria de usar esses filtros?';
+$messages['importother'] = '<b>Importação de filtros:</b>Foi encontrado outro conjunto de filtros de %s. Gostaria de importar esses filtros para o seu conjunto actual?';
+$messages['switchtoadveditor'] = 'Mudando para o editor avançado é possível editar o arquivo Sieve diretamente. Quaisquer alterações aqui efetuadas podem ser ilegíveis no editor normal e podem ser perdidas quando os filtros são guardados usando o editor normal. Deseja continuar?';
+$messages['filterimported'] = 'Filtro importado com sucesso';
+$messages['filterimporterror'] = 'Não foi possível importar o filtro. Ocorreu um erro no servidor.';
+$messages['notifyinvalidmethod'] = 'O método parece não estar escrito num formato válido, ele deve ser uma URL. Por exemplo: "mailto: alert@example.com».';
+$messages['nobodycontentpart'] = 'Por favor, indique uma parte de conteúdo para testar';
+$messages['badoperator'] = 'O operador seleccionado não pode ser usado nesta regra';
+$messages['filteractionerror'] = 'A ação solicitada não é suportada pelo servidor';
+$messages['filtermissingerror'] = 'Não foi possível encontrar a regra solicitada';
+$messages['contentpartexp'] = 'O tipo de MIME ou parte específica da mensagem que deve ser testado. Por exemplo: `text/html`, `audio/mp3` or `image`.';
+$messages['delrulesetconf'] = 'Tem certeza que quer eliminar este conjunto de regras?';
+$messages['rulesetexists'] = 'Um conjunto de regras com este nome já existe. Por favor, indique outro nome';
+$messages['copyexisting'] = '<b>Copiar conjunto de regras existente:</b>Gostaria de copiar os filtros de um conjunto de de regras existente para o seu conjunto actual?';
+$messages['filtercopied'] = 'Filtro copiado com sucesso';
+$messages['nosieverulesets'] = 'Nenhum conjunto de regras encontrado.';
+$messages['baddateformat'] = 'Erro: Indique a data no formato AAAA-MM-DD';
+$messages['badtimeformat'] = 'Erro: Indique a hora no formato HH:MM:SS';
+
+?> \ No newline at end of file
diff --git a/plugins/sieverules/localization/pt_PT.inc b/plugins/sieverules/localization/pt_PT.inc
new file mode 100644
index 000000000..5b3dffc24
--- /dev/null
+++ b/plugins/sieverules/localization/pt_PT.inc
@@ -0,0 +1,183 @@
+<?php
+/* Author: Ling Fude */
+
+$labels = array();
+$labels['filters'] = 'Filtros';
+$labels['managefilters'] = 'Gerir filtros';
+$labels['filtername'] = 'Nome do filtro';
+$labels['disablerule'] = 'Desactivar regra';
+$labels['disabled'] = 'Desactivado';
+$labels['newfilter'] = 'Novo filtro';
+$labels['moveup'] = 'Mover para cima';
+$labels['movedown'] = 'Mover para baixo';
+$labels['filterallof'] = 'corresponde a todas as seguintes regras';
+$labels['filteranyof'] = 'corresponde a uma das seguintes regras';
+$labels['filterany'] = 'todas as mensagens';
+$labels['filtercontains'] = 'contém';
+$labels['filternotcontains'] = 'não contém';
+$labels['filteris'] = 'é igual a';
+$labels['filterisnot'] = 'é diferente de';
+$labels['filterexists'] = 'existe';
+$labels['filternotexists'] = 'não existe';
+$labels['filterregex'] = 'corresponde à expressão';
+$labels['filternotregex'] = 'não corresponde à expressão';
+$labels['filterunder'] = 'é inferior a';
+$labels['filterover'] = 'é superior a';
+$labels['filterbefore'] = 'é antes';
+$labels['filterafter'] = 'é depois';
+$labels['filteradvoptions'] = 'mais opções...';
+$labels['spamtest'] = 'Probabilidade de Spam';
+$labels['operator'] = 'Operador';
+$labels['comparator'] = 'Comparador';
+$labels['isgreaterthan'] = 'é maior que';
+$labels['isgreaterthanequal'] = 'é maior ou igual a';
+$labels['islessthan'] = 'é menor que';
+$labels['islessthanequal'] = 'é menor ou igual a';
+$labels['equals'] = 'é igual a';
+$labels['notequals'] = 'é diferente de';
+$labels['countisgreaterthan'] = 'contagem é maior que';
+$labels['countisgreaterthanequal'] = 'contagem é maior ou igual a';
+$labels['countislessthan'] = 'contagem é menor que';
+$labels['countislessthanequal'] = 'contagem é menor ou igual a';
+$labels['countequals'] = 'contagem é igual a';
+$labels['countnotequals'] = 'contagem é diferente de';
+$labels['valueisgreaterthan'] = 'valor é maior que';
+$labels['valueisgreaterthanequal'] = 'valor é maior ou igual a';
+$labels['valueislessthan'] = 'valor é menor que';
+$labels['valueislessthanequal'] = 'valor é menor ou igual a';
+$labels['valueequals'] = 'valor é igual a';
+$labels['valuenotequals'] = 'valor diferente de';
+$labels['userpart'] = 'parte do utilizador igual a';
+$labels['notuserpart'] = 'parte do utilizador diferente de';
+$labels['detailpart'] = 'parte do detalhe igual a';
+$labels['notdetailpart'] = 'parte do detalhe diferente de';
+$labels['domainpart'] = 'parte do domínio igual a';
+$labels['notdomainpart'] = 'parte do domínio diferente de';
+$labels['teststring'] = 'Texto de teste';
+$labels['messagemoveto'] = 'Mover mensagem para';
+$labels['messageredirect'] = 'Redirecionar mensagem para';
+$labels['messageimapflags'] = 'Marcar mensagem como';
+$labels['messagereject'] = 'Rejeitar com a mensagem';
+$labels['messagevacation'] = 'Mensagem Fora do Escritório';
+$labels['messagekeep'] = 'Manter mensagem';
+$labels['messagediscard'] = 'Rejeitar mensagem';
+$labels['messagenotify'] = 'Enviar notificação';
+$labels['messagestop'] = 'Parar o processamento de filtros';
+$labels['messagehelp'] = 'O que é isto?';
+$labels['sieveorigsubj'] = 'Acrescentar assunto original à resposta';
+$labels['sievevachandle'] = 'Identificador';
+$labels['method'] = 'Método';
+$labels['options'] = 'Opções';
+$labels['messagesrules'] = 'Regras para Filtros';
+$labels['messagesactions'] = 'Acções para Filtros';
+$labels['sieveto'] = 'Alias';
+$labels['sievefrom'] = 'De';
+$labels['flag'] = 'Importância';
+$labels['importancen'] = 'Nenhum';
+$labels['importance1'] = 'Alta';
+$labels['importance2'] = 'Normal';
+$labels['importance3'] = 'Baixa';
+$labels['flagread'] = 'Lida';
+$labels['flagdeleted'] = 'Eliminada';
+$labels['flaganswered'] = 'Respondida';
+$labels['flagdraft'] = 'Rascunho';
+$labels['flagflagged'] = 'Marcada';
+$labels['addsieverule'] = 'Adicionar outra regra, depois desta';
+$labels['addsieveact'] = 'Adicionar outra acção, depois desta';
+$labels['deletesieverule'] = 'Eliminar esta regra';
+$labels['deletesieveact'] = 'Eliminar esta acção';
+$labels['envelopefrom'] = 'Envelope De';
+$labels['envelopeto'] = 'Envelope Para';
+$labels['otherheader'] = 'Outro cabeçalho';
+$labels['days'] = 'Periodo';
+$labels['message'] = 'Mensagem';
+$labels['sieveruleheaders'] = 'Ver exemplos de outros cabecalhos';
+$labels['examplefilters'] = 'Exemplo de Filtros';
+$labels['importfilters'] = 'Importar Filtros';
+$labels['usedefaultfilter'] = 'Usar filtros predefinidos';
+$labels['importfilter'] = 'Importar filtros';
+$labels['moreactions'] = 'Mais opções...';
+$labels['adveditor'] = 'Editor avançado';
+$labels['stdeditor'] = 'Editor padrão';
+$labels['messageredirectcopy'] = 'Enviar cópia para';
+$labels['messagecopyto'] = 'Copiar mensagem para';
+$labels['body'] = 'Corpo';
+$labels['auto'] = 'Auto';
+$labels['raw'] = 'Raw';
+$labels['text'] = 'Texto';
+$labels['other'] = 'Outro';
+$labels['bodycontentpart'] = 'Parte Conteúdo';
+$labels['notchecked'] = 'não verificado';
+$labels['spamlevelisgreaterthanequal'] = 'é maior ou igual a';
+$labels['spamlevelislessthanequal'] = 'é menor ou igual a';
+$labels['spamlevelequals'] = 'é igual a';
+$labels['i;ascii-casemap'] = 'correspondência de texto indeferente a maiúsculas e minúsculas';
+$labels['i;octet'] = 'correspondência exacta do texto';
+$labels['i;ascii-numeric'] = 'correspondência numérica';
+$labels['selectruleset'] = 'Seleccionar conjunto de regras';
+$labels['activeruleset'] = '%s (activo)';
+$labels['activateruleset'] = 'Activar este conjunto de regras';
+$labels['newruleset'] = 'Criar um no grupo de regras';
+$labels['delruleset'] = 'Eliminar este conjunto de regras';
+$labels['renameruleset'] = 'Renomear este conjunto de regras';
+$labels['copy'] = 'Copiar';
+$labels['copyexistingfilter'] = 'Copiar filtros existentes';
+$labels['copytoruleset'] = 'Copiar o filtro para outro conjunto de regras';
+$labels['copyfromruleset'] = 'Copiar filtros de um conjunto regras existente';
+$labels['time'] = 'Tempo';
+$labels['weekday'] = 'dia da semana';
+
+$messages = array();
+$messages['nosieverules'] = 'Nenhum filtro encontrado.';
+$messages['filterdeleteconfirm'] = 'Tem a certeza que pretende eliminar este filtro?';
+$messages['ruledeleteconfirm'] = 'Tem a certeza que pretende eliminar esta regra?';
+$messages['actiondeleteconfirm'] = 'Tem a certeza que pretende eliminar esta acção?';
+$messages['filterunknownerror'] = 'Erro de servidor desconhecido';
+$messages['filterconnerror'] = 'Não é possível ligar ao servidor Sieve';
+$messages['filterdeleteerror'] = 'Não foi possível eliminar o filtro. Erro no servidor';
+$messages['filterdeleted'] = 'Filtro eliminado com sucesso';
+$messages['filtersaved'] = 'Filtro guardado com sucesso';
+$messages['filtersaveerror'] = 'Não foi possível guardar o filtro. Erro no servidor';
+$messages['vacdaysexp'] = 'O período é o número de dias durante o qual a mensagem não será reenviado para o mesmo remetente, não importa quantas vezes ele entre contacto consigo.<br/><br/>Por exemplo: Se o João lhe enviar e-mails na segunda-feira e o período está definido para 7 dias, o João irá receber uma mensagem de Fora do Escritório na segunda-feira, mas não irá receber mais nenhuma até à segunda-feira seguinte, não importa quantos e-mails ele lhe envie durante a semana.';
+$messages['vachandleexp'] = 'Um identificador pode ser usado para ligar as diferentes mensagens de Fora do Escritório em conjunto, uma vez que uma mensagem for enviada nenhuma outra mensagem com o mesmo identificador será enviada no mesmo período.';
+$messages['vactoexp'] = 'Lista de endereços de destinatários adicionais que estão incluídos na resposta automática. Se um destinatário de e-mail não é o seu endereço principal e não está nesta lista, nenhuma mensagem será enviada.';
+$messages['norulename'] = 'Por favor, indique um nome para este filtro';
+$messages['ruleexists'] = 'Já existe um filtro com este nome. Por favor, indique outro';
+$messages['noheader'] = 'Por favor, indique o nome do cabeçalho para testar';
+$messages['headerbadchars'] = 'Erro: O cabeçalho contém caracteres proibidos';
+$messages['noheadervalue'] = 'Por favor indique um valor para testar o cabeçalho contra';
+$messages['sizewrongformat'] = 'Erro: O tamanho da mensagem deve ser numérico';
+$messages['noredirect'] = 'Indique um endereço de e-mail para redirecionar as mensagens';
+$messages['redirectaddresserror'] = 'Erro: O endereço de e-mail parece ser inválido';
+$messages['noreject'] = 'Indique uma mensagem para enviar juntamente com o e-mail rejeitado';
+$messages['vacnodays'] = 'Por favor insira um número de dias para o período em que a mensagem não será reenviado para a mesma pessoa';
+$messages['vacdayswrongformat'] = 'Erro: O período deve ser um número maior ou igual a 1';
+$messages['vacnomsg'] = 'Insira o texto para a sua mensagem';
+$messages['notifynomethod'] = 'Por favor, indique um método pelo qual a notificação deve ser enviada';
+$messages['notifynomsg'] = 'Insira o texto para a sua mensagem';
+$messages['sieveruleexp'] = 'Por favor, defina uma ou mais regras sobre as quais cada mensagem será testada. Os filtros são executados na ordem em que aparecem à esquerda do ecrã, se for encontrada uma correspondência mais nenhum filtro será testado.';
+$messages['sieveruleexp_stop'] = 'Por favor, defina uma ou mais regras sobre as quais cada mensagem será testada. Os filtros são executados na ordem em que aparecem à esquerda do ecrã até uma acção de \'Stop\' ser encontrada.';
+$messages['sieveactexp'] = 'Por favor, seleccione uma das opções abaixo. Essas acções serão realizadas para qualquer mensagem correspondente à(s) regra(s) acima.';
+$messages['sieveheadershlp'] = 'Abaixo estão alguns exemplos de outros cabeçalhos que podem ser testados pelos filtros. Selecione um cabeçalho para adicioná-lo à regra, ou introduza um personalizado na caixa acima.';
+$messages['movingfilter'] = 'A mover filtro...';
+$messages['noexistingfilters'] = 'Não foi detectado nenhum filtro existente!';
+$messages['importdefault'] = '<b>Usar filtros predefinidos:</b> Há um conjunto de filtros predefinidos disponíveis. Gostaria de usar esses filtros?';
+$messages['importother'] = '<b>Importação de filtros:</b>Foi encontrado outro conjunto de filtros de %s. Gostaria de importar esses filtros para o seu conjunto actual?';
+$messages['switchtoadveditor'] = 'Mudando para o editor avançado permite editar o ficheiro Sieve directamente. Quaisquer alterações aqui efectuadas podem ser ilegíveis no editor normal e podem ser perdidas quando os filtros são guardados usando o editor normal. Deseja continuar?';
+$messages['filterimported'] = 'Filtro importado com sucesso';
+$messages['filterimporterror'] = 'Não foi possível importar o filtro. Ocorreu um erro no servidor.';
+$messages['notifyinvalidmethod'] = 'O método parece não estar escrito num formato válido, ele deve ser um URL. Por exemplo: "mailto: alert@example.com».';
+$messages['nobodycontentpart'] = 'Por favor, indique uma parte de conteúdo para testar';
+$messages['badoperator'] = 'O operador seleccionado não pode ser usado nesta regra';
+$messages['filteractionerror'] = 'A acção solicitada não é suportada pelo servidor';
+$messages['filtermissingerror'] = 'Não foi possível encontrar a regra solicitada';
+$messages['contentpartexp'] = 'O tipo de MIME ou parte específica da mensagem que deve ser testado. Por exemplo: `text/html`, `audio/mp3` or `image`.';
+$messages['delrulesetconf'] = 'Tem certeza que quer eliminar este conjunto de regras?';
+$messages['rulesetexists'] = 'Um conjunto de regras com este nome já existe. Por favor, indique outro nome';
+$messages['copyexisting'] = '<b>Copiar conjunto de regras existente:</b>Gostaria de copiar os filtros de um conjunto de de regras existente para o seu conjunto actual?';
+$messages['filtercopied'] = 'Filtro copiado com sucesso';
+$messages['nosieverulesets'] = 'Nenhum conjunto de regras encontrado.';
+$messages['baddateformat'] = 'Erro: Indique a data no formato AAAA-MM-DD';
+$messages['badtimeformat'] = 'Erro: Indique a hora no formato HH:MM:SS';
+
+?> \ No newline at end of file
diff --git a/plugins/sieverules/localization/ro_RO.inc b/plugins/sieverules/localization/ro_RO.inc
new file mode 100644
index 000000000..f8dce4c02
--- /dev/null
+++ b/plugins/sieverules/localization/ro_RO.inc
@@ -0,0 +1,175 @@
+<?php
+/* Author: Ovidiu Bica */
+
+$labels = array();
+$labels['filters'] = 'Filtre';
+$labels['managefilters'] = 'Administrează filtrele';
+$labels['filtername'] = 'Nume filtru';
+$labels['disablerule'] = 'Dezactivează regula';
+$labels['disabled'] = 'Dezactivat';
+$labels['newfilter'] = 'Filtru nou';
+$labels['moveup'] = 'Mută sus';
+$labels['movedown'] = 'Mută jos';
+$labels['filterallof'] = 'îndeplineşte toate regulile de mai jos';
+$labels['filteranyof'] = 'îndeplineşte oricare regula de mai jos';
+$labels['filterany'] = 'toate mesajele';
+$labels['filtercontains'] = 'conţine';
+$labels['filternotcontains'] = 'nu conţine';
+$labels['filteris'] = 'este egal cu';
+$labels['filterisnot'] = 'nu este egal cu';
+$labels['filterexists'] = 'există';
+$labels['filternotexists'] = 'nu există';
+$labels['filterregex'] = 'indeplineşte expresia';
+$labels['filternotregex'] = 'nu indeplineşte expresia';
+$labels['filterunder'] = 'este mai puţin de';
+$labels['filterover'] = 'este mai mult de';
+$labels['filteradvoptions'] = 'mai multe opţiuni';
+$labels['spamtest'] = 'Probabilitate de spam';
+$labels['operator'] = 'Operator';
+$labels['comparator'] = 'Comparator';
+$labels['isgreaterthan'] = 'este mai mare de';
+$labels['isgreaterthanequal'] = 'este mai mare sau egal cu';
+$labels['islessthan'] = 'este mai mic de';
+$labels['islessthanequal'] = 'este mai mic sau egal cu';
+$labels['equals'] = 'este egal cu';
+$labels['notequals'] = 'nu este egal';
+$labels['countisgreaterthan'] = 'numărul este mai mare de';
+$labels['countisgreaterthanequal'] = 'numărul este mai mare sau egal cu';
+$labels['countislessthan'] = 'numărul este mai mic de';
+$labels['countislessthanequal'] = 'numărul este mai mic sau egal cu';
+$labels['countequals'] = 'numărul este egal cu';
+$labels['countnotequals'] = 'numărul nu este egal cu';
+$labels['valueisgreaterthan'] = 'valoarea este mai mare de';
+$labels['valueisgreaterthanequal'] = 'valoarea este mai mare sau egală cu';
+$labels['valueislessthan'] = 'valoarea este mai mică de';
+$labels['valueislessthanequal'] = 'valoarea este mai mică sau egală cu';
+$labels['valueequals'] = 'valoarea este egala cu';
+$labels['valuenotequals'] = 'valoarea nu este egală';
+$labels['userpart'] = 'utilizatorul este';
+$labels['notuserpart'] = 'utilizatorul nu este';
+$labels['detailpart'] = 'detaliul este';
+$labels['notdetailpart'] = 'detaliul nu este';
+$labels['domainpart'] = 'domeniul este';
+$labels['notdomainpart'] = 'domeniul nu este';
+$labels['teststring'] = 'mesaj de test';
+$labels['messagemoveto'] = 'Mută mesajul în';
+$labels['messageredirect'] = 'Redirectionează mesajul la';
+$labels['messageimapflags'] = 'Marchează mesajul ca';
+$labels['messagereject'] = 'Refuză mesajul cu';
+$labels['messagevacation'] = 'Mesaj - Plecat din birou';
+$labels['messagekeep'] = 'Păastrează mesajul';
+$labels['messagediscard'] = 'Refuză mesajul';
+$labels['messagenotify'] = 'Trimite notificare';
+$labels['messagestop'] = 'Opreşte procesarea filtrelor';
+$labels['messagehelp'] = 'Ce este asta?';
+$labels['sieveorigsubj'] = 'Atasează subiectul original la răspuns';
+$labels['sievevachandle'] = 'Foloseşte';
+$labels['method'] = 'Metodă';
+$labels['options'] = 'Opţiuni';
+$labels['messagesrules'] = 'Reguli filtrare';
+$labels['messagesactions'] = 'Acţiuni filtrare';
+$labels['sieveto'] = 'Sinonime';
+$labels['sievefrom'] = 'De la';
+$labels['flag'] = 'Importanţă';
+$labels['importancen'] = 'Nici unul';
+$labels['importance1'] = 'Mare';
+$labels['importance2'] = 'Normal';
+$labels['importance3'] = 'Scăzut';
+$labels['flagread'] = 'Citit';
+$labels['flagdeleted'] = 'Şters';
+$labels['flaganswered'] = 'Răspuns';
+$labels['flagdraft'] = 'Ciornă';
+$labels['flagflagged'] = 'Marcat';
+$labels['addsieverule'] = 'Adaugă o nouă regulă sub aceasta';
+$labels['addsieveact'] = 'Adaugă o nouă acţiune sub aceasta';
+$labels['deletesieverule'] = 'Şterge această regulă';
+$labels['deletesieveact'] = 'Şterge această acţiune';
+$labels['envelopefrom'] = 'Mesaj de la';
+$labels['envelopeto'] = 'Mesaj către';
+$labels['otherheader'] = 'Alt cuprins';
+$labels['days'] = 'Perioadă';
+$labels['message'] = 'Mesaj';
+$labels['sieveruleheaders'] = 'Vezi exemple de alte cuprinsuri';
+$labels['examplefilters'] = 'Exemple de filtre';
+$labels['importfilters'] = 'Importa filtre';
+$labels['usedefaultfilter'] = 'Foloseste filtre implicite';
+$labels['importfilter'] = 'Importa filtru';
+$labels['adveditor'] = 'Editor avansat';
+$labels['messageredirectcopy'] = 'Trimite o copie către';
+$labels['messagecopyto'] = 'Copiază mesajul către';
+$labels['body'] = 'Conţinut';
+$labels['auto'] = 'Auto';
+$labels['raw'] = 'Brut';
+$labels['text'] = 'Text';
+$labels['other'] = 'Altul';
+$labels['bodycontentpart'] = 'Conţinut';
+$labels['notchecked'] = 'neverificat';
+$labels['spamlevelisgreaterthanequal'] = 'este mai mare sau egal cu';
+$labels['spamlevelislessthanequal'] = 'este mai mic sau egal cu';
+$labels['spamlevelequals'] = 'este egal cu';
+$labels['i;ascii-casemap'] = 'potrivire caractere mici/mari';
+$labels['i;octet'] = 'potrivire exactă';
+$labels['i;ascii-numeric'] = 'potrivire numerică';
+$labels['selectruleset'] = 'Selectează setul de reguli';
+$labels['activeruleset'] = '%s (activ)';
+$labels['activateruleset'] = 'Activează acest set de reguli';
+$labels['newruleset'] = 'Crează un nou set de reguli';
+$labels['delruleset'] = 'Sterge acest set de reguli';
+$labels['renameruleset'] = 'Redenumeşte acest set de reguli';
+$labels['copy'] = 'Copiază';
+$labels['copyexistingfilter'] = 'Copiază filtre existente';
+$labels['copytoruleset'] = 'Copiază filtrul la un alt set de reguli';
+$labels['copyfromruleset'] = 'Copiază filtrele de la un set de reguli existent';
+
+$messages = array();
+$messages['nosieverules'] = 'Nu a fost găsit niciun filtru.';
+$messages['filterdeleteconfirm'] = 'Eşti sigur că doreşti să ştergi acest filtru?';
+$messages['ruledeleteconfirm'] = 'Eşti sigur că doreşti să ştergi această regulă?';
+$messages['actiondeleteconfirm'] = 'Eşti sigur că doreşti să ştergi această acţiune?';
+$messages['filterunknownerror'] = 'Eroare de server necunoscută.';
+$messages['filterconnerror'] = 'Nu m-am putut conecta la serverul Sieve.';
+$messages['filterdeleteerror'] = 'Nu am putut şterge filtrul. Eroare de server.';
+$messages['filterdeleted'] = 'Filtru şters cu succes.';
+$messages['filtersaved'] = 'Filtru salvat cu succes.';
+$messages['filtersaveerror'] = 'Nu am putut salva filtrul. Eroare de server.';
+$messages['vacdaysexp'] = 'Perioada este numărul de zile în care mesajul nu va fi retrimis persoanei indiferent de câte ori te va contacta.<br /><br />De exemplu: Dacă Ion iţi trimite un email luni şi perioada este setată la 7 zile, atunci Ion va primi un mesaj OUT of OFFICE luni însă nu va mai primi niciunul pana lunea următoare indiferent de câte mesaje îţi va trimite.';
+$messages['vachandleexp'] = 'Poate fi folosită o regulă pentru a lega mesaje OUT of OFFICE împreună. Odată trimis un mesaj, nu va mai fi trimis niciun mesaj cu aceeasi regulă.';
+$messages['vactoexp'] = 'Lista adreselor de email aditionale care vor fi incluse in raspunsul automat. ';
+$messages['norulename'] = 'Te rog sa introduci un nume pentru acest filtru.';
+$messages['ruleexists'] = 'Un filtru cu acest nume există deja. Te rog să introduci altul.';
+$messages['noheader'] = 'Te rog să introduci numele headerului pentru verificare.';
+$messages['headerbadchars'] = 'Eroare: Headerul conţine caractere ilegale.';
+$messages['noheadervalue'] = 'Te rog să introduci o valoare pentru a testa headerul.';
+$messages['sizewrongformat'] = 'Eroare: Mărimea mesajului trebuie să fie numerică .';
+$messages['noredirect'] = 'Te rog să introduci o adresă de email pentru a redirecţiona mesajele.';
+$messages['redirectaddresserror'] = 'Eroare: Adresa nu pare să fie validă.';
+$messages['noreject'] = 'Te rog să introduci un mesaj pentru a fi trimis impreună cu mesajul de respingere.';
+$messages['vacnodays'] = 'Te rog să introduci o perioadă de zile în care mesaju';
+$messages['vacdayswrongformat'] = 'Eroare: Perioada trebuie să fie un număr mai mare sau egal cu 1.';
+$messages['vacnomsg'] = 'Te rog să introduci un text pentru mesaj.';
+$messages['notifynomethod'] = 'Te rog să introduci o metodă prin care să se trimită notificarea.';
+$messages['notifynomsg'] = 'Te rog să introduci un text pentru mesaj.';
+$messages['sieveruleexp'] = 'Te rog să introduci una sau mai multe reguli prin care va fi testat fiecare mesaj. Filtrele sunt aplicate în ordinea în care apar în stânga ecranului. Dacă este găsită o potrivire, niciun alt filtru nu va mai fi testat.';
+$messages['sieveruleexp_stop'] = 'Te rog să introduci una sau mai multe reguli prin care va fi testat fiecare mesaj. Filtrele sunt aplicate în ordinea în care apar în stânga ecranului până câand este găsită o acţiune de stopare.';
+$messages['sieveactexp'] = 'Te rog sa selectezi una din opţiunile de mai jos. Aceste acţiuni vor fi efectuate pentru orice mesaj ce se potriveşte regulilor de mai jos.';
+$messages['sieveheadershlp'] = 'Mai jos aveţi exemple de alte headere ce pot fi testate de către filtre. Selectează un header pentru a-l adăuga la regulă sau introdu una proprie în câmpul de mai sus.';
+$messages['movingfilter'] = 'Se mută filtrul ...';
+$messages['noexistingfilters'] = 'Nici un filtru existent ...';
+$messages['importdefault'] = '<b>Foloseşte filtrele implicite:</b>Există un set de filtre implicite. Doreşti să foloseşti aceste filtre?';
+$messages['importother'] = '<b>Importă filtre</b> Un alt set de filtre de la %s a fost găsit. Doreşti să imporţi aceste filtre in setul tău curent?';
+$messages['switchtoadveditor'] = 'Trecerea la editorul avansat iti permite să editezi fişierul sieve direct. Orice modificare faci aici poate fi de nedescifrat in editorul normal si poate fi pierdută atunci când filtrele sunt salvate folosind editorul normal. Doreşti să continui?';
+$messages['filterimported'] = 'Filtrul importat cu succes?';
+$messages['filterimporterror'] = 'Imposibil de importat filtrul. Eroare de server.';
+$messages['notifyinvalidmethod'] = 'Metoda nu pare a fi scrisă într-un format valid, trebuie să fie un URL. De ex. `mailto:ion@exemplu.com`';
+$messages['nobodycontentpart'] = 'Te rog să introduci un conţinut de probă.';
+$messages['badoperator'] = 'Îmi pare rău, operatorul selectat nu poate fi folosit în această regulă.';
+$messages['filteractionerror'] = 'Acţiunea cerută nu este suportată de server.';
+$messages['filtermissingerror'] = 'Imposibil de găsit regula cerută.';
+$messages['contentpartexp'] = 'Tipul MIME-Type sau o parte specifica din mesajul ce trebuie testat. De ex. `message/rfc822`, `text/html`, `audio/mp3` sau `image`.';
+$messages['delrulesetconf'] = 'Eşti sigur că doreşti să ştergi acest set de reguli?';
+$messages['rulesetexists'] = 'Un set de reguli cu acest nume există deja. Introdu altul.';
+$messages['copyexisting'] = '<b>Copiază setul de reguli existent:</b> Doreşti să copiezi filtrele dintr-un set de reguli existent in setul tău curent?';
+$messages['filtercopied'] = 'Filtrul copiat cu succes.';
+$messages['nosieverulesets'] = 'Niciun set de reguli găsit.';
+
+?> \ No newline at end of file
diff --git a/plugins/sieverules/localization/ru_RU.inc b/plugins/sieverules/localization/ru_RU.inc
new file mode 100644
index 000000000..12aaeea53
--- /dev/null
+++ b/plugins/sieverules/localization/ru_RU.inc
@@ -0,0 +1,182 @@
+<?php
+/* Author: Peter Zotov */
+
+$labels = array();
+$labels['filters'] = 'Фильтры';
+$labels['managefilters'] = 'управление фильтрами';
+$labels['filtername'] = 'Имя фильтра';
+$labels['disablerule'] = 'отключить правило';
+$labels['disabled'] = 'отключено';
+$labels['newfilter'] = 'Новый фильтр';
+$labels['moveup'] = 'вверх';
+$labels['movedown'] = 'вниз';
+$labels['filterallof'] = 'соответствует всем правилам';
+$labels['filteranyof'] = 'соответствует хотя бы одному из правил';
+$labels['filterany'] = 'все сообщения';
+$labels['filtercontains'] = 'содержит';
+$labels['filternotcontains'] = 'не содержит';
+$labels['filteris'] = 'совпадает с';
+$labels['filterisnot'] = 'не совпадает с';
+$labels['filterexists'] = 'существует';
+$labels['filternotexists'] = 'не существует';
+$labels['filterregex'] = 'соответствует регулярному выражению';
+$labels['filternotregex'] = 'не соответствует регулярному выражению';
+$labels['filterunder'] = 'меньше чем';
+$labels['filterover'] = 'больше чем';
+$labels['filterbefore'] = 'до';
+$labels['filterafter'] = 'после';
+$labels['filteradvoptions'] = 'другие...';
+$labels['spamtest'] = 'Вероятность спама';
+$labels['operator'] = 'Условие';
+$labels['comparator'] = 'Сравнение';
+$labels['isgreaterthan'] = 'больше чем';
+$labels['isgreaterthanequal'] = 'больше чем или равен';
+$labels['islessthan'] = 'меньше чем';
+$labels['islessthanequal'] = 'меньше чем или равен';
+$labels['equals'] = 'равен';
+$labels['notequals'] = 'не равен';
+$labels['countisgreaterthan'] = 'количество больше чем';
+$labels['countisgreaterthanequal'] = 'количество больше чем или равно';
+$labels['countislessthan'] = 'количество меньше чем';
+$labels['countislessthanequal'] = 'количество меньше чем или равно';
+$labels['countequals'] = 'количество равно';
+$labels['countnotequals'] = 'количество не равно';
+$labels['valueisgreaterthan'] = 'значение больше чем';
+$labels['valueisgreaterthanequal'] = 'значение больше чем или равно';
+$labels['valueislessthan'] = 'значение меньше чем';
+$labels['valueislessthanequal'] = 'значение меньше чем или равно';
+$labels['valueequals'] = 'значение равно';
+$labels['valuenotequals'] = 'значение не равно';
+$labels['userpart'] = 'имя пользователя (перед \'@\' или \'+\') равно';
+$labels['notuserpart'] = 'имя пользователя не равно';
+$labels['detailpart'] = 'часть имени после \'+\' равна';
+$labels['notdetailpart'] = 'часть имени после \'+\' не равна';
+$labels['domainpart'] = 'имя домена (после \'@\') равно';
+$labels['notdomainpart'] = 'имя домена не равно';
+$labels['teststring'] = 'Сравнить со строкой';
+$labels['messagemoveto'] = 'переместить сообщения в';
+$labels['messageredirect'] = 'перенаправить сообщения на адрес';
+$labels['messageimapflags'] = 'пометить сообщения как';
+$labels['messagereject'] = 'отклонить с сообщением';
+$labels['messagevacation'] = 'сообщение "Нет на месте"';
+$labels['messagekeep'] = 'сохранить сообщение';
+$labels['messagediscard'] = 'отклонить сообщение';
+$labels['messagenotify'] = 'отправить уведомление';
+$labels['messagestop'] = 'прекратить обработку фильтров';
+$labels['messagehelp'] = 'Что это?';
+$labels['sieveorigsubj'] = 'Добавить тему исходного сообщения к ответу';
+$labels['sievevachandle'] = 'Метка';
+$labels['method'] = 'Способ';
+$labels['options'] = 'Параметры';
+$labels['messagesrules'] = 'Правила фильтра';
+$labels['messagesactions'] = 'Действия фильтра';
+$labels['sieveto'] = 'Адреса';
+$labels['sievefrom'] = 'От';
+$labels['flag'] = 'Важность';
+$labels['importancen'] = 'не указана';
+$labels['importance1'] = 'высокая';
+$labels['importance2'] = 'обычная';
+$labels['importance3'] = 'низкая';
+$labels['flagread'] = 'прочитано';
+$labels['flagdeleted'] = 'удалено';
+$labels['flaganswered'] = 'ответ написан';
+$labels['flagdraft'] = 'черновик';
+$labels['flagflagged'] = 'помечено';
+$labels['addsieverule'] = 'добавить правило';
+$labels['addsieveact'] = 'добавить дополнительное действие';
+$labels['deletesieverule'] = 'удалить правило';
+$labels['deletesieveact'] = 'удалить действие';
+$labels['otherheader'] = 'Другой заголовок';
+$labels['days'] = 'Периодичность';
+$labels['message'] = 'Сообщение';
+$labels['sieveruleheaders'] = 'посмотреть примеры других заголовков';
+$labels['examplefilters'] = 'Примеры фильтров';
+$labels['importfilters'] = 'Импорт фильтров';
+$labels['usedefaultfilter'] = 'Использовать фильтры по умолчанию';
+$labels['importfilter'] = 'Импортировать фильтры';
+$labels['moreactions'] = 'Другие варианты...';
+$labels['adveditor'] = 'Расширенный редактор';
+$labels['stdeditor'] = 'Стандартный редактор';
+$labels['messageredirectcopy'] = 'отослать копию на адрес';
+$labels['messagecopyto'] = 'сохранить копию в папку';
+$labels['body'] = 'Тело сообщения';
+$labels['auto'] = 'автоматически';
+$labels['raw'] = 'в исходнике';
+$labels['text'] = 'в тексте';
+$labels['other'] = 'часть сообщения';
+$labels['bodycontentpart'] = 'MIME-тип части сообщения';
+$labels['notchecked'] = 'не проверено';
+$labels['spamlevelisgreaterthanequal'] = 'больше чем или равна';
+$labels['spamlevelislessthanequal'] = 'меньше чем или равна';
+$labels['spamlevelequals'] = 'равна';
+$labels['i;ascii-casemap'] = 'сравнение строк без учета регистра';
+$labels['i;octet'] = 'точное сравнение строк';
+$labels['i;ascii-numeric'] = 'числовое сравнение';
+$labels['selectruleset'] = 'Выбрать набор правил';
+$labels['activeruleset'] = '%s (активный)';
+$labels['activateruleset'] = 'Активировать набор правил';
+$labels['newruleset'] = 'Создать набор правил';
+$labels['delruleset'] = 'Удалить набор правил';
+$labels['renameruleset'] = 'Переименовать набор правил';
+$labels['copy'] = 'Скопировать';
+$labels['copyexistingfilter'] = 'Скопировать существующие фильтры';
+$labels['copytoruleset'] = 'Скопировать фильтры в другой набор';
+$labels['copyfromruleset'] = 'Скопировать фильтры из существующего набора';
+$labels['time'] = 'Время';
+$labels['weekday'] = 'День недели';
+
+$messages = array();
+$messages['nosieverules'] = 'Фильтры не найдены.';
+$messages['filterdeleteconfirm'] = 'Вы уверены, что хотите удалить этот фильтр?';
+$messages['ruledeleteconfirm'] = 'Вы уверены, что хотите удалить это правило?';
+$messages['actiondeleteconfirm'] = 'Вы уверены, что хотите удалить это действие?';
+$messages['filterunknownerror'] = 'Неизвестная ошибка сервера.';
+$messages['filterconnerror'] = 'Невозможно соединиться с сервером sieve.';
+$messages['filterdeleteerror'] = 'Невозможно удалить фильтр. Возникла ошибка сервера.';
+$messages['filterdeleted'] = 'Фильтр успешно удален.';
+$messages['filtersaved'] = 'Фильтр успешно сохранен.';
+$messages['filtersaveerror'] = 'Невозможно сохранить фильтр. Возникла ошибка сервера.';
+$messages['vacdaysexp'] = 'Количество дней, в течение которого корреспонденты не будут получать повторные сообщения об вашем отсутствии, вне зависимости от того, сколько раз они вам написали за это время.<br /><br />Например: Если Вася написал вам письмо в понедельник и вы установили периодичность в 7 (дней), то Вася получит сообщение о Вашем отсутствии в понедельник, и больше не будет получать таких сообщений до следующего понедельника, даже если он писал вам много раз.';
+$messages['vachandleexp'] = 'Метка связывает несколько сообщений об отсутствии вместе: после того, как одно из них было отправлено, другие сообщения с той же меткой не будут отправляться в течение этого периода..';
+$messages['vactoexp'] = 'Список дополнительных адресов получателей, для которых будет работать "автоответчик". Ответы не будут отправляться, если адреса получателя принятого сообщения нет в этом списке.';
+$messages['vactoexp_adv'] = 'Несколько адресов разделяются запятой (,). Например, test1@example.com,test2@example.com,test3@example.com.';
+$messages['vactoexp_err'] = 'Ошибка: Несколько ардесов должны быть разделены запятыми.';
+$messages['norulename'] = 'Пожалуйста, введите имя для этого фильтра.';
+$messages['ruleexists'] = 'Фильтр с таким именем уже существует. Введите другое имя фильтра.';
+$messages['noheader'] = 'Пожалуйста, введите имя заголовка для проверки.';
+$messages['headerbadchars'] = 'Ошибка: указанная строка содержит запрещенные символы.';
+$messages['noheadervalue'] = 'Пожалуйста, введите значение для проверки заголовка.';
+$messages['sizewrongformat'] = 'Ошибка: размер сообщения должен быть числовым.';
+$messages['noredirect'] = 'Пожалуйста, введите адрес электронной почты для перенаправки сообщения.';
+$messages['redirectaddresserror'] = 'Ошибка: введен неверный адрес.';
+$messages['noreject'] = 'Пожалуйста, введите текст сообщения.';
+$messages['vacnodays'] = 'Пожалуйста, укажите периодичность отсылки уведомлений';
+$messages['vacdayswrongformat'] = 'Ошибка: Периодичность должна быть положительным целым числом';
+$messages['vacnomsg'] = 'Пожалуйста, введите текст сообщения.';
+$messages['notifynomethod'] = 'Пожалуйста, введите способ отправки уведомления.';
+$messages['notifynomsg'] = 'Пожалуйста, введите текст сообщения.';
+$messages['sieveruleexp'] = 'Пожалуйста, введите одно или несколько правил, согласно которым будут проверяться сообщения. Фильтры работают в том порядке, в котором они появляются слева. Если соответствие найдено, остальные фильтры тестироваться не будут.';
+$messages['sieveactexp'] = 'Пожалуйста, выберите одно или несколько действий. Эти действия будут выполняться для каждого сообщения, соответствующего вышеуказанным правилам.';
+$messages['sieveheadershlp'] = 'Ниже находятся несколько примеров заголовков, которые могут быть проверены фильтрами. Выберите заголовок, чтобы добавить его, либо введите другой в поле ввода.';
+$messages['movingfilter'] = 'Перемещение фильтра...';
+$messages['noexistingfilters'] = 'Фильтров не найдено!';
+$messages['importdefault'] = '<b>Фильтры по умолчанию:</b> Доступен набор фильтров по умолчанию. Использовать?';
+$messages['importother'] = '<b>Импорт фильтров:</b> Найден набор фильтров от приложения %s. Импортировать?';
+$messages['switchtoadveditor'] = 'Переключение в режим расширенного редактора позволяет редактировать исходный текст сценария \'sieve\'. Изменения, сделанные в этом режиме, могут не восприниматься графическим интерфейсом, и могут быть потеряны в случае сохранения фильтров в графическом интерфейсе. Продолжить?';
+$messages['filterimported'] = 'Фильтр успешно импортирован';
+$messages['filterimporterror'] = 'Ошибка сервера во время импорта фильтра. Импорт не выполнен';
+$messages['notifyinvalidmethod'] = 'Формат метода неверен. Нужно указать URI, например: «mailto:alert@example.com».';
+$messages['nobodycontentpart'] = 'Укажите часть тела сообщения';
+$messages['badoperator'] = 'Такой оператор не может использоваться в данном правиле';
+$messages['filteractionerror'] = 'Запрошенное действие не поддерживается сервером';
+$messages['filtermissingerror'] = 'Указанное правило не существует';
+$messages['contentpartexp'] = 'MIME-тип или часть сообщения для проверки. Например, «message/rfc822», «text/html», «audio/mp3» или «image».';
+$messages['delrulesetconf'] = 'Действительно удалить этот набор правил?';
+$messages['rulesetexists'] = 'Набор правил с таким названием уже существует. Выберите другое название.';
+$messages['copyexisting'] = '<b>Копирование существующего набора правил:</b> Скопировать фильтры из существующего набора правил в текущий набор?';
+$messages['filtercopied'] = 'Фильтры успешно скопированы';
+$messages['nosieverulesets'] = 'Наборы правил не найдены.';
+$messages['baddateformat'] = 'Ошибка: Дата должна вводиться в формате ГГГГ-ММ-ДД';
+$messages['badtimeformat'] = 'Ошибка: Время должно вводиться в формате ЧЧ:ММ:СС';
+
+?> \ No newline at end of file
diff --git a/plugins/sieverules/localization/sk_SK.inc b/plugins/sieverules/localization/sk_SK.inc
new file mode 100644
index 000000000..420ffbb88
--- /dev/null
+++ b/plugins/sieverules/localization/sk_SK.inc
@@ -0,0 +1,159 @@
+<?php
+/* Author: Michal Michalac */
+
+$labels = array();
+$labels['filters'] = 'Pravidlá';
+$labels['managefilters'] = 'Spravovať pravidlá';
+$labels['filtername'] = 'Názov pravidla';
+$labels['disablerule'] = 'Zakázať pravidlo';
+$labels['disabled'] = 'zakázané';
+$labels['newfilter'] = 'Nové pravidlo';
+$labels['moveup'] = 'Posunúť vyššie';
+$labels['movedown'] = 'Posunúť nižšie';
+$labels['filterallof'] = 'vyhovuje všetkým nasl. podmienkam';
+$labels['filteranyof'] = 'vyhovuje niektorej z nasl. podmienok';
+$labels['filterany'] = 'všetky správy';
+$labels['filtercontains'] = 'obsahuje';
+$labels['filternotcontains'] = 'neobsahuje';
+$labels['filteris'] = 'je presne';
+$labels['filterisnot'] = 'nie je';
+$labels['filterexists'] = 'existuje';
+$labels['filternotexists'] = 'neexistuje';
+$labels['filterregex'] = 'vyhovuje regulárnemu výrazu';
+$labels['filternotregex'] = 'nevyhovuje regulárnemu výrazu';
+$labels['filterunder'] = 'je menšie ako';
+$labels['filterover'] = 'je väčšie ako';
+$labels['filteradvoptions'] = 'viac volieb...';
+$labels['spamtest'] = 'Pravdepodobnosť spamu';
+$labels['operator'] = 'Operátor';
+$labels['comparator'] = 'Porovnanie';
+$labels['isgreaterthan'] = 'je väčšie ako';
+$labels['isgreaterthanequal'] = 'je väčšie, alebo rovné ako';
+$labels['islessthan'] = 'je menšie ako';
+$labels['islessthanequal'] = 'je menšie, alebo rovné ako';
+$labels['equals'] = 'je rovné';
+$labels['notequals'] = 'nie je rovné';
+$labels['countisgreaterthan'] = 'počet je väčší ako';
+$labels['countisgreaterthanequal'] = 'počet je väčší, alebo rovný ako';
+$labels['countislessthan'] = 'počet je menší ako';
+$labels['countislessthanequal'] = 'počet je menší, alebo rovný ako';
+$labels['countequals'] = 'počet je';
+$labels['countnotequals'] = 'počet nie je ';
+$labels['valueisgreaterthan'] = 'hodnota je väčšia ako';
+$labels['valueisgreaterthanequal'] = 'hodnota je väčšia, alebo rovná ako';
+$labels['valueislessthan'] = 'hodnota je menšia ako';
+$labels['valueislessthanequal'] = 'hodnota je menšia, alebo rovná ako';
+$labels['valueequals'] = 'hodnota je rovná';
+$labels['valuenotequals'] = 'hodnota nie je rovná';
+$labels['userpart'] = 'užívateľská časť sa zhoduje s';
+$labels['notuserpart'] = 'užívateľská časť sa nezhoduje s';
+$labels['detailpart'] = 'detail sa zhoduje s';
+$labels['notdetailpart'] = 'detail sa nezhoduje s';
+$labels['domainpart'] = 'doména sa zhoduje';
+$labels['notdomainpart'] = 'doména sa nezhoduje';
+$labels['teststring'] = 'Testovací text';
+$labels['messagemoveto'] = 'Presunúť správu do';
+$labels['messageredirect'] = 'Preposlať správu na';
+$labels['messageimapflags'] = 'Označiť správu ako';
+$labels['messagereject'] = 'Odmietnuť so správou';
+$labels['messagevacation'] = 'Dovolenka';
+$labels['messagekeep'] = 'Zachovať správu';
+$labels['messagediscard'] = 'Zrušiť správu';
+$labels['messagenotify'] = 'Zaslať upozornenie';
+$labels['messagestop'] = 'Ukončiť spracovanie pravidiel';
+$labels['messagehelp'] = 'Čo je toto?';
+$labels['sieveorigsubj'] = 'Pripojiť k odpovedi pôvodný predmet';
+$labels['sievevachandle'] = 'Odkaz';
+$labels['method'] = 'Metóda';
+$labels['options'] = 'Voľby';
+$labels['messagesrules'] = 'Podmienky pravidla';
+$labels['messagesactions'] = 'Akcie pravidla';
+$labels['sieveto'] = 'Aliasy';
+$labels['sievefrom'] = 'Od';
+$labels['flag'] = 'Dôležitosť';
+$labels['importancen'] = 'žiadna';
+$labels['importance1'] = 'vysoká';
+$labels['importance2'] = 'štandardná';
+$labels['importance3'] = 'nízka';
+$labels['flagread'] = 'Prečítanú';
+$labels['flagdeleted'] = 'Vymazanú';
+$labels['flaganswered'] = 'Zodpovedanú';
+$labels['flagdraft'] = 'Koncept';
+$labels['flagflagged'] = 'Označenú';
+$labels['addsieverule'] = 'Pridať ďalšiu podmienku';
+$labels['addsieveact'] = 'Pridať ďalšiu akciu';
+$labels['deletesieverule'] = 'Vymazať túto podmienku';
+$labels['deletesieveact'] = 'Vymazať túto akciu';
+$labels['envelopefrom'] = 'Odosielateľ na obálke';
+$labels['envelopeto'] = 'Adresát na obálke';
+$labels['otherheader'] = 'Iná hlavička';
+$labels['days'] = 'Obdobie';
+$labels['message'] = 'Správa';
+$labels['sieveruleheaders'] = 'Zobraziť príklady ďalších hlavičiek';
+$labels['examplefilters'] = 'Pripravené pravidlá';
+$labels['importfilters'] = 'Importovať pravidlá';
+$labels['usedefaultfilter'] = 'Použiť predvolené pravidlá';
+$labels['importfilter'] = 'Importovať pravidlo';
+$labels['adveditor'] = 'Pokročilý editor';
+$labels['messageredirectcopy'] = 'Preposlať kópiu na';
+$labels['messagecopyto'] = 'Kopírovať správu do';
+$labels['body'] = 'Telo';
+$labels['auto'] = 'Automatické';
+$labels['raw'] = 'Hrubé';
+$labels['text'] = 'Text';
+$labels['other'] = 'Iné';
+$labels['bodycontentpart'] = 'Obsah správy';
+$labels['notchecked'] = 'nekontrolovaný';
+$labels['spamlevelisgreaterthanequal'] = 'je väčší, alebo rovný ako';
+$labels['spamlevelislessthanequal'] = 'je menší, alebo rovný ako';
+$labels['spamlevelequals'] = 'je rovný';
+$labels['i;ascii-casemap'] = 'text sa zhoduje bez rozlíšenia veľkosti písmen';
+$labels['i;octet'] = 'text sa zhoduje';
+$labels['i;ascii-numeric'] = 'číslo sa zhoduje';
+
+$messages = array();
+$messages['nosieverules'] = 'Žiadne pravidlá neboli nájdené.';
+$messages['filterdeleteconfirm'] = 'Ste si istí, že chcete toto pravidlo naozaj vymazať?';
+$messages['ruledeleteconfirm'] = 'Ste si istí, že chcete túto podmienku naozaj vymazať?';
+$messages['actiondeleteconfirm'] = 'Ste si istí, že chcete túto akciu naozaj vymazať?';
+$messages['filterunknownerror'] = 'Neznáma chyba servera';
+$messages['filterconnerror'] = 'Nie je možné pripojiť sa k sieve serveru';
+$messages['filterdeleteerror'] = 'Pravidlo nie je možné vymazať. Vyskytla sa chyba serveru';
+$messages['filterdeleted'] = 'Pravidlo bolo úspešne vymazané';
+$messages['filtersaved'] = 'Pravidlo bolo úspešne uložené';
+$messages['filtersaveerror'] = 'Pravidlo nie je možné uložiť. Vyskytla sa chyba serveru';
+$messages['vacdaysexp'] = "Obdobie je počet dní, počas ktorého nebude správa posielaná rovnakému užívateľovi bez ohľadu na to, koľko krát Vás bude kontaktovať. Napr.: Ak si nastavíte obdobie na 7 (dní) a Jozef Vám pošle e-mail v pondelok, v stredu, v nedeľu a na ďalší pondelok, dostane správu o Vašej neprítomnosti vždy len v pondelok.";
+$messages['vachandleexp'] = 'Odkaz sa dá použiť na pripojenie iných dovolenkových správ. Každá z nich sa v nastavenom období použije len raz.';
+$messages['vactoexp'] = "Zoznam ďalších adresátov zahrnutých do automatického odpovedania. Ak e-mail nie je adresovaný na Vašu hlavnú e-mailovú adresu ani na adresu v tomto zozname, automatická odpoveď sa neposiela.";
+$messages['norulename'] = 'Zadajte prosím názov pravidla';
+$messages['ruleexists'] = 'Pravidlo s týmto názvom už existuje. Zadajte prosím iný názov';
+$messages['noheader'] = 'Zadajte prosím názov hlavičky pre porovnanie';
+$messages['headerbadchars'] = 'Chyba: Hlavička obsahuje zakázané znaky';
+$messages['noheadervalue'] = 'Zadajte prosím hodnotu s ktorou sa má hlavička porovnávať';
+$messages['sizewrongformat'] = 'Chyba: Veľkosť správy musí byť číslo';
+$messages['noredirect'] = 'Zadajte prosím e-mailovú adresu na ktorú sa má správa preposlať';
+$messages['redirectaddresserror'] = 'Chyba: Adresa vyzerá ako neplatná';
+$messages['noreject'] = 'Zadajte prosím správu, ktorá sa pošle s odmietnutím';
+$messages['vacnodays'] = 'Zadajte prosím do obdobia počet dní, počas ktorých nebude automatická odpoveď posielaná rovnakému užívateľovi';
+$messages['vacdayswrongformat'] = 'Chyba: Obdobie musí byť číslo väčšie, alebo rovné 1';
+$messages['vacnomsg'] = 'Zadajte prosím nejaký text správy';
+$messages['notifynomethod'] = 'Zadajte prosím spôsob, ktorým má byť upozornenie poslané';
+$messages['notifynomsg'] = 'Zadajte prosím text Vašej správy';
+$messages['sieveruleexp'] = "Zadefinujte prosím podmienky s ktorými bude správa porovnávaná. Pravidlá sa vyhodnocujú v poradí v akom sú zobrazené v ľavej časti tejto obrazovky. Ak sa nájde zhoda, ďalšie pravidlá sa vyhodnocovať nebudú.";
+$messages['sieveactexp'] = 'Vyberte prosím zo zoznamu akciu, ktorá sa bude vykonávať pre všetky e-maily vyhovujúce podmienke/podmienkam vyššie.';
+$messages['sieveheadershlp'] = 'Nižšie je uvedených niekoľko príkladov hlavičiek, ktoré môžu byť použité v podmienkach. Vyberte si tú, ktorú chcete vložiť do podmienky hore, alebo zadajte názov hlavičky do okienka ručne.';
+$messages['movingfilter'] = 'Presúvam pravidlo...';
+$messages['noexistingfilters'] = 'Žiadne pravidlo nebolo nájdené!';
+$messages['importdefault'] = '<b>Použiť pripravené pravidlá:</b> Je dostupných niekoľko pravidiel. Chcete ich použiť?';
+$messages['importother'] = '<b>Importovať pravidlá:</b> Ďalšia sada pravidiel bola nájdená v %s. Chcete ich importovať?';
+$messages['switchtoadveditor'] = 'Prepnutie do pokročilého editora Vám umožní priamo editovať súbor pravidel. Úpravy, ktoré tu urobíte môžu byť pre štandardný editor pravidiel nečitateľné a môžu sa pri uložení v ňom stratiť. Chcete pokračovať?';
+$messages['filterimported'] = 'Pravidlá boli úspešne importované';
+$messages['filterimporterror'] = 'Pravidlá nebolo možné importovať. Vyskytla sa chyba servera';
+$messages['notifyinvalidmethod'] = 'Vyzerá to, že metóda nie je zapísaná v platnom formáte. Musí to byť URI. Napr.: `mailto:adresa@domena.sk`.';
+$messages['nobodycontentpart'] = 'Zadajte prosím obsahovú časť testu';
+$messages['badoperator'] = 'Prepáčte, ale operátor ktorý ste vybrali nemôže byť v tejto podmienke použitý';
+$messages['filteractionerror'] = 'Akcia, ktorú ste vybrali nie je podporovaná serverom';
+$messages['filtermissingerror'] = 'Nepodarilo sa nájsť požadovanú podmienku';
+$messages['contentpartexp'] = 'Typ MIME, alebo špecifická časť správy, ktorá má byť testovaná. Napr.: `message/rfc822`, `text/html`, `audio/mp3` či `image`.';
+
+?> \ No newline at end of file
diff --git a/plugins/sieverules/localization/sl_SI.inc b/plugins/sieverules/localization/sl_SI.inc
new file mode 100644
index 000000000..16bc1851d
--- /dev/null
+++ b/plugins/sieverules/localization/sl_SI.inc
@@ -0,0 +1,185 @@
+<?php
+/* Author: Jernej Simončič */
+
+$labels = array();
+$labels['filters'] = 'Pravila';
+$labels['managefilters'] = 'Upravljal pravila';
+$labels['filtername'] = 'Ime';
+$labels['disablerule'] = 'Onemogoči pravilo';
+$labels['disabled'] = 'Onemogočeno';
+$labels['newfilter'] = 'Novo pravilo';
+$labels['moveup'] = 'Premakni višje';
+$labels['movedown'] = 'Premakni nižje';
+$labels['filterallof'] = 'sporočilo zadošča vsem pogojem';
+$labels['filteranyof'] = 'sporočilo zadošča kateremukoli od pogojev';
+$labels['filterany'] = 'vsa sporočila';
+$labels['filtercontains'] = 'vsebuje';
+$labels['filternotcontains'] = 'ne vsebuje';
+$labels['filteris'] = 'je enak';
+$labels['filterisnot'] = 'ni enak';
+$labels['filterexists'] = 'obstaja';
+$labels['filternotexists'] = 'ne obstaja';
+$labels['filterregex'] = 'ustreza regularnemu izrazu';
+$labels['filternotregex'] = 'ne ustreza regularnemu izrazu';
+$labels['filterunder'] = 'je manj kot';
+$labels['filterover'] = 'je več kot';
+$labels['filterbefore'] = 'je pred';
+$labels['filterafter'] = 'je po';
+$labels['filteradvoptions'] = 'več možnosti...';
+$labels['spamtest'] = 'spam verjetnost';
+$labels['operator'] = 'Operater';
+$labels['comparator'] = 'Primerjava';
+$labels['isgreaterthan'] = 'je večje kot';
+$labels['isgreaterthanequal'] = 'je večje ali enako';
+$labels['islessthan'] = 'je manjše kot';
+$labels['islessthanequal'] = 'je manjše ali enako';
+$labels['equals'] = 'je enako';
+$labels['notequals'] = 'ni enako';
+$labels['countisgreaterthan'] = 'število je večje kot';
+$labels['countisgreaterthanequal'] = 'število je večje ali enako';
+$labels['countislessthan'] = 'število je manjše kot';
+$labels['countislessthanequal'] = 'število je manjše ali enako';
+$labels['countequals'] = 'število je enako';
+$labels['countnotequals'] = 'število ni enako';
+$labels['valueisgreaterthan'] = 'vrednost je večja kot';
+$labels['valueisgreaterthanequal'] = 'vrednost je večja ali enaka';
+$labels['valueislessthan'] = 'vrednost je manjša kot';
+$labels['valueislessthanequal'] = 'vrednost je manjša ali enaka';
+$labels['valueequals'] = 'vrednost je enaka';
+$labels['valuenotequals'] = 'vrednost ni enaka';
+$labels['userpart'] = 'uporabniški del naslova je enak';
+$labels['notuserpart'] = 'uporabniški del naslova ni enak';
+$labels['detailpart'] = 'podrobni del naslova je enak';
+$labels['notdetailpart'] = 'podrobni del naslova ni enak';
+$labels['domainpart'] = 'domena je enaka';
+$labels['notdomainpart'] = 'domena ni enaka';
+$labels['teststring'] = 'Vzorčno besedilo';
+$labels['messagemoveto'] = 'Premakni sporočilo v';
+$labels['messageredirect'] = 'Preusmeri sporočilo';
+$labels['messageimapflags'] = 'Označi sporočilo kot';
+$labels['messagereject'] = 'Zavrni s sporočilom';
+$labels['messagevacation'] = 'Samodejni odgovor';
+$labels['messagekeep'] = 'Ohrani sporočilo';
+$labels['messagediscard'] = 'Zavrzi sporočilo';
+$labels['messagenotify'] = 'Pošlji obvestilo';
+$labels['messagestop'] = 'Prenehaj z izvajanjem pravil';
+$labels['messagehelp'] = 'Kaj je to?';
+$labels['sieveorigsubj'] = 'Pripni originalno zadevo k odgovoru';
+$labels['sievevachandle'] = 'Vzdevek';
+$labels['method'] = 'Metoda';
+$labels['options'] = 'Možnosti';
+$labels['messagesrules'] = 'Pogoji';
+$labels['messagesactions'] = 'Dejanja';
+$labels['sieveto'] = 'Drugi prejemniki';
+$labels['sievefrom'] = 'Od';
+$labels['flag'] = 'Pomembnost';
+$labels['importancen'] = 'Brez';
+$labels['importance1'] = 'Visoka';
+$labels['importance2'] = 'Običajna';
+$labels['importance3'] = 'Nizka';
+$labels['flagread'] = 'Prebrano';
+$labels['flagdeleted'] = 'Izbrisano';
+$labels['flaganswered'] = 'Odgovorjeno';
+$labels['flagdraft'] = 'Osnutek';
+$labels['flagflagged'] = 'Zastavica';
+$labels['addsieverule'] = 'Dodaj novo pravilo';
+$labels['addsieveact'] = 'Dodaj novo dejanje';
+$labels['deletesieverule'] = 'Izbriši to pravilo';
+$labels['deletesieveact'] = 'Izbriši to dejanje';
+$labels['envelopefrom'] = 'Pošiljatelj ovojnice';
+$labels['envelopeto'] = 'Prejemnik ovojnice';
+$labels['otherheader'] = 'Druga polja';
+$labels['days'] = 'Ponovitev';
+$labels['message'] = 'Sporočilo';
+$labels['sieveruleheaders'] = 'Prikaži vzorce polj';
+$labels['examplefilters'] = 'Vzorčni filtri';
+$labels['importfilters'] = 'Uvozi filtre';
+$labels['usedefaultfilter'] = 'Uporabi privzete filtre';
+$labels['importfilter'] = 'Uvozi filter';
+$labels['moreactions'] = 'Več možnosti...';
+$labels['adveditor'] = 'Napredni urejevalnik';
+$labels['stdeditor'] = 'Običajni urejevalnik';
+$labels['messageredirectcopy'] = 'Pošlji kopijo';
+$labels['messagecopyto'] = 'Kopiraj sporočilo v';
+$labels['body'] = 'Telo';
+$labels['auto'] = 'Samodejno';
+$labels['raw'] = 'Surovo';
+$labels['text'] = 'Besedilo';
+$labels['other'] = 'Drugo';
+$labels['bodycontentpart'] = 'Del vsebine';
+$labels['notchecked'] = 'ni pregledano';
+$labels['spamlevelisgreaterthanequal'] = 'je večja ali enaka';
+$labels['spamlevelislessthanequal'] = 'je manjša ali enaka';
+$labels['spamlevelequals'] = 'je enaka';
+$labels['i;ascii-casemap'] = 'primerjaj brez razlikovanja velikih in malih črk';
+$labels['i;octet'] = 'primerjaj z razlikovanjem velikih in malih črk';
+$labels['i;ascii-numeric'] = 'primerjaj kot število';
+$labels['selectruleset'] = 'Izberi zbirko pravil';
+$labels['activeruleset'] = '%s (aktivna)';
+$labels['activateruleset'] = 'Aktiviraj to zbirko';
+$labels['newruleset'] = 'Ustvari novo zbirko';
+$labels['delruleset'] = 'Izbriši to zbirko';
+$labels['renameruleset'] = 'Preimenuj to zbirko';
+$labels['copy'] = 'Kopiraj';
+$labels['copyexistingfilter'] = 'Kopiraj obstoječa pravila';
+$labels['copytoruleset'] = 'Kopiraj pravilo v drugo zbirko';
+$labels['copyfromruleset'] = 'Kopiraj pravila iz obstoječe zbirke';
+$labels['time'] = 'Čas';
+$labels['weekday'] = 'Dan v tednu';
+
+$messages = array();
+$messages['nosieverules'] = 'Ni pravil.';
+$messages['filterdeleteconfirm'] = 'Ali resnično želiš izbrisati to pravilo?';
+$messages['ruledeleteconfirm'] = 'Ali resnično želiš izbrisati ta pogoj?';
+$messages['actiondeleteconfirm'] = 'Ali resnično želiš izbrisati to dejanje?';
+$messages['filterunknownerror'] = 'Neznana napaka strežnika';
+$messages['filterconnerror'] = 'Ni se bilo mogoče povezati na strežnik sieve';
+$messages['filterdeleteerror'] = 'Ni mogoče izbrisati pravila. Prišlo je do napake strežnika';
+$messages['filterdeleted'] = 'Pravilo izbrisano';
+$messages['filtersaved'] = 'Pravilo shranjeno';
+$messages['filtersaveerror'] = 'Ni mogoče shraniti pravila. Prišlo je do napake strežnika';
+$messages['vacdaysexp'] = 'Ponovitev je število dni, ki mora preteči, preden bo sporočilo znova poslano istemu pošiljatelju, ne glede na to, koliko sporočil je poslal v tem času.<br /><br />Npr.: če Janez pošlje sporočilo v ponedeljek, in je ponovitev nastavljena na 7, potem bo dobil odgovor v ponedeljek, še enega pa ne bo dobil pred naslednjim ponedeljkom, ne glede na to, koliko sporočil bo poslal vmes.';
+$messages['vachandleexp'] = 'Z vzdevkom se lahko med seboj poveže več različnih samodejnih odgovorov - ko je bil samodejni odgovor z nekim vzdevkom poslan, ne bo v tej ponovitvi poslano noben drug odgovor z istim vzdevkom.';
+$messages['vactoexp'] = 'Seznam dodatnih naslovov prejemnikov, ki bodo vključeni pri samodejnem odgovarjanju. Če naslova prejemnika sporočila ni na tem seznamu, samodejni odgovor na sporočilo ne bo poslan.';
+$messages['vactoexp_adv'] = 'Naslove ločite z vejicami. Primer: naslov1@example.com,naslov2@example.org,naslov3@example.com';
+$messages['vactoexp_err'] = 'Napaka: naslovi morajo biti ločeni z vejicami (,)';
+$messages['norulename'] = 'Vnesite ime pravila';
+$messages['ruleexists'] = 'Pravilo s tem imenom že obstaja. Vnesite drugo ime';
+$messages['noheader'] = 'Vnesite ime polja';
+$messages['headerbadchars'] = 'Napaka: polje vsebuje nedovoljene znake';
+$messages['noheadervalue'] = 'Vnesite vrednost, s katero se preizkuša polje';
+$messages['sizewrongformat'] = 'Napaka: velikost sporočila mora biti število';
+$messages['noredirect'] = 'Vnestie e-poštni naslov, na katerega naj se preusmeri sporočilo';
+$messages['redirectaddresserror'] = 'Napaka: naslov ni videti veljaven';
+$messages['noreject'] = 'Vnesite sporočilo, ki naj se pošlje z zavrnitvijo';
+$messages['vacnodays'] = 'Vnesite število dni, po preteku katerih se bo samodejni odgovor ponovil';
+$messages['vacdayswrongformat'] = 'Napaka: ponovitev mora biti večja ali enaka 1';
+$messages['vacnomsg'] = 'Vnesite besedilo sporočila';
+$messages['notifynomethod'] = 'Vnesite metodo, s katero naj bo poslano sporočilo';
+$messages['notifynomsg'] = 'Vnesite besedilo sporočila';
+$messages['sieveruleexp'] = 'Pripravite enega ali več pogojev, pod katerimi bo to pravilo uveljavljeno. Pravila se izvajajo v vrstnem redu, po katerem so razvrščena na seznamu na levi strani. Če sporočilo ustreza pogojem, se nadaljna pravila ne bodo izvedla.';
+$messages['sieveruleexp_stop'] = 'Pripravite enega ali več pogojev, pod katerimi bo to pravilo uveljavljeno. Pravila se izvajajo v vrstnem redu, po katerem so razvrščena na seznamu na levi strani, in se izvajajo do dejanja ›Prenehaj‹.';
+$messages['sieveactexp'] = 'Izberite eno od spodnjih možnosti. Ta dejanja se bodo izvedla za vsako sporočilo, ki ustreza zgornjim pravilom.';
+$messages['sieveheadershlp'] = 'Spodaj je nekaj primerov drugih polj, ki jih lahko preizkušajo pravila. Izberite polje s seznama, ali pa vnesite poljubno polje.';
+$messages['movingfilter'] = 'Premikam pravilo...';
+$messages['noexistingfilters'] = 'Obstoječa pravila niso bila zaznana!';
+$messages['importdefault'] = '<b>Uporabi privzeta pravila:</b> na voljo so privzeta pravila. Ali jih želite uvoziti?';
+$messages['importother'] = '<b>Uvozi filtre:</b> Najdena je bila druga zbirka pravil %s. Ali želite uvoziti ta pravila v trenutno zbirko?';
+$messages['switchtoadveditor'] = 'Preklop v napredni urejevalnik omogoča neposredno urejanje datoteke sieve. Sprememb, ki jih naredite v naprednem urejevalniku, običajni urejevalnik morda ne bo razumel, in se lahko izgubijo, če pravila shranite z običajnim urejevalnikom. Ali želite nadaljevati?';
+$messages['filterimported'] = 'Pravilo uspešno uvoženo';
+$messages['filterimporterror'] = 'Pravila ni bilo mogoče uvoziti. Prišlo je do napake strežnika';
+$messages['notifyinvalidmethod'] = 'Metoda mora biti zapisana v URI formatu, npr.: ›mailto:alert@example.com‹.';
+$messages['nobodycontentpart'] = 'Vnesite del vsebine za preizkus';
+$messages['badoperator'] = 'Izbranega operaterja ne morete uporabiti s tem pravilom';
+$messages['filteractionerror'] = 'Strežnik ne podpira željenega dejanja';
+$messages['filtermissingerror'] = 'Željenega pravila ni bilo mogoče najti';
+$messages['contentpartexp'] = 'MIME vrsta ali specifičen del sporočila, ki naj se testira. Npr.: ›message/rfc822‹, ›text/html‹, ›audio/mp3‹ ali ›image‹.';
+$messages['delrulesetconf'] = 'Ali ste prepričani, da želite izbrisati izbrano zbirko?';
+$messages['rulesetexists'] = 'Zbirka s tem imenom že obstaja. Vnesite drugo ime';
+$messages['copyexisting'] = '<b>Kopiraj obstoječo zbirko:</b> Ali želite kopirati pravila iz obstoječe zbirke v trenutno?';
+$messages['filtercopied'] = 'Pravilo uspešno prekopirano';
+$messages['nosieverulesets'] = 'Ni zbirk.';
+$messages['baddateformat'] = 'Napaka: vnesite datum v obliki LLLL-MM-DD';
+$messages['badtimeformat'] = 'Napaka: vnesite čas v obliki UU:MM:SS';
+
+?> \ No newline at end of file
diff --git a/plugins/sieverules/localization/sv_SE.inc b/plugins/sieverules/localization/sv_SE.inc
new file mode 100644
index 000000000..2aa2d4e03
--- /dev/null
+++ b/plugins/sieverules/localization/sv_SE.inc
@@ -0,0 +1,159 @@
+<?php
+/* Author: Ida Wellner */
+
+$labels = array();
+$labels['filters'] = 'Filter';
+$labels['managefilters'] = 'Hantera filter';
+$labels['filtername'] = 'Filternamn';
+$labels['disablerule'] = 'Inaktivera regel';
+$labels['disabled'] = 'Inaktiverad';
+$labels['newfilter'] = 'Nytt filter';
+$labels['moveup'] = 'Flytta uppåt';
+$labels['movedown'] = 'Flytta nedåt';
+$labels['filterallof'] = 'matcha samtliga av följande regler';
+$labels['filteranyof'] = 'matcha en av följande regler';
+$labels['filterany'] = 'alla meddelanden';
+$labels['filtercontains'] = 'innehåller';
+$labels['filternotcontains'] = 'inte innehåller';
+$labels['filteris'] = 'är';
+$labels['filterisnot'] = 'inte är';
+$labels['filterexists'] = 'existerar';
+$labels['filternotexists'] = 'inte existerar';
+$labels['filterregex'] = 'matchar följande reguljära uttryck';
+$labels['filternotregex'] = 'inte matchar följande reguljära uttryck';
+$labels['filterunder'] = 'är mindre än';
+$labels['filterover'] = 'är större än';
+$labels['filteradvoptions'] = 'fler inställningar...';
+$labels['spamtest'] = 'Spamklassning';
+$labels['operator'] = 'Operator';
+$labels['comparator'] = 'Typ av matchning';
+$labels['isgreaterthan'] = 'är större än';
+$labels['isgreaterthanequal'] = 'är större än eller lika med';
+$labels['islessthan'] = 'är mindre än';
+$labels['islessthanequal'] = 'är mindre än eller lika med';
+$labels['equals'] = 'är lika med';
+$labels['notequals'] = 'är inte lika med';
+$labels['countisgreaterthan'] = 'antal är större än';
+$labels['countisgreaterthanequal'] = 'antal är större än eller lika med';
+$labels['countislessthan'] = 'antal är mindre än';
+$labels['countislessthanequal'] = 'antal är mindre än eller lika med';
+$labels['countequals'] = 'antal är lika med';
+$labels['countnotequals'] = 'antal är inte lika med';
+$labels['valueisgreaterthan'] = 'värdet är större än';
+$labels['valueisgreaterthanequal'] = 'värdet är större än eller lika med';
+$labels['valueislessthan'] = 'värdet är mindre än';
+$labels['valueislessthanequal'] = 'värdet är mindre än eller lika med';
+$labels['valueequals'] = 'värdet är lika med';
+$labels['valuenotequals'] = 'värdet är inte lika med';
+$labels['userpart'] = 'användare är lika med';
+$labels['notuserpart'] = 'användare är inte lika med';
+$labels['detailpart'] = 'klartextnamn är lika med';
+$labels['notdetailpart'] = 'klartextnamn är inte lika med';
+$labels['domainpart'] = 'domän är lika med';
+$labels['notdomainpart'] = 'domän är inte lika med';
+$labels['teststring'] = 'Matcha mot';
+$labels['messagemoveto'] = 'Flytta meddelande till';
+$labels['messageredirect'] = 'Omdirigera meddelande till';
+$labels['messageimapflags'] = 'Markera meddelande som';
+$labels['messagereject'] = 'Avvisa med meddelande';
+$labels['messagevacation'] = 'Frånvarobesked';
+$labels['messagekeep'] = 'Behåll meddelandet';
+$labels['messagediscard'] = 'Kasta meddelandet';
+$labels['messagenotify'] = 'Skicka notifiering';
+$labels['messagestop'] = 'Sluta behandla filter';
+$labels['messagehelp'] = 'Vad är detta?';
+$labels['sieveorigsubj'] = 'Lägg till orginalmeddelandets ämnesrad i svaret';
+$labels['sievevachandle'] = 'Id';
+$labels['method'] = 'Metod';
+$labels['options'] = 'Options';
+$labels['messagesrules'] = 'Filterregler';
+$labels['messagesactions'] = 'Filteråtgärder';
+$labels['sieveto'] = 'Alias';
+$labels['sievefrom'] = 'Från';
+$labels['flag'] = 'Prioritet';
+$labels['importancen'] = 'Ingen';
+$labels['importance1'] = 'Hög';
+$labels['importance2'] = 'Normal';
+$labels['importance3'] = 'Låg';
+$labels['flagread'] = 'Läst';
+$labels['flagdeleted'] = 'Borttaget';
+$labels['flaganswered'] = 'Besvarat';
+$labels['flagdraft'] = 'Utkast';
+$labels['flagflagged'] = 'Flaggat';
+$labels['addsieverule'] = 'Lägg till ytterligare regel under denna';
+$labels['addsieveact'] = 'Lägg till ytterligare åtgärd under denna';
+$labels['deletesieverule'] = 'Ta bort denna regel';
+$labels['deletesieveact'] = 'Ta bort denna åtgärd';
+$labels['envelopefrom'] = 'Kuvertavsändare';
+$labels['envelopeto'] = 'Kuvertmottagare';
+$labels['otherheader'] = 'Annat brevhuvud';
+$labels['days'] = 'Dagar';
+$labels['message'] = 'Meddelande';
+$labels['sieveruleheaders'] = 'Se exempel på andra brevhuvuden';
+$labels['examplefilters'] = 'Exempelfilter';
+$labels['importfilters'] = 'Importera filter';
+$labels['usedefaultfilter'] = 'Använd standardfilter';
+$labels['importfilter'] = 'Importera filter';
+$labels['adveditor'] = 'Avancerad editor';
+$labels['messageredirectcopy'] = 'Skicka en kopia till';
+$labels['messagecopyto'] = 'Kopiera meddelandet till';
+$labels['body'] = 'Meddelandetext';
+$labels['auto'] = 'Auto';
+$labels['raw'] = 'Raw';
+$labels['text'] = 'Text';
+$labels['other'] = 'Annat';
+$labels['bodycontentpart'] = 'Innehållsdel';
+$labels['notchecked'] = 'inte kontrollerat';
+$labels['spamlevelisgreaterthanequal'] = 'är större än eller lika med';
+$labels['spamlevelislessthanequal'] = 'är mindre än eller lika med';
+$labels['spamlevelequals'] = 'är lika med';
+$labels['i;ascii-casemap'] = 'ej skiftlägeskänslig strängmatchning';
+$labels['i;octet'] = 'exakt strängmatchning';
+$labels['i;ascii-numeric'] = 'numerisk matchning';
+
+$messages = array();
+$messages['nosieverules'] = 'Inga filter funna.';
+$messages['filterdeleteconfirm'] = 'Är du säker på att du vill ta bort det här filtret?';
+$messages['ruledeleteconfirm'] = 'Är du säker på att du vill radera den här regeln?';
+$messages['actiondeleteconfirm'] = 'Är du säker på att du vill radera den här åtgärden?';
+$messages['filterunknownerror'] = 'Okänt serverfel';
+$messages['filterconnerror'] = 'Kan ej kontakta sieve-servern';
+$messages['filterdeleteerror'] = 'Kan ej ta bort filtret. Ett serverfel inträffade.';
+$messages['filterdeleted'] = 'Filtret har tagits bort';
+$messages['filtersaved'] = 'Filret har sparats';
+$messages['filtersaveerror'] = 'Kan inte spara filtret. Ett serverfel inträffade.';
+$messages['vacdaysexp'] = 'Frånvaromeddelandet kommer endast att skickas en gång till samma användare under det antal dagar som anges ovan, oavsett hur många gånger den personen mailar dig.<br /> <br />Exempel: Om Joe mailar dig på måndag och antalet dagar är 7 kommer han att få ett frånvaromeddelande på måndag, men sedan får han inget nytt förrän nästa måndag oavsett hur många gånger han mailar dig under veckan.';
+$messages['vachandleexp'] = 'Ett id kan använndas för att länka samman flera frånvaromeddelanden. När ett frånvaromeddelande med detta id har skickats kommer inga fler att frånvaromeddelanden med samma id att skickas under perioden.';
+$messages['vactoexp'] = 'Frånvaromeddelandet skickas enbart till din huvudsakliga adress + de adresser du valt i listan ovan. Har du fler mottagaradresser du vill kunna välja bland måste du först lägga till dessa under Profiler.';
+$messages['norulename'] = 'Fyll i ett namn på detta filter.';
+$messages['ruleexists'] = 'Ett filter med det valda namnet finns redan. Vänligen fyll i ett annat namn.';
+$messages['noheader'] = 'Fyll i namnet på brevhuvudet';
+$messages['headerbadchars'] = 'Fel: Brevhuvudet innehåller otillåtna tecken';
+$messages['noheadervalue'] = 'Fyll i ett värde som brevhuvudet ska testas mot';
+$messages['sizewrongformat'] = 'Fel: Meddelandestorlek måste anges i siffror';
+$messages['noredirect'] = 'Fyll i en e-postadress att omdirigera meddelanden till';
+$messages['redirectaddresserror'] = 'Fel: e-postadressen har inte giltigt format';
+$messages['noreject'] = 'Fyll i ett meddelande som ska skickas med brev som avvisas';
+$messages['vacnodays'] = 'Fyll i antalet dagar för den period under vilken meddelandet inte kommer att skickas på nytt till samma person';
+$messages['vacdayswrongformat'] = 'Fel: Antalet dagar måste vara ett tal större än eller lika med 1';
+$messages['vacnomsg'] = 'Fyll i text som ska skickas i frånvaromeddelandet';
+$messages['notifynomethod'] = 'Fyll i med vilken metod notifieringen ska skickas';
+$messages['notifynomsg'] = 'Fyll i en notifieringstext';
+$messages['sieveruleexp'] = 'Definiera en eller flera regler som varje meddelande kommer att testas mot. Filter körs i den ordning de listas till vänster.';
+$messages['sieveactexp'] = 'Välj bland alternativen nedan. Dessa åtgärder kommer att utföras varje gång ett meddelande matchar reglerna ovan.';
+$messages['sieveheadershlp'] = 'Detta är några exempel på andra brevhuvudet som filtren kan testa. Välj ett brevhuvud för att lägga till det till regeln eller fyll i ett eget brevhuvud.';
+$messages['movingfilter'] = 'Flyttar filter...';
+$messages['noexistingfilters'] = 'Hittar inga existerande filter!';
+$messages['importdefault'] = '<b>Använd standardfilter:</b> Det finns en uppsättning standardfilter tillgängliga. Skulle du vilja använda dem?';
+$messages['importother'] = '<b>Importera filter:</b> En annan uppsättning filter från %s har upptäckts. Skulle du vilja importera dem till din nuvarande filteruppsättning?';
+$messages['switchtoadveditor'] = 'Med den avancerade editorn kan du redigera din filterfil direkt. Ändringar gjorda där kan gå förlorade om du senare redigerar dina filter via den vanliga filterredigeringen. Vill du fortsätta?';
+$messages['filterimported'] = 'Importen av filter lyckades';
+$messages['filterimporterror'] = 'Importen av filter misslyckades. Ett serverfel uppstod.';
+$messages['notifyinvalidmethod'] = 'Den angivna metoden har inte ett giltigt format, det måste vara en URI. Exempel: `mailto:alert@example.com`.';
+$messages['nobodycontentpart'] = 'Fyll i vilken del av innehållet som ska testas';
+$messages['badoperator'] = 'Den valda operatorn kan inte användas i den här regeln';
+$messages['filteractionerror'] = 'Den valda åtgärden stöds inte av servern';
+$messages['filtermissingerror'] = 'Kan inte hitta den önskade regeln';
+$messages['contentpartexp'] = 'Fyll i MIME-typ eller specifik del av meddelandet som ska testas. Exempel: `message/rfc822`, `text/html`, `audio/mp3`';
+
+?> \ No newline at end of file
diff --git a/plugins/sieverules/localization/zh_TW.inc b/plugins/sieverules/localization/zh_TW.inc
new file mode 100644
index 000000000..4f63b1e70
--- /dev/null
+++ b/plugins/sieverules/localization/zh_TW.inc
@@ -0,0 +1,192 @@
+<?php
+/* Author: Guo-Wei Su */
+
+$labels = array();
+$labels['filters'] = '郵件規則';
+$labels['managefilters'] = '管理郵件規則';
+$labels['filtername'] = '規則名稱';
+$labels['disablerule'] = '停用規則';
+$labels['disabled'] = '停用';
+$labels['newfilter'] = '建立新規則';
+$labels['moveup'] = '上移';
+$labels['movedown'] = '下移';
+$labels['filterallof'] = '符合所有條件';
+$labels['filteranyof'] = '符合任何一個條件';
+$labels['filterany'] = '所有郵件';
+$labels['filtercontains'] = '包含';
+$labels['filternotcontains'] = '不包含';
+$labels['filteris'] = '等於';
+$labels['filterisnot'] = '不等於';
+$labels['filterexists'] = '存在';
+$labels['filternotexists'] = '不存在';
+$labels['filterregex'] = '符合正則表示式';
+$labels['filternotregex'] = '不符合正則表示式';
+$labels['filterunder'] = '小於';
+$labels['filterover'] = '大於';
+$labels['filterbefore'] = '之前';
+$labels['filterafter'] = '之後';
+$labels['filteradvoptions'] = '更多選項...';
+$labels['spamtest'] = 'Spam 可能性';
+$labels['operator'] = '操作';
+$labels['comparator'] = '比較';
+$labels['isgreaterthan'] = '大於';
+$labels['isgreaterthanequal'] = '大於或等於';
+$labels['islessthan'] = '小於';
+$labels['islessthanequal'] = '小於或等於';
+$labels['equals'] = '等於';
+$labels['notequals'] = '不等於';
+$labels['countisgreaterthan'] = '數量大於';
+$labels['countisgreaterthanequal'] = '數量大於或等於';
+$labels['countislessthan'] = '數量少於';
+$labels['countislessthanequal'] = '數量少於或等於';
+$labels['countequals'] = '數量等於';
+$labels['countnotequals'] = '數量不等於';
+$labels['valueisgreaterthan'] = '值大於';
+$labels['valueisgreaterthanequal'] = '值大於或等於';
+$labels['valueislessthan'] = '值小於';
+$labels['valueislessthanequal'] = '值小於或等於';
+$labels['valueequals'] = '值等於';
+$labels['valuenotequals'] = '值不等於';
+$labels['userpart'] = 'user part equals';
+$labels['notuserpart'] = 'user part does not equal';
+$labels['detailpart'] = 'detail part equals';
+$labels['notdetailpart'] = 'detail part does not equal';
+$labels['domainpart'] = 'domain part equals';
+$labels['notdomainpart'] = 'domain part does not equal';
+$labels['teststring'] = '測試字串';
+$labels['messagemoveto'] = '移動郵件至';
+$labels['messageredirect'] = 'Redirect message to';
+$labels['messageimapflags'] = '變更為';
+$labels['messagereject'] = '拒絕郵件';
+$labels['messagevacation'] = '不在辦公室訊息';
+$labels['messagekeep'] = '保留郵件';
+$labels['messagediscard'] = '丟棄郵件';
+$labels['messagenotify'] = '寄送通知';
+$labels['messagestop'] = '中斷郵件規則';
+$labels['messagehelp'] = '這是什麼?';
+$labels['sieveorigsubj'] = '附加來件主旨至回信主旨中';
+$labels['sievevachandle'] = 'Handle';
+$labels['method'] = '方式';
+$labels['options'] = '選項';
+$labels['messagesrules'] = '規則條件';
+$labels['messagesactions'] = '規則動作';
+$labels['sieveto'] = '別名';
+$labels['sievefrom'] = '寄件者';
+$labels['flag'] = '重要性';
+$labels['importancen'] = '無';
+$labels['importance1'] = '高';
+$labels['importance2'] = '一般';
+$labels['importance3'] = '低';
+$labels['flagread'] = '讀取';
+$labels['flagdeleted'] = '刪除';
+$labels['flaganswered'] = '已答覆';
+$labels['flagdraft'] = '草稿';
+$labels['flagflagged'] = '標幟';
+$labels['addsieverule'] = '新增條件,在這筆之後';
+$labels['addsieveact'] = '新增動作,在這筆之後';
+$labels['deletesieverule'] = '刪除這個條件';
+$labels['deletesieveact'] = '刪除這個動作';
+$labels['envelopefrom'] = 'Envelope From';
+$labels['envelopeto'] = 'Envelope To';
+$labels['otherheader'] = '其他郵件表頭';
+$labels['days'] = '期間';
+$labels['message'] = '訊息';
+$labels['sieveruleheaders'] = '顯示表頭範例';
+$labels['examplefilters'] = '規則範例';
+$labels['importfilters'] = '匯入規則';
+$labels['usedefaultfilter'] = '使用預設規則';
+$labels['importfilter'] = '匯入規則';
+$labels['moreactions'] = '更多選項...';
+$labels['adveditor'] = '進階編輯器';
+$labels['stdeditor'] = '一般編輯器';
+$labels['messageredirectcopy'] = '寄送副本到';
+$labels['messagecopyto'] = '複製郵件到';
+$labels['body'] = 'Body';
+$labels['auto'] = 'Auto';
+$labels['raw'] = 'Raw';
+$labels['text'] = 'Text';
+$labels['other'] = 'Other';
+$labels['bodycontentpart'] = 'Content Part';
+$labels['notchecked'] = 'not checked';
+$labels['spamlevelisgreaterthanequal'] = '大於或等於';
+$labels['spamlevelislessthanequal'] = '小於或等於';
+$labels['spamlevelequals'] = '等於';
+$labels['i;ascii-casemap'] = 'case-insensitive string match';
+$labels['i;octet'] = 'exact string match';
+$labels['i;ascii-numeric'] = '數字符合';
+$labels['selectruleset'] = 'Select ruleset';
+$labels['activeruleset'] = '%s (active)';
+$labels['activateruleset'] = 'Activate this ruleset';
+$labels['newruleset'] = 'Create a new ruleset';
+$labels['delruleset'] = 'Delete this ruleset';
+$labels['renameruleset'] = 'Rename this ruleset';
+$labels['copy'] = '複製';
+$labels['copyexistingfilter'] = '複製規則';
+$labels['copytoruleset'] = 'Copy filter to another ruleset';
+$labels['copyfromruleset'] = 'Copy filters from existing ruleset';
+$labels['time'] = '時間';
+$labels['weekday'] = '平日';
+$labels['virustest'] = 'Virus Probability';
+$labels['novirus'] = '找不到病毒';
+$labels['virusremoved'] = '發現病毒並移除';
+$labels['viruscured'] = '發現病毒並清除';
+$labels['possiblevirus'] = 'message possibly contains a virus';
+$labels['definitevirus'] = 'message possibly defiantly a virus';
+
+$messages = array();
+$messages['nosieverules'] = '沒有任何規則';
+$messages['filterdeleteconfirm'] = '您確定要刪除這筆郵件規則嗎?';
+$messages['ruledeleteconfirm'] = '您確定要刪除這筆規則條件嗎?';
+$messages['actiondeleteconfirm'] = '您確定要刪除這筆規則動作嗎?';
+$messages['filterunknownerror'] = '未知的伺服器錯誤';
+$messages['filterconnerror'] = '無法連線至sieve伺服器';
+$messages['filterdeleteerror'] = '無法刪除郵件規則。(伺服器錯誤)';
+$messages['filterdeleted'] = '成功刪除郵件規則';
+$messages['filtersaved'] = '郵件規則儲存完必';
+$messages['filtersaveerror'] = '無法儲存郵件規則。(伺服器錯誤)';
+$messages['vacdaysexp'] = 'The period is the number of days during which the message will not be resent to the same user, no matter how many times they contact you.<br /><br />For example: If Joe emails you on Monday and the period is set to 7 then Joe will receive an out of office message on Monday but will not get another one until the following Monday, no matter how many emails he sends an email during the week.';
+$messages['vachandleexp'] = 'A handle can be used to link different out of office messages together, once one message has been sent no other message with the same handle will be resent in that period.';
+$messages['vactoexp'] = 'List of additional recipient addresses which are included in the auto replying. If a mail\'s recipient is not your main address and it\'s not on this list, no message will be sent.';
+$messages['vactoexp_adv'] = 'Separate multiple aliases with a comma (,). For Example: test1@example.com,test2@example.com,test3@example.com';
+$messages['vactoexp_err'] = 'Error: Multiple aliases should be separated with a comma (,)';
+$messages['norulename'] = '請輸入規則名稱';
+$messages['ruleexists'] = '重複的規則名稱。請重新輸入';
+$messages['noheader'] = 'Please enter the name of the header to test';
+$messages['headerbadchars'] = 'Error: Header contains forbidden characters';
+$messages['noheadervalue'] = 'Please enter a value to test the header against';
+$messages['sizewrongformat'] = '錯誤: 郵件大小必須是數字';
+$messages['noredirect'] = '請輸入一個電子郵件位址以便轉寄訊息';
+$messages['redirectaddresserror'] = 'Error: Address appears invalid';
+$messages['noreject'] = 'Please enter a message to send with rejected email';
+$messages['vacnodays'] = 'Please enter a number of days for the period in which the message will not be resent to the same person';
+$messages['vacdayswrongformat'] = 'Error: The period must be a number greater than or equal to 1';
+$messages['vacnomsg'] = 'Please enter some text for your message';
+$messages['notifynomethod'] = 'Please enter a method by which the notification should be sent';
+$messages['notifynomsg'] = 'Please enter some text for your message';
+$messages['sieveruleexp'] = '請定義一個或多個規則條件。每封信都會依照左側列表,採由上而下的順序比對規則條件,如果符合其中一個規則,後續的郵件規則將不被執行。';
+$messages['sieveruleexp_stop'] = 'Please define one or more rules against which each message will be tested. Filters are run in the order in which they appear on the left of this screen until a \'Stop\' action is met.';
+$messages['sieveactexp'] = '請從選單中選擇項目,這些動作將會套用在符合上述規則條件的郵件。';
+$messages['sieveheadershlp'] = 'Below are some examples of other headers that can be tested by the filters. Select a header to add it to the rule or enter a custom one in the box above.';
+$messages['movingfilter'] = '移動郵件規則...';
+$messages['noexistingfilters'] = 'No existing filters detected!';
+$messages['importdefault'] = '<b>Use default filters:</b> There is a set of default filters available. Would you like to use these filters?';
+$messages['importother'] = '<b>Import filters:</b> Another set of filters from %s has been found. Would you like to import these filters into your current set?';
+$messages['switchtoadveditor'] = 'Switching to the advanced editor allows you to edit the sieve file directly. Any changes here may be unreadable in the normal editor and may be lost when filters are saved using the normal editor. Do you wish to continue?';
+$messages['filterimported'] = 'Filter imported successfully';
+$messages['filterimporterror'] = '無法匯入郵件規則。(伺服器錯誤)';
+$messages['notifyinvalidmethod'] = 'The method does not appear to be written in a valid format, it must be a URI. For example: `mailto:alert@example.com`.';
+$messages['nobodycontentpart'] = 'Please enter a content part to test';
+$messages['badoperator'] = 'Sorry the operator you selected cannot be used in this rule';
+$messages['filteractionerror'] = 'The action you requested is not supported by the server';
+$messages['filtermissingerror'] = 'Unable to find the rule requested';
+$messages['contentpartexp'] = 'The MIME-type or specific part of the message which should be tested. For example: `message/rfc822`, `text/html`, `audio/mp3` or `image`.';
+$messages['delrulesetconf'] = 'Are you sure you want to delete this ruleset?';
+$messages['rulesetexists'] = 'A ruleset with this name already exists. Please enter another';
+$messages['copyexisting'] = '<b>Copy exiting ruleset:</b> Would you like to copy filters from an existing ruleset into your current set?';
+$messages['filtercopied'] = 'Filter copied successfully';
+$messages['nosieverulesets'] = 'No rulesets found.';
+$messages['baddateformat'] = 'Error: Please enter the date in the format YYYY-MM-DD';
+$messages['badtimeformat'] = 'Error: Please enter the time in the format HH:MM:SS';
+$messages['missingfoldername'] = '錯誤: 請輸入資料夾名稱';
+
+?> \ No newline at end of file
diff --git a/plugins/sieverules/package.xml b/plugins/sieverules/package.xml
new file mode 100644
index 000000000..1ca73d3f8
--- /dev/null
+++ b/plugins/sieverules/package.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<package xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" packagerversion="1.9.0" version="2.0" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0
+ http://pear.php.net/dtd/tasks-1.0.xsd
+ http://pear.php.net/dtd/package-2.0
+ http://pear.php.net/dtd/package-2.0.xsd">
+ <name>sieverules</name>
+ <uri>http://github.com/JohnDoh/Roundcube-Plugin-SieveRules-Managesieve/</uri>
+ <summary>Control sieve filter settings from within Roundcube</summary>
+ <description>Adds a 'Filters' tab to the 'Personal Settings' to allow the user to manage their Sieve mail rules. Uses the Managesieve protocol. Predefined rules created for the user to select.</description>
+ <lead>
+ <name>Philip Weir</name>
+ <user>JohnDoh</user>
+ <email>roundcube@tehinterweb.co.uk</email>
+ <active>yes</active>
+ </lead>
+ <date>2013-02-24</date>
+ <time>10:16:53</time>
+ <version>
+ <release>1.18</release>
+ <api>1.18</api>
+ </version>
+ <stability>
+ <release>stable</release>
+ <api>stable</api>
+ </stability>
+ <license uri="http://www.gnu.org/licenses/gpl.html">GNU GPLv3+</license>
+ <notes>-</notes>
+ <contents>
+ <dir baseinstalldir="/" name="/">
+ <file name="sieverules.php" role="php">
+ <tasks:replace from="@name@" to="name" type="package-info"/>
+ <tasks:replace from="@package_version@" to="version" type="package-info"/>
+ </file>
+ <file name="sieverules.js" role="data">
+ <tasks:replace from="@name@" to="name" type="package-info"/>
+ <tasks:replace from="@package_version@" to="version" type="package-info"/>
+ </file>
+ <file name="config.inc.php.dist" role="data"/>
+ <file name="CHANGELOG" role="data"/>
+ <file name="README.md" role="data"/>
+ <file name="importFilters/avelsieve.php" role="php"/>
+ <file name="importFilters/ingo.php" role="php"/>
+ <file name="include/rcube_sieve.php" role="php"/>
+ <file name="include/rcube_sieve_script.php" role="php"/>
+ <file name="jquery.maskedinput.js" role="data"/>
+ <file name="lib/Net/Sieve.php" role="php"/>
+ <file name="localization/ca_ES.inc" role="data"/>
+ <file name="localization/cs_CZ.inc" role="data"/>
+ <file name="localization/de_CH.inc" role="data"/>
+ <file name="localization/de_DE.inc" role="data"/>
+ <file name="localization/en_GB.inc" role="data"/>
+ <file name="localization/en_US.inc" role="data"/>
+ <file name="localization/es_AR.inc" role="data"/>
+ <file name="localization/es_ES.inc" role="data"/>
+ <file name="localization/et_EE.inc" role="data"/>
+ <file name="localization/fi_FI.inc" role="data"/>
+ <file name="localization/fr_FR.inc" role="data"/>
+ <file name="localization/hu_HU.inc" role="data"/>
+ <file name="localization/it_IT.inc" role="data"/>
+ <file name="localization/nl_NL.inc" role="data"/>
+ <file name="localization/pl_PL.inc" role="data"/>
+ <file name="localization/pt_BR.inc" role="data"/>
+ <file name="localization/pt_PT.inc" role="data"/>
+ <file name="localization/ro_RO.inc" role="data"/>
+ <file name="localization/ru_RU.inc" role="data"/>
+ <file name="localization/sk_SK.inc" role="data"/>
+ <file name="localization/sl_SI.inc" role="data"/>
+ <file name="localization/sv_SE.inc" role="data"/>
+ <file name="localization/zh_TW.inc" role="data"/>
+ <file name="skins/classic/cross.gif" role="data"/>
+ <file name="skins/classic/help.gif" role="data"/>
+ <file name="skins/classic/icons.gif" role="data"/>
+ <file name="skins/classic/icons.png" role="data"/>
+ <file name="skins/classic/ie6hacks.css" role="data"/>
+ <file name="skins/classic/iehacks.css" role="data"/>
+ <file name="skins/classic/safari.css" role="data"/>
+ <file name="skins/classic/sieverules.css" role="data"/>
+ <file name="skins/classic/tabstyles.css" role="data"/>
+ <file name="skins/classic/templates/advancededitor.html" role="data"/>
+ <file name="skins/classic/templates/editsieverule.html" role="data"/>
+ <file name="skins/classic/templates/setupsieverules.html" role="data"/>
+ <file name="skins/classic/templates/sieverules.html" role="data"/>
+ <file name="skins/classic/tick.gif" role="data"/>
+ <file name="skins/larry/cross.png" role="data"/>
+ <file name="skins/larry/help.png" role="data"/>
+ <file name="skins/larry/icons.png" role="data"/>
+ <file name="skins/larry/iehacks.css" role="data"/>
+ <file name="skins/larry/listicons.png" role="data"/>
+ <file name="skins/larry/safari.css" role="data"/>
+ <file name="skins/larry/sieverules.css" role="data"/>
+ <file name="skins/larry/tabstyles.css" role="data"/>
+ <file name="skins/larry/templates/advancededitor.html" role="data"/>
+ <file name="skins/larry/templates/editsieverule.html" role="data"/>
+ <file name="skins/larry/templates/setupsieverules.html" role="data"/>
+ <file name="skins/larry/templates/sieverules.html" role="data"/>
+ <file name="skins/larry/tick.png" role="data"/>
+ </dir>
+ <!-- / -->
+ </contents>
+ <dependencies>
+ <required>
+ <php>
+ <min>5.2.1</min>
+ </php>
+ <pearinstaller>
+ <min>1.7.0</min>
+ </pearinstaller>
+ <package>
+ <name>jqueryui</name>
+ <uri>http://trac.roundcube.net/browser/trunk/plugins/jqueryui/</uri>
+ <min>1.8.14</min>
+ </package>
+ </required>
+ </dependencies>
+ <phprelease/>
+</package>
diff --git a/plugins/sieverules/sieverules.js b/plugins/sieverules/sieverules.js
new file mode 100644
index 000000000..5ec505869
--- /dev/null
+++ b/plugins/sieverules/sieverules.js
@@ -0,0 +1,1480 @@
+/**
+ * SieveRules plugin script
+ */
+
+rcube_webmail.prototype.sieverules_select = function(list) {
+ if (rcmail.sieverules_examples) rcmail.sieverules_examples.clear_selection();
+ var id;
+
+ if (this.sieverules_timer)
+ clearTimeout(rcmail.sieverules_timer);
+
+ if (id = list.get_single_selection())
+ rcmail.sieverules_timer = window.setTimeout(function() { rcmail.sieverules_load(id, 'plugin.sieverules.edit'); }, 200);
+}
+
+rcube_webmail.prototype.sieverules_keypress = function(list) {
+ if (list.key_pressed == list.DELETE_KEY)
+ rcmail.command('plugin.sieverules.delete');
+ else if (list.key_pressed == list.BACKSPACE_KEY)
+ rcmail.command('plugin.sieverules.delete');
+}
+
+rcube_webmail.prototype.sieverules_ex_select = function(list) {
+ rcmail.sieverules_list.clear_selection();
+ if (list.multi_selecting)
+ return false;
+
+ if (this.sieverules_timer)
+ clearTimeout(this.sieverules_timer);
+
+ var id;
+ if (id = list.get_single_selection())
+ rcmail.sieverules_timer = window.setTimeout(function() { rcmail.sieverules_load(id, 'plugin.sieverules.add'); }, 200);
+}
+
+rcube_webmail.prototype.sieverules_mouse_up = function(e) {
+ if (rcmail.sieverules_list) {
+ if (!rcube_mouse_is_over(e, rcmail.sieverules_list.list))
+ rcmail.sieverules_list.blur();
+ }
+
+ if (rcmail.sieverules_examples) {
+ if (!rcube_mouse_is_over(e, rcmail.sieverules_examples.list))
+ rcmail.sieverules_examples.blur();
+ }
+
+ // handle mouse release when dragging
+ if (rcmail.sieverules_ex_drag_active && rcmail.sieverules_list && rcmail.env.sieverules_last_target) {
+ rcmail.command('plugin.sieverules.import_ex');
+ rcmail.sieverules_examples.draglayer.hide();
+ }
+ else if (rcmail.sieverules_drag_active && rcmail.sieverules_list && rcmail.env.sieverules_last_target) {
+ var _src = rcmail.sieverules_list.get_single_selection();
+
+ if (rcmail.env.sieverules_last_target == 'end') {
+ var _dst = rcmail.sieverules_list.rows.length;
+ $(rcmail.gui_objects.sieverules_list).children('tbody').children('tr:last').removeClass('droptargetend');
+ }
+ else {
+ var _dst = rcmail.env.sieverules_last_target.substr(6);
+ $('#' + rcmail.env.sieverules_last_target).removeClass('droptarget');
+ }
+
+ rcmail.command('plugin.sieverules.move', { source:_src, dest:_dst });
+ rcmail.sieverules_list.draglayer.hide();
+ }
+};
+
+rcube_webmail.prototype.sieverules_ex_drag_start = function(list) {
+ rcmail.sieverules_ex_drag_active = true;
+ rcmail.sieverules_list.drag_active = true;
+ rcmail.sieverules_drag_start(list);
+};
+
+rcube_webmail.prototype.sieverules_drag_start = function(list) {
+ rcmail.sieverules_drag_active = true;
+
+ if (this.sieverules_timer)
+ clearTimeout(this.sieverules_timer);
+
+ if (rcmail.gui_objects.sieverules_list) {
+ rcmail.initialBodyScrollTop = bw.ie ? 0 : window.pageYOffset;
+ rcmail.initialListScrollTop = rcmail.gui_objects.sieverules_list.parentNode.scrollTop;
+
+ var pos, list, rulesTable;
+ list = $(rcmail.gui_objects.sieverules_list.parentNode);
+ pos = list.offset();
+ rcmail.env.sieveruleslist_coords = { x1:pos.left, y1:pos.top, x2:pos.left + list.width(), y2:pos.top + list.height() };
+
+ rows = rcmail.sieverules_list.rows;
+ rcmail.env.sieverules_coords = new Array();
+ for (var i = 0; i < rows.length; i++) {
+ pos = $('#' + rows[i].id).offset();
+ rcmail.env.sieverules_coords[rows[i].id] = { x1:pos.left, y1:pos.top, x2:pos.left + $('#' + rows[i].id).width(), y2:pos.top + $('#' + rows[i].id).height(), on:0 };
+ }
+ }
+};
+
+rcube_webmail.prototype.sieverules_drag_move = function(e) {
+ if (rcmail.gui_objects.sieverules_list && rcmail.env.sieveruleslist_coords) {
+ // offsets to compensate for scrolling while dragging a message
+ var boffset = bw.ie ? -document.documentElement.scrollTop : rcmail.initialBodyScrollTop;
+ var moffset = rcmail.initialListScrollTop-rcmail.gui_objects.sieverules_list.parentNode.scrollTop;
+ var toffset = -moffset-boffset;
+
+ var li, pos, mouse;
+ mouse = rcube_event.get_mouse_pos(e);
+ pos = rcmail.env.sieveruleslist_coords;
+ mouse.y += toffset;
+
+ // if mouse pointer is outside of folderlist
+ if (mouse.x < pos.x1 || mouse.x >= pos.x2 || mouse.y < pos.y1 || mouse.y >= pos.y2) {
+ $(rcmail.gui_objects.sieverules_list).children('tbody').children('tr:last').removeClass('droptargetend');
+ rcmail.env.sieverules_last_target = null;
+ }
+ else {
+ $(rcmail.gui_objects.sieverules_list).children('tbody').children('tr:last').addClass('droptargetend');
+ rcmail.env.sieverules_last_target = 'end';
+ }
+
+ // over the folders
+ for (var k in rcmail.env.sieverules_coords) {
+ pos = rcmail.env.sieverules_coords[k];
+ if (mouse.x >= pos.x1 && mouse.x < pos.x2 && mouse.y >= pos.y1 && mouse.y < pos.y2) {
+ $(rcmail.gui_objects.sieverules_list).children('tbody').children('tr:last').removeClass('droptargetend');
+ $('#' + k).addClass('droptarget');
+ rcmail.env.sieverules_last_target = k;
+ rcmail.env.sieverules_coords[k].on = 1;
+ }
+ else if (pos.on) {
+ $('#' + k).removeClass('droptarget');
+ rcmail.env.sieverules_last_target = null;
+ rcmail.env.sieverules_coords[k].on = 0;
+ }
+ }
+ }
+};
+
+rcube_webmail.prototype.sieverules_drag_end = function(e) {
+ rcmail.sieverules_drag_active = false;
+ rcmail.sieverules_ex_drag_active = false;
+ rcmail.env.sieverules_last_target = null;
+
+ // over the rules
+ if (rcmail.gui_objects.sieverules_list && rcmail.env.sieverules_coords) {
+ for (var k in rcmail.env.sieverules_coords) {
+ if (rcmail.env.sieverules_coords[k].on) {
+ $('#' + k).removeClass('droptarget');
+ }
+ }
+ }
+
+ $(rcmail.gui_objects.sieverules_list).children('tbody').children('tr:last').removeClass('droptargetend');
+};
+
+rcube_webmail.prototype.sieverules_load = function(id, action) {
+ if (action == 'plugin.sieverules.edit' && (!id || id == rcmail.env.iid))
+ return false;
+
+ var add_url = '';
+ var target = window;
+ if (rcmail.env.contentframe && window.frames && window.frames[rcmail.env.contentframe]) {
+ add_url = '&_framed=1';
+ target = window.frames[rcmail.env.contentframe];
+ rcube_find_object(rcmail.env.contentframe).style.visibility = 'inherit';
+ }
+
+ if (action && (id || action == 'plugin.sieverules.add')) {
+ rcmail.set_busy(true);
+ target.location.href = rcmail.env.comm_path+'&_action='+action+'&_iid='+id+add_url;
+ }
+
+ return true;
+}
+
+rcube_webmail.prototype.sieverules_ready = function(id) {
+ if (id.substring(0, 2) != 'ex')
+ rcmail.enable_command('plugin.sieverules.delete', true);
+
+ if (rcmail.sieverules_examples)
+ rcmail.sieverules_examples.clear_selection();
+
+ rcmail.sieverules_list.highlight_row(id);
+ rcmail.env.iid = id;
+
+ return true;
+}
+
+rcube_webmail.prototype.sieverules_update_list = function(action, param1, param2, param3, param4) {
+ var sid = rcmail.sieverules_list.get_single_selection();
+ var selection;
+ var rows = rcmail.sieverules_list.rows;
+ var rules = Array();
+
+ switch(action) {
+ case 'add-first':
+ rcmail.sieverules_list.clear();
+ case 'add':
+ if (rows.length == 1 && rows[0].obj.cells[0].innerHTML == rcmail.gettext('loading',''))
+ rcmail.sieverules_list.remove_row(0);
+
+ var newrow = document.createElement('tr');
+
+ if (param1 == -1) {
+ var cell = document.createElement('td');
+ cell.setAttribute('colspan', '2');
+ cell.appendChild(document.createTextNode(param2));
+ newrow.appendChild(cell);
+ }
+ else {
+ newrow.id = param1;
+ var cell = document.createElement('td');
+ cell.appendChild(document.createTextNode(param2));
+ newrow.appendChild(cell);
+
+ cell = document.createElement('td');
+ cell.className = 'control';
+
+ param3 = param3.replace(/\\'/g, '\'');
+ param4 = param4.replace(/\\'/g, '\'');
+
+ cell.innerHTML = param3 + param4;
+ newrow.appendChild(cell);
+ }
+
+ rcmail.sieverules_list.insert_row(newrow);
+ break;
+ case 'update':
+ rows[param1].obj.cells[0].innerHTML = param2;
+ break;
+ case 'delete':
+ rcmail.sieverules_list.clear_selection();
+ sid = null;
+ case 'reload':
+ rcmail.sieverules_list.clear();
+
+ var newrow = document.createElement('tr');
+ var cell = document.createElement('td');
+ cell.setAttribute('colspan', '2');
+ cell.appendChild(document.createTextNode(rcmail.gettext('loading','')));
+ newrow.appendChild(cell);
+ rcmail.sieverules_list.insert_row(newrow);
+
+ rcmail.http_request('plugin.sieverules.update_list', '', false);
+ break;
+ case 'move':
+ // create array of rules
+ for (var i = 0; i < rows.length; i++) {
+ rules[i] = rows[i].obj.cells[0].innerHTML;
+
+ if (sid == i) selection = rules[i];
+ }
+
+ // assign order
+ rules.splice(param2, 0, rules[param1]);
+
+ if (parseInt(param1) < parseInt(param2))
+ rules.splice(param1, 1);
+ else
+ rules.splice(parseInt(param1) + 1, 1);
+
+ // update table
+ for (var i = 0; i < rows.length; i++) {
+ rows[i].obj.cells[0].innerHTML = rules[i];
+
+ if (rules[i] == selection) sid = i;
+ }
+
+ var target = window;
+ if (rcmail.env.contentframe && window.frames && window.frames[rcmail.env.contentframe])
+ target = window.frames[rcmail.env.contentframe];
+
+ // update iid of rule being editied
+ var iid;
+ if (target.rcube_find_object && (iid = target.rcube_find_object('_iid'))) {
+ if (iid.value != param1 && iid.value != "") {
+ if (iid.value > param1 && iid.value < param2) {
+ sid = parseInt(iid.value) - 1;
+ rcmail.sieverules_list.highlight_row(sid);
+ rcmail.sieverules_list.select_row(sid);
+ iid.value = sid;
+ target.rcmail.env.iid = sid;
+ }
+ else if (iid.value < param1 && iid.value > param2) {
+ sid = parseInt(iid.value) + 1;
+ rcmail.sieverules_list.highlight_row(sid);
+ rcmail.sieverules_list.select_row(sid);
+ iid.value = sid;
+ target.rcmail.env.iid = sid;
+ }
+ else {
+ rcmail.sieverules_list.select_row(iid.value);
+ }
+ }
+ else if (iid.value != "") {
+ rcmail.sieverules_list.highlight_row(sid);
+ rcmail.sieverules_list.select_row(sid);
+ iid.value = sid;
+ target.rcmail.env.iid = sid;
+ }
+ }
+ else if (sid) {
+ rcmail.sieverules_list.highlight_row(sid);
+ rcmail.sieverules_list.select_row(sid);
+ }
+
+ break;
+ }
+}
+
+rcube_webmail.prototype.sieverules_rule_join_radio = function(value) {
+ var rulesTable = rcube_find_object('rules-table');
+
+ if (rulesTable.tBodies[0].rows.length == 3)
+ rcmail.command('plugin.sieverules.add_rule','', rulesTable.tBodies[0].rows[0]);
+
+ rulesTable.style.display = (value == 'any' ? 'none' : '');
+}
+
+rcube_webmail.prototype.sieverules_header_select = function(sel) {
+ var idx = sel.parentNode.parentNode.rowIndex / 3;
+ var eidx = ((idx + 1) * 3) - 1;
+ var obj = document.getElementsByName('_selheader[]')[idx];
+ var testType = obj.value.split('::')[0];
+ var header = obj.value.split('::')[1];
+ var selIdx = 0;
+ var target_obj = $("input[name='_target[]']")[idx];
+
+ document.getElementsByName('_test[]')[idx].value = testType;
+ document.getElementsByName('_header[]')[idx].value = header;
+ document.getElementsByName('_target[]')[idx].className = '';
+ document.getElementsByName('_operator[]')[idx].selectedIndex = 0;
+ document.getElementsByName('_bodypart[]')[idx].style.display = 'none';
+ document.getElementsByName('_datepart[]')[idx].style.display = 'none';
+ document.getElementsByName('_weekday[]')[idx].style.display = 'none';
+ $(target_obj).unmask();
+
+ if (header == 'size') {
+ document.getElementsByName('_header[]')[idx].style.visibility = 'hidden';
+ document.getElementsByName('_headerhlp')[idx].style.visibility = 'hidden';
+ document.getElementsByName('_operator[]')[idx].style.display = 'none';
+ document.getElementsByName('_date_operator[]')[idx].style.display = 'none';
+ document.getElementsByName('_spamtest_operator[]')[idx].style.display = 'none';
+ document.getElementsByName('_spam_probability[]')[idx].style.display = 'none';
+ document.getElementsByName('_virus_probability[]')[idx].style.display = 'none';
+ document.getElementsByName('_size_operator[]')[idx].style.display = '';
+ document.getElementsByName('_target[]')[idx].style.display = '';
+ document.getElementsByName('_target[]')[idx].className = 'short';
+ document.getElementsByName('_units[]')[idx].style.display = '';
+ }
+ else if (header == 'spamtest') {
+ document.getElementsByName('_header[]')[idx].style.visibility = 'hidden';
+ document.getElementsByName('_headerhlp')[idx].style.visibility = 'hidden';
+ document.getElementsByName('_operator[]')[idx].style.display = 'none';
+ document.getElementsByName('_size_operator[]')[idx].style.display = 'none';
+ document.getElementsByName('_date_operator[]')[idx].style.display = 'none';
+ document.getElementsByName('_spamtest_operator[]')[idx].style.display = '';
+ document.getElementsByName('_spam_probability[]')[idx].style.display = '';
+ document.getElementsByName('_virus_probability[]')[idx].style.display = 'none';
+ document.getElementsByName('_target[]')[idx].style.display = 'none';
+ document.getElementsByName('_target[]')[idx].value = document.getElementsByName('_spam_probability[]')[idx].value;
+ document.getElementsByName('_units[]')[idx].style.display = 'none';
+ }
+ else if (header == 'virustest') {
+ document.getElementsByName('_header[]')[idx].style.visibility = 'hidden';
+ document.getElementsByName('_headerhlp')[idx].style.visibility = 'hidden';
+ document.getElementsByName('_operator[]')[idx].style.display = 'none';
+ document.getElementsByName('_size_operator[]')[idx].style.display = 'none';
+ document.getElementsByName('_date_operator[]')[idx].style.display = 'none';
+ document.getElementsByName('_spamtest_operator[]')[idx].style.display = '';
+ document.getElementsByName('_spam_probability[]')[idx].style.display = 'none';
+ document.getElementsByName('_virus_probability[]')[idx].style.display = '';
+ document.getElementsByName('_target[]')[idx].style.display = 'none';
+ document.getElementsByName('_target[]')[idx].value = document.getElementsByName('_spam_probability[]')[idx].value;
+ document.getElementsByName('_units[]')[idx].style.display = 'none';
+ }
+ else if (header.indexOf('predefined_') == 0) {
+ document.getElementsByName('_header[]')[idx].style.visibility = 'hidden';
+ document.getElementsByName('_headerhlp')[idx].style.visibility = 'hidden';
+ document.getElementsByName('_operator[]')[idx].style.display = 'none';
+ document.getElementsByName('_size_operator[]')[idx].style.display = 'none';
+ document.getElementsByName('_date_operator[]')[idx].style.display = 'none';
+ document.getElementsByName('_spamtest_operator[]')[idx].style.display = 'none';
+ document.getElementsByName('_spam_probability[]')[idx].style.display = 'none';
+ document.getElementsByName('_virus_probability[]')[idx].style.display = 'none';
+ document.getElementsByName('_target[]')[idx].style.display = 'none';
+ document.getElementsByName('_units[]')[idx].style.display = 'none';
+
+ if (rcmail.env.predefined_rules[header.substring(11)][0] == 'size') {
+ document.getElementsByName('_header[]')[idx].value = 'size';
+ selIdx = rcmail.sieverules_get_index(document.getElementsByName('_size_operator[]')[idx], rcmail.env.predefined_rules[header.substring(11)][2]);
+ document.getElementsByName('_size_operator[]')[idx].selectedIndex = selIdx;
+ var reg = new RegExp('^([0-9]+)(K|M)*$');
+ var matches = reg.exec(rcmail.env.predefined_rules[header.substring(11)][3]);
+ document.getElementsByName('_target[]')[idx].value = matches[1];
+ selIdx = rcmail.sieverules_get_index(document.getElementsByName('_units[]')[idx], matches[2]);
+ document.getElementsByName('_units[]')[idx].selectedIndex = selIdx;
+ }
+ else if (rcmail.env.predefined_rules[header.substring(11)][0] == 'spamtest') {
+ document.getElementsByName('_header[]')[idx].value = 'spamtest';
+ selIdx = rcmail.sieverules_get_index(document.getElementsByName('_spamtest_operator[]')[idx], rcmail.env.predefined_rules[header.substring(11)][2]);
+ document.getElementsByName('_spamtest_operator[]')[idx].selectedIndex = selIdx;
+ document.getElementsByName('_spam_probability[]')[idx].value = rcmail.env.predefined_rules[header.substring(11)][3];
+ }
+ else if (rcmail.env.predefined_rules[header.substring(11)][0] == 'virustest') {
+ document.getElementsByName('_header[]')[idx].value = 'virustest';
+ selIdx = rcmail.sieverules_get_index(document.getElementsByName('_spamtest_operator[]')[idx], rcmail.env.predefined_rules[header.substring(11)][2]);
+ document.getElementsByName('_spamtest_operator[]')[idx].selectedIndex = selIdx;
+ document.getElementsByName('_virus_probability[]')[idx].value = rcmail.env.predefined_rules[header.substring(11)][3];
+ }
+ else {
+ document.getElementsByName('_header[]')[idx].value = rcmail.env.predefined_rules[header.substring(11)][1];
+ selIdx = rcmail.sieverules_get_index(document.getElementsByName('_operator[]')[idx], rcmail.env.predefined_rules[header.substring(11)][2], -1);
+
+ // check advanced options if standard not found
+ if (selIdx == -1 && rcmail.sieverules_get_index(document.getElementsByName('_advoperator[]')[idx], rcmail.env.predefined_rules[header.substring(11)][2], -1) > -1) {
+ document.getElementsByName('_operator[]')[idx].selectedIndex = rcmail.sieverules_get_index(document.getElementsByName('_operator[]')[idx], 'advoptions');
+ document.getElementsByName('_advoperator[]')[idx].selectedIndex = rcmail.sieverules_get_index(document.getElementsByName('_advoperator[]')[idx], rcmail.env.predefined_rules[header.substring(11)][2]);
+ document.getElementsByName('_comparator[]')[idx].selectedIndex = rcmail.sieverules_get_index(document.getElementsByName('_comparator[]')[idx], rcmail.env.predefined_rules[header.substring(11)][3]);
+ document.getElementsByName('_advtarget[]')[idx].value = rcmail.env.predefined_rules[header.substring(11)][4];
+ }
+ else {
+ document.getElementsByName('_operator[]')[idx].selectedIndex = selIdx;
+ document.getElementsByName('_target[]')[idx].value = rcmail.env.predefined_rules[header.substring(11)][4];
+ }
+ }
+ }
+ else {
+ document.getElementsByName('_operator[]')[idx].style.display = '';
+ document.getElementsByName('_size_operator[]')[idx].style.display = 'none';
+ document.getElementsByName('_spamtest_operator[]')[idx].style.display = 'none';
+ document.getElementsByName('_spam_probability[]')[idx].style.display = 'none';
+ document.getElementsByName('_virus_probability[]')[idx].style.display = 'none';
+ document.getElementsByName('_date_operator[]')[idx].style.display = 'none';
+ document.getElementsByName('_target[]')[idx].style.display = '';
+ document.getElementsByName('_units[]')[idx].style.display = 'none';
+
+ if (header == 'other') {
+ document.getElementsByName('_header[]')[idx].style.visibility = 'visible';
+ document.getElementsByName('_headerhlp')[idx].style.visibility = 'visible';
+ document.getElementsByName('_header[]')[idx].value = '';
+ }
+ else {
+ document.getElementsByName('_header[]')[idx].style.visibility = 'hidden';
+ document.getElementsByName('_headerhlp')[idx].style.visibility = 'hidden';
+ }
+
+ if (header == 'body') {
+ document.getElementsByName('_header[]')[idx].style.display = 'none';
+ document.getElementsByName('_headerhlp')[idx].style.display = 'none';
+ document.getElementsByName('_bodypart[]')[idx].style.display = '';
+
+ document.getElementsByName('_body_contentpart[]')[idx].parentNode.parentNode.style.display = '';
+ }
+ else if (testType == 'date') {
+ document.getElementsByName('_header[]')[idx].style.display = 'none';
+ document.getElementsByName('_headerhlp')[idx].style.display = 'none';
+ document.getElementsByName('_datepart[]')[idx].style.display = '';
+ document.getElementsByName('_operator[]')[idx].style.display = 'none';
+ document.getElementsByName('_date_operator[]')[idx].style.display = '';
+
+ document.getElementsByName('_datepart[]')[idx].selectedIndex = 0;
+ document.getElementsByName('_body_contentpart[]')[idx].parentNode.parentNode.style.display = 'none';
+ $(target_obj).datepicker({ dateFormat: 'yy-mm-dd' });
+ }
+ else {
+ document.getElementsByName('_header[]')[idx].style.display = '';
+ document.getElementsByName('_headerhlp')[idx].style.display = '';
+
+ document.getElementsByName('_body_contentpart[]')[idx].parentNode.parentNode.style.display = 'none';
+ }
+ }
+
+ var idx = sel.parentNode.parentNode.rowIndex;
+ rcube_find_object('rules-table').tBodies[0].rows[idx + 1].style.display = 'none';
+ rcube_find_object('rules-table').tBodies[0].rows[idx + 2].style.display = 'none';
+}
+
+rcube_webmail.prototype.sieverules_bodypart_select = function(sel) {
+ var idx = sel.parentNode.parentNode.rowIndex;
+ var eidx = idx / 3;
+ var obj = document.getElementsByName('_bodypart[]')[eidx];
+
+ document.getElementsByName('_body_contentpart[]')[eidx].disabled = false;
+ document.getElementsByName('_advoperator[]')[eidx].disabled = (document.getElementsByName('_operator[]')[eidx].value == 'advoptions') ? false : true;
+
+ if (document.getElementsByName('_operator[]')[eidx].value == 'advoptions')
+ rcmail.sieverules_rule_advop_select(document.getElementsByName('_advoperator[]')[eidx]);
+ else
+ document.getElementsByName('_comparator[]')[eidx].disabled = true;
+
+ document.getElementsByName('_advtarget[]')[eidx].disabled = (document.getElementsByName('_operator[]')[eidx].value == 'advoptions') ? false : true;
+ var advopts_row = rcube_find_object('rules-table').tBodies[0].rows[idx + 2];
+ if (obj.value != 'content' && document.getElementsByName('_operator[]')[eidx].value == 'advoptions')
+ document.getElementsByName('_body_contentpart[]')[eidx].disabled = true;
+ else
+ advopts_row.style.display = (obj.value == 'content' ? '' : 'none');
+}
+
+rcube_webmail.prototype.sieverules_datepart_select = function(sel) {
+ var idx = sel.parentNode.parentNode.rowIndex;
+ var eidx = idx / 3;
+ var obj = document.getElementsByName('_datepart[]')[eidx];
+ var opr = document.getElementsByName('_operator[]')[eidx];
+ var target_obj = $("input[name='_target[]']")[eidx];
+ $(target_obj).datepicker("destroy");
+ $(target_obj).unmask();
+
+ if (obj.value == 'date')
+ $(target_obj).datepicker({ dateFormat: 'yy-mm-dd' });
+ else if (obj.value == 'time')
+ $(target_obj).mask('99:99:99', {example: 'HH:MM:SS', placeholder: '0'});
+
+ document.getElementsByName('_advtarget[]')[eidx].style.display = (obj.value == 'weekday') ? 'none' : '';
+ document.getElementsByName('_advweekday[]')[eidx].style.display = (obj.value == 'weekday') ? '' : 'none';
+ if (opr.value != 'exists' && opr.value != 'notexists' && opr.value != 'advoptions') {
+ document.getElementsByName('_target[]')[eidx].style.display = (obj.value == 'weekday') ? 'none' : '';
+ document.getElementsByName('_weekday[]')[eidx].style.display = (obj.value == 'weekday') ? '' : 'none';
+ }
+}
+
+rcube_webmail.prototype.sieverules_rule_op_select = function(sel) {
+ var idx = sel.parentNode.parentNode.rowIndex;
+ var eidx = idx / 3;
+ var datepart = document.getElementsByName('_datepart[]')[eidx].value;
+
+ var obj = document.getElementsByName('_operator[]')[eidx];
+ if (obj.value == 'exists' || obj.value == 'notexists' || obj.value == 'advoptions') {
+ document.getElementsByName('_target[]')[eidx].style.display = 'none';
+ document.getElementsByName('_weekday[]')[eidx].style.display = 'none';
+ }
+ else {
+ document.getElementsByName('_target[]')[eidx].style.display = (datepart == 'weekday') ? 'none' : '';
+ document.getElementsByName('_weekday[]')[eidx].style.display = (datepart == 'weekday') ? '' : 'none';
+ }
+
+ if (obj.value != 'exists' && obj.value != 'notexists' && document.getElementsByName('_test[]')[eidx].value == 'exists') {
+ var h_obj = document.getElementsByName('_selheader[]')[eidx];
+ var testType = h_obj.value.split('::')[0];
+
+ document.getElementsByName('_test[]')[eidx].value = testType;
+ }
+
+ document.getElementsByName('_body_contentpart[]')[eidx].disabled = (document.getElementsByName('_bodypart[]')[eidx].value == 'content') ? false : true;
+ document.getElementsByName('_advoperator[]')[eidx].disabled = false;
+ rcmail.sieverules_rule_advop_select(document.getElementsByName('_advoperator[]')[eidx]);
+ document.getElementsByName('_advtarget[]')[eidx].disabled = false;
+ var advopts_row = rcube_find_object('rules-table').tBodies[0].rows[idx + 2];
+ if (obj.value != 'advoptions' && document.getElementsByName('_bodypart[]')[eidx].value == 'content') {
+ document.getElementsByName('_advoperator[]')[eidx].disabled = true;
+ document.getElementsByName('_comparator[]')[eidx].disabled = true;
+ document.getElementsByName('_advtarget[]')[eidx].disabled = true;
+ }
+ else {
+ advopts_row.style.display = (obj.value == 'advoptions' ? '' : 'none');
+ }
+
+ return false;
+}
+
+rcube_webmail.prototype.sieverules_rule_advop_select = function(sel) {
+ var obj = sel.parentNode.parentNode.parentNode.parentNode;
+ var idx = (obj.parentNode.parentNode.rowIndex - 2) / 3;
+
+ if (sel.value.substring(0, 5) == 'count' || sel.value.substring(0, 5) == 'value')
+ document.getElementsByName('_comparator[]')[idx].disabled = false;
+ else
+ document.getElementsByName('_comparator[]')[idx].disabled = true;
+
+ return false;
+}
+
+rcube_webmail.prototype.sieverules_action_select = function(sel) {
+ var idx = sel.parentNode.parentNode.rowIndex;
+ var actoion_row = rcube_find_object('actions-table').tBodies[0].rows[idx];
+ var obj = document.getElementsByName('_act[]')[idx];
+
+ // hide everything
+ document.getElementsByName('_folder[]')[idx].style.display = 'none';
+ $(document.getElementsByName('_customfolder[]')[idx]).parent().hide();
+ document.getElementsByName('_redirect[]')[idx].style.display = 'none';
+ document.getElementsByName('_reject[]')[idx].style.display = 'none';
+ document.getElementsByName('_imapflags[]')[idx].style.display = 'none';
+ document.getElementsByName('_day[]')[idx].parentNode.parentNode.parentNode.parentNode.style.display = 'none';
+ document.getElementsByName('_nmethod[]')[idx].parentNode.parentNode.parentNode.parentNode.style.display = 'none';
+ document.getElementsByName('_eheadname[]')[idx].parentNode.parentNode.parentNode.parentNode.style.display = 'none';
+
+ if (obj.value == 'fileinto' || obj.value == 'fileinto_copy')
+ document.getElementsByName('_folder[]')[idx].style.display = '';
+ else if (obj.value == 'reject' || obj.value == 'ereject')
+ document.getElementsByName('_reject[]')[idx].style.display = '';
+ else if (obj.value == 'vacation') {
+ document.getElementsByName('_day[]')[idx].parentNode.parentNode.parentNode.parentNode.style.display = '';
+
+ if (rcmail.env.sieverules_htmleditor == 1) {
+ rowid = document.getElementsByName('_msg[]')[idx].id.replace('rcmfd_sievevacmag_', '');
+ document.getElementById('rcmfd_sievevachtmlcb_' + rowid).checked = true;
+ rcmail.sieverules_toggle_vac_html(document.getElementById('rcmfd_sievevachtmlcb_' + rowid), rowid, 'rcmfd_sievevacmag_' + rowid);
+ }
+
+ rcmail.enable_sig(document.getElementsByName('_vacfrom[]')[idx]);
+ }
+ else if (obj.value == 'notify' || obj.value == 'enotify')
+ document.getElementsByName('_nmethod[]')[idx].parentNode.parentNode.parentNode.parentNode.style.display = '';
+ else if (obj.value == 'redirect' || obj.value == 'redirect_copy')
+ document.getElementsByName('_redirect[]')[idx].style.display = '';
+ else if (obj.value == 'imapflags' || obj.value == 'imap4flags')
+ document.getElementsByName('_imapflags[]')[idx].style.display = '';
+ else if (obj.value == 'editheaderadd' || obj.value == 'editheaderrem') {
+ document.getElementsByName('_eheadname[]')[idx].parentNode.parentNode.parentNode.parentNode.style.display = '';
+
+ if (obj.value == 'editheaderrem') {
+ document.getElementsByName('_eheadval[]')[idx].parentNode.parentNode.style.display = 'none';
+ document.getElementsByName('_eheadaddlast[]')[idx].parentNode.parentNode.style.display = 'none';
+ document.getElementsByName('_hadv_opts[]')[idx].parentNode.parentNode.style.display = '';
+ }
+ else {
+ document.getElementsByName('_eheadval[]')[idx].parentNode.parentNode.style.display = '';
+ document.getElementsByName('_eheadaddlast[]')[idx].parentNode.parentNode.style.display = '';
+ document.getElementsByName('_eheadopp[]')[idx].parentNode.parentNode.style.display = 'none';
+ document.getElementsByName('_eheadindex[]')[idx].parentNode.parentNode.style.display = 'none';
+ document.getElementsByName('_hadv_opts[]')[idx].parentNode.parentNode.style.display = 'none';
+ }
+ }
+
+ if ($(document.getElementsByName('_folder[]')[idx]).is(':visible') && document.getElementsByName('_folder[]')[idx].value == '@@newfolder')
+ $(document.getElementsByName('_customfolder[]')[idx]).parent().show();
+}
+
+rcube_webmail.prototype.sieverules_select_folder = function(sel) {
+ var idx = sel.parentNode.parentNode.rowIndex;
+ var actoion_row = rcube_find_object('actions-table').tBodies[0].rows[idx];
+ var obj = document.getElementsByName('_folder[]')[idx];
+
+ $(document.getElementsByName('_customfolder[]')[idx]).parent().hide();
+ if (obj.value == '@@newfolder')
+ $(document.getElementsByName('_customfolder[]')[idx]).parent().show();
+}
+
+rcube_webmail.prototype.sieverules_xheaders = function(sel) {
+ var idx = sel.parentNode.parentNode.rowIndex + 1;
+ var xheader_row = rcube_find_object('rules-table').tBodies[0].rows[idx];
+ xheader_row.style.display = (xheader_row.style.display == 'none' ? '' : 'none');
+ return false;
+}
+
+rcube_webmail.prototype.sieverules_set_xheader = function(sel) {
+ var obj = sel.parentNode.parentNode.parentNode.parentNode;
+ var idx = (obj.parentNode.parentNode.rowIndex - 1) / 3;
+ var headerBox = document.getElementsByName('_header[]')[idx];
+ headerBox.value = sel.value;
+}
+
+rcube_webmail.prototype.sieverules_get_index = function(list, value, fallback) {
+ fallback = fallback || 0;
+
+ for (var i = 0; i < list.length; i++) {
+ if (list[i].value == value)
+ return i;
+ }
+
+ return fallback;
+}
+
+rcube_webmail.prototype.sieverules_toggle_vac_to = function(sel, id) {
+ var obj = rcube_find_object('rcmfd_sievevacto_' + id);
+ var opts = document.getElementsByName('_vacto_check_' + id + '[]')
+
+ obj.value = "";
+ for (i = 0; i < opts.length; i++) {
+ if (opts[i].checked) {
+ if (obj.value.length > 0) obj.value += ",";
+ obj.value += opts[i].value;
+ }
+ }
+}
+
+rcube_webmail.prototype.sieverules_toggle_vac_osubj = function(sel, id) {
+ var obj = rcube_find_object('rcmfd_sievevactoh_' + id);
+ obj.value = sel.checked ? sel.value : "";
+}
+
+rcube_webmail.prototype.sieverules_toggle_vac_html = function(obj, rowid, txtid) {
+ rcmail_toggle_editor(obj, txtid);
+
+ var sel = rcube_find_object('rcmfd_sievevachtmlhd_' + rowid);
+ sel.value = obj.checked ? obj.value : "";
+}
+
+rcube_webmail.prototype.sieverules_notify_impt = function(sel, id) {
+ var obj = rcube_find_object('rcmfd_sievenimpt_' + id);
+ obj.value = sel.value == 'none' ? '' : sel.value;
+}
+
+rcmail.sieverules_help = function(sel, row) {
+ var obj = sel.parentNode.parentNode.parentNode.parentNode;
+ var help_row = obj.tBodies[0].rows[row];
+ help_row.style.display = (help_row.style.display == 'none' ? '' : 'none');
+ return false;
+}
+
+rcube_webmail.prototype.sieverules_show_adv = function(sel) {
+ var obj = sel.parentNode.parentNode.parentNode.parentNode;
+ var rows = obj.tBodies[0].rows;
+
+ if (sel.checked) {
+ for(var i = 0; i < rows.length; i++)
+ if(rows[i].className && rows[i].className.match(/advanced/))
+ rows[i].style.display = '';
+ }
+ else {
+ for(var i = 0; i < rows.length; i++)
+ if(rows[i].className && rows[i].className.match(/advanced/))
+ rows[i].style.display = 'none';
+
+ for(var i = 0; i < rows.length; i++)
+ if(rows[i].className && rows[i].className.match(/advhelp/))
+ rows[i].style.display = 'none';
+ }
+}
+
+rcube_webmail.prototype.sieverules_adveditor = function(sel) {
+ if (sel.checked && !confirm(rcmail.gettext('switchtoadveditor','sieverules'))) {
+ sel.checked = false;
+ return false;
+ }
+
+ if (sel.checked)
+ rcmail.goto_url('plugin.sieverules.advanced', '', true);
+ else
+ rcmail.goto_url('plugin.sieverules', '_override=1', true);
+}
+
+rcube_webmail.prototype.sieverules_load_setup = function() {
+ var add_url = '';
+
+ var target = window;
+ if (rcmail.env.contentframe && window.frames && window.frames[rcmail.env.contentframe]) {
+ add_url = '&_framed=1';
+ target = window.frames[rcmail.env.contentframe];
+ rcube_find_object(rcmail.env.contentframe).style.visibility = 'inherit';
+ }
+
+ target.location.href = rcmail.env.comm_path+'&_action=plugin.sieverules.setup' + add_url;
+}
+
+rcube_webmail.prototype.sieverules_select_ruleset = function(obj, action) {
+ if (typeof obj == 'string') {
+ window.location.href = rcmail.env.comm_path+'&_action='+action+'&_ruleset=' + obj;
+ }
+ else {
+ var idx = obj.selectedIndex;
+ window.location.href = rcmail.env.comm_path+'&_action='+action+'&_ruleset=' + obj.options[idx].value;
+ }
+}
+
+rcube_webmail.prototype.sieverules_add_ruleset = function(val, text) {
+ var obj = rcube_find_object('rulelist');
+
+ // remove loading message
+ if (obj.options.length == 1 && obj.options[0].value == '' && obj.options[0].text == rcmail.gettext('loading',''))
+ obj.remove(0);
+
+ var opt = document.createElement('option');
+ opt.value = val;
+ opt.text = text;
+
+ obj.options.add(opt);
+
+ if (rcmail.env.ruleset == val)
+ obj.selectedIndex = obj.options.length - 1;
+}
+
+rcube_webmail.prototype.sieverules_disable_ruleset_options = function() {
+ $('#rulelist').attr("disabled", "disabled");
+ rcmail.enable_command('plugin.sieverules.ruleset_dialog', 'plugin.sieverules.activate_ruleset', 'plugin.sieverules.del_ruleset', false);
+}
+
+rcube_webmail.prototype.sieverulesdialog_submit = function() {
+ var action = rcube_find_object('sieverulesrsdialog_action').value;
+ var val = rcube_find_object('sieverulesrsdialog_name').value;
+
+ if (action == '' || action == 'rename_ruleset') {
+ var obj = rcube_find_object('sieverulesrsdialog_ruleset');
+ for (i = 0; i < obj.options.length ; i++) {
+ if (obj.options[i].value == val) {
+ alert(rcmail.gettext('rulesetexists','sieverules'));
+ rcube_find_object('sieverulesrsdialog_name').focus();
+ return false;
+ }
+ }
+ }
+ else if (action == 'copyto_ruleset' || action == 'copyfrom_ruleset') {
+ var obj = rcube_find_object('sieverulesrsdialog_ruleset');
+ var idx = obj.selectedIndex;
+ val = obj.options[idx].value;
+ }
+
+ $('#sieverulesrsdialog').dialog('close');
+
+ var target = window;
+ if (rcmail.env.contentframe && window.frames && window.frames[rcmail.env.contentframe])
+ target = window.frames[rcmail.env.contentframe];
+
+ if (action == 'rename_ruleset')
+ window.location.href = rcmail.env.comm_path+'&_action=plugin.sieverules.rename_ruleset&_ruleset=' + rcmail.env.ruleset + '&_new=' + val;
+ else if (action == 'copyto_ruleset')
+ rcmail.http_request('plugin.sieverules.copy_filter', '_iid='+ target.rcmail.env.iid +'&_dest=' + val, true);
+ else if (action == 'copyfrom_ruleset')
+ window.location.href = rcmail.env.comm_path+'&_action=plugin.sieverules.import&_import=_copy_&_ruleset=' + val + '&_new=' + rcmail.env.ruleset;
+ else
+ window.location.href = rcmail.env.comm_path+'&_action=plugin.sieverules&_ruleset=' + val;
+}
+
+rcube_webmail.prototype.enable_sig = function(obj) {
+ var id;
+
+ if (obj.options[0].value == 'auto' || obj.options[0].value == '')
+ id = obj.selectedIndex;
+ else
+ id = obj.selectedIndex + 1;
+
+ // enable manual signature insert
+ if (rcmail.env.signatures && rcmail.env.signatures[id])
+ rcmail.enable_command('plugin.sieverules.vacation_sig', true);
+ else
+ rcmail.enable_command('plugin.sieverules.vacation_sig', false);
+}
+
+rcube_webmail.prototype.sieverules_toggle_eheadlast = function(obj) {
+ var selectobj = document.getElementById(obj.id.replace('_eheadaddlast_', '_eheadindex_'));
+
+ if (obj.checked)
+ selectobj.selectedIndex = 6;
+ else
+ selectobj.selectedIndex = 0;
+}
+
+$(document).ready(function() {
+ if (window.rcmail) {
+ rcmail.addEventListener('init', function(evt) {
+ if (rcmail.env.action == 'plugin.sieverules.add' || rcmail.env.action == 'plugin.sieverules.edit' || rcmail.env.action == 'plugin.sieverules.setup' || rcmail.env.action == 'plugin.sieverules.advanced')
+ var tab = $('<span>').attr('id', 'settingstabpluginsieverules').addClass('tablink selected');
+ else
+ var tab = $('<span>').attr('id', 'settingstabpluginsieverules').addClass('tablink');
+
+ var button = $('<a>').attr('href', rcmail.env.comm_path+'&_action=plugin.sieverules').attr('title', rcmail.gettext('managefilters', 'sieverules')).html(rcmail.gettext('filters','sieverules')).appendTo(tab);
+
+ // add button and register command
+ rcmail.add_element(tab, 'tabs');
+
+ if ((rcmail.env.action == 'plugin.sieverules' || rcmail.env.action == 'plugin.sieverules.advanced') && !rcmail.env.sieveruleserror) {
+ if (rcmail.gui_objects.sieverules_list) {
+ rcmail.sieverules_list = new rcube_list_widget(rcmail.gui_objects.sieverules_list, {multiselect:false, draggable:true, keyboard:true});
+
+ // override blur function to prevent current rule being deselected
+ rcmail.sieverules_list.blur = function() {}
+
+ rcmail.sieverules_list.addEventListener('select', function(o) { rcmail.sieverules_select(o); });
+ rcmail.sieverules_list.addEventListener('keypress', function(o) { rcmail.sieverules_keypress(o); });
+ rcmail.sieverules_list.addEventListener('dragstart', function(o) { rcmail.sieverules_drag_start(o); });
+ rcmail.sieverules_list.addEventListener('dragmove', function(e) { rcmail.sieverules_drag_move(e); });
+ rcmail.sieverules_list.addEventListener('dragend', function(e) { rcmail.sieverules_drag_end(e); });
+ document.onmouseup = function(e) { return rcmail.sieverules_mouse_up(e); };
+ rcmail.sieverules_list.init();
+ rcmail.sieverules_list.focus();
+
+ if (rcmail.env.iid && rcmail.env.iid < rcmail.sieverules_list.rows.length && !rcmail.env.eid)
+ rcmail.sieverules_list.select_row(rcmail.env.iid, false, false);
+ }
+
+ if (rcmail.gui_objects.sieverules_examples) {
+ rcmail.sieverules_examples = new rcube_list_widget(rcmail.gui_objects.sieverules_examples, {multiselect:true, draggable:true, keyboard:true});
+ rcmail.sieverules_examples.addEventListener('select', function(o) { rcmail.sieverules_ex_select(o); });
+ rcmail.sieverules_examples.addEventListener('dragstart', function(o) { rcmail.sieverules_ex_drag_start(o); });
+ rcmail.sieverules_examples.addEventListener('dragmove', function(e) { rcmail.sieverules_drag_move(e); });
+ rcmail.sieverules_examples.addEventListener('dragend', function(e) { rcmail.sieverules_drag_end(e); });
+ rcmail.sieverules_examples.init();
+
+ if (rcmail.env.eid)
+ rcmail.sieverules_examples.highlight_row(rcmail.env.eid);
+
+ rcmail.register_command('plugin.sieverules.import_ex', function() {
+ if (rcmail.sieverules_examples.get_selection().length > 0) {
+ rcmail.set_busy(true, 'sieverules.movingfilter');
+ rcmail.goto_url('plugin.sieverules.import', '_import=_example_&_pos='+ rcmail.env.sieverules_last_target +'&_eids=' + rcmail.sieverules_examples.get_selection(), true);
+ }
+ }, true);
+ }
+
+ if (rcmail.env.action == 'plugin.sieverules') {
+ rcmail.register_command('plugin.sieverules.move', function(props, obj) {
+ var args = (props.source) ? props : { source:obj.parentNode.parentNode.rowIndex - 1, dest:props };
+
+ if (args.dest > -1 && args.dest <= rcmail.sieverules_list.rows.length) {
+ var lock = rcmail.set_busy(true, 'sieverules.movingfilter');
+ rcmail.http_request('plugin.sieverules.move', '_src=' + args.source + '&_dst=' + args.dest, lock);
+ }
+ }, true);
+
+ rcmail.register_command('plugin.sieverules.add', function(id) {
+ if (rcmail.sieverules_examples) rcmail.sieverules_examples.clear_selection();
+ rcmail.sieverules_list.clear_selection();
+ rcmail.env.iid = null;
+ rcmail.enable_command('plugin.sieverules.delete', false);
+
+ var add_url = '';
+
+ var target = window;
+ if (rcmail.env.contentframe && window.frames && window.frames[rcmail.env.contentframe]) {
+ add_url = '&_framed=1';
+ target = window.frames[rcmail.env.contentframe];
+ rcube_find_object(rcmail.env.contentframe).style.visibility = 'inherit';
+ }
+
+ target.location.href = rcmail.env.comm_path+'&_action=plugin.sieverules.add' + add_url;
+ }, true);
+ }
+
+ rcmail.register_command('plugin.sieverules.ruleset_dialog', function(props, obj) {
+ rcube_find_object('sieverulesrsdialog_add').style.display = 'none';
+ rcube_find_object('sieverulesrsdialog_edit').style.display = 'none';
+ rcube_find_object('sieverulesrsdialog_copyto').style.display = 'none';
+ rcube_find_object('sieverulesrsdialog_copyfrom').style.display = 'none';
+ rcube_find_object('sieverulesrsdialog_input').style.display = 'none';
+ rcube_find_object('sieverulesrsdialog_select').style.display = 'none';
+ rcube_find_object('sieverulesrsdialog_name').value = '';
+
+ if (props == 'rename_ruleset') {
+ //rcube_find_object('sieverulesrsdialog_edit').style.display = '';
+ boxtitle = rcube_find_object('sieverulesrsdialog_edit').innerHTML;
+ rcube_find_object('sieverulesrsdialog_input').style.display = '';
+ rcube_find_object('sieverulesrsdialog_name').value = rcmail.env.ruleset;
+ }
+ else if (props == 'copyto_ruleset') {
+ //rcube_find_object('sieverulesrsdialog_copyto').style.display = '';
+ boxtitle = rcube_find_object('sieverulesrsdialog_copyto').innerHTML;
+ rcube_find_object('sieverulesrsdialog_select').style.display = '';
+ }
+ else if (props == 'copyfrom_ruleset') {
+ //rcube_find_object('sieverulesrsdialog_copyfrom').style.display = '';
+ boxtitle = rcube_find_object('sieverulesrsdialog_copyfrom').innerHTML;
+ rcube_find_object('sieverulesrsdialog_select').style.display = '';
+ }
+ else {
+ //rcube_find_object('sieverulesrsdialog_add').style.display = '';
+ boxtitle = rcube_find_object('sieverulesrsdialog_add').innerHTML;
+ rcube_find_object('sieverulesrsdialog_input').style.display = '';
+ }
+
+ rcube_find_object('sieverulesrsdialog_action').value = props;
+
+ $('#sieverulesrsdialog').dialog({ title: boxtitle, width: 512, resizable: false, modal: true });
+ }, true);
+
+ rcmail.register_command('plugin.sieverules.activate_ruleset', function(props, obj) {
+ rcmail.set_busy(true);
+
+ var obj = rcube_find_object('rulelist');
+ if (obj) {
+ rcmail.http_request('plugin.sieverules.enable_ruleset', '_ruleset=' + rcmail.env.ruleset, true);
+ obj.options.length = 0;
+
+ var opt = document.createElement('option');
+ opt.value = '';
+ opt.text = rcmail.gettext('loading','');
+
+ obj.options.add(opt);
+ rcmail.enable_command('plugin.sieverules.activate_ruleset', false);
+ }
+ else {
+ window.location.href = rcmail.env.comm_path+'&_action=plugin.sieverules.enable_ruleset&_reload=1&_ruleset=' + rcmail.env.ruleset;
+ }
+ }, false);
+
+ rcmail.register_command('plugin.sieverules.del_ruleset', function(props, obj) {
+ if (rcmail.env.ruleset_total < 2)
+ return false;
+
+ if (confirm(rcmail.gettext('delrulesetconf','sieverules')))
+ window.location.href = rcmail.env.comm_path+'&_action=plugin.sieverules.del_ruleset&_ruleset=' + rcmail.env.ruleset + '&_next=' + rcmail.env.ruleset_next;
+ }, false);
+
+ rcmail.register_command('plugin.sieverules.sieverules_adveditor', function(props, obj) {
+ var chkbox = document.createElement('checkbox');
+
+ if (props == "1")
+ chkbox.checked = true;
+
+ rcmail.sieverules_adveditor(chkbox);
+ }, true);
+
+ rcmail.register_command('plugin.sieverules.delete', function(id) {
+ if (confirm(rcmail.gettext('filterdeleteconfirm','sieverules'))) {
+ var add_url = '';
+
+ var target = window;
+ if (rcmail.env.contentframe && window.frames && window.frames[rcmail.env.contentframe]) {
+ add_url = '&_framed=1';
+ target = window.frames[rcmail.env.contentframe];
+ rcube_find_object(rcmail.env.contentframe).style.visibility = 'inherit';
+ }
+
+ target.location.href = rcmail.env.comm_path+'&_action=plugin.sieverules.delete&_iid=' + rcmail.env.iid + add_url;
+ rcmail.enable_command('plugin.sieverules.delete', false);
+ }
+ }, false);
+
+ if (rcmail.env.action == 'plugin.sieverules.advanced') {
+ rcmail.register_command('plugin.sieverules.save', function() {
+ rcmail.gui_objects.editform.submit();
+ }, true);
+ }
+
+ // enable commands
+ if (!rcmail.env.ruleset_active && rcmail.env.ruleset_total > 1)
+ rcmail.enable_command('plugin.sieverules.del_ruleset', true);
+
+ if (!rcmail.env.ruleset_active)
+ rcmail.enable_command('plugin.sieverules.activate_ruleset', true);
+ }
+ else if (rcmail.env.action == 'plugin.sieverules.setup') {
+ rcmail.register_command('plugin.sieverules.import', function(props) {
+ var add_url = '';
+
+ var target = window;
+ if (rcmail.env.framed)
+ target = window.parent;
+
+ target.location.href = './?_task=settings&_action=plugin.sieverules.import&' + props;
+ }, true);
+
+ rcmail.register_command('plugin.sieverules.ruleset_dialog_setup', function(props, obj) {
+ var target = window;
+ if (rcmail.env.framed)
+ target = window.parent;
+
+ target.rcube_find_object('sieverulesrsdialog_add').style.display = 'none';
+ target.rcube_find_object('sieverulesrsdialog_edit').style.display = 'none';
+ target.rcube_find_object('sieverulesrsdialog_input').style.display = 'none';
+ //target.rcube_find_object('sieverulesrsdialog_copyfrom').style.display = '';
+ boxtitle = rcube_find_object('sieverulesrsdialog_copyfrom').innerHTML;
+ target.rcube_find_object('sieverulesrsdialog_select').style.display = '';
+ target.rcube_find_object('sieverulesrsdialog_action').value = props;
+
+ target.$('#sieverulesrsdialog').dialog({ title: boxtitle, width: 512, resizable: false, modal: true });
+ }, true);
+ }
+
+ if (rcmail.env.action == 'plugin.sieverules.add' || rcmail.env.action == 'plugin.sieverules.edit') {
+ rcmail.register_command('plugin.sieverules.add_rule', function(props, obj) {
+ rcmail.enable_command('plugin.sieverules.del_rule', true);
+ var rulesTable = rcube_find_object('rules-table').tBodies[0];
+ var idx = obj.parentNode.parentNode.rowIndex + 3;
+ var newNode1 = rulesTable.rows[0].cloneNode(true);
+ var newNode2 = rulesTable.rows[1].cloneNode(true);
+ var newNode3 = rulesTable.rows[2].cloneNode(true);
+
+ if (idx < rulesTable.rows.length) {
+ rulesTable.insertBefore(newNode3, rulesTable.rows[idx]);
+ rulesTable.insertBefore(newNode2, rulesTable.rows[idx]);
+ rulesTable.insertBefore(newNode1, rulesTable.rows[idx]);
+ }
+ else {
+ rulesTable.appendChild(newNode1);
+ rulesTable.appendChild(newNode2);
+ rulesTable.appendChild(newNode3);
+ }
+
+ rcmail.env.sieverules_rules++;
+ var tmp = $(newNode2).html().replace(/rowid/g, rcmail.env.sieverules_rules);
+ $(newNode2).html(tmp);
+ var tmp = $(newNode3).html().replace(/rowid/g, rcmail.env.sieverules_rules);
+ $(newNode3).html(tmp);
+
+ newNode1.style.display = "";
+ newNode2.style.display = "none";
+ newNode3.style.display = "none";
+
+ return false;
+ }, true);
+
+ rcmail.register_command('plugin.sieverules.del_rule', function(props, obj) {
+ var rulesTable = rcube_find_object('rules-table').tBodies[0];
+
+ if (rulesTable.rows.length == 6)
+ return false;
+
+ if (confirm(rcmail.gettext('ruledeleteconfirm','sieverules'))) {
+ rulesTable.deleteRow(obj.parentNode.parentNode.rowIndex + 2);
+ rulesTable.deleteRow(obj.parentNode.parentNode.rowIndex + 1);
+ rulesTable.deleteRow(obj.parentNode.parentNode.rowIndex);
+ }
+
+ if (rcube_find_object('rules-table').tBodies[0].rows.length == 6)
+ rcmail.enable_command('plugin.sieverules.del_rule', false);
+
+ return false;
+ }, false);
+
+ rcmail.register_command('plugin.sieverules.copy_rule', function(props, obj) {
+ parent.rcmail.command('plugin.sieverules.ruleset_dialog', 'copyto_ruleset', obj);
+ }, true);
+
+ rcmail.register_command('plugin.sieverules.add_action', function(props, obj) {
+ rcmail.enable_command('plugin.sieverules.del_action', true);
+ var actsTable = rcube_find_object('actions-table').tBodies[0];
+ var idx = obj.parentNode.parentNode.rowIndex + 1;
+ var newNode = actsTable.rows[0].cloneNode(true);
+
+ if (idx < actsTable.rows.length)
+ actsTable.insertBefore(newNode, actsTable.rows[idx]);
+ else
+ actsTable.appendChild(newNode);
+
+ rcmail.env.sieverules_actions++;
+ var tmp = $(newNode).html().replace(/rowid/g, rcmail.env.sieverules_actions);
+ $(newNode).html(tmp);
+
+ newNode.style.display = "";
+
+ return false;
+ }, true);
+
+ rcmail.register_command('plugin.sieverules.del_action', function(props, obj) {
+ var actsTable = rcube_find_object('actions-table').tBodies[0];
+
+ if (actsTable.rows.length == 2)
+ return false;
+
+ if (confirm(rcmail.gettext('actiondeleteconfirm','sieverules')))
+ actsTable.deleteRow(obj.parentNode.parentNode.rowIndex);
+
+ if (rcube_find_object('actions-table').tBodies[0].rows.length == 2)
+ rcmail.enable_command('plugin.sieverules.del_action', false);
+
+ return false;
+ }, false);
+
+ rcmail.register_command('plugin.sieverules.save', function() {
+ var rows;
+
+ if (rcmail.env.framed)
+ rows = parent.rcmail.sieverules_list.rows;
+ else
+ rows = rcmail.sieverules_list.rows;
+
+ var input_name = rcube_find_object('_name');
+ var rule_join = document.getElementsByName('_join');
+ var headers = document.getElementsByName('_header[]');
+ var bodyparts = document.getElementsByName('_bodypart[]');
+ var contentparts = document.getElementsByName('_body_contentpart[]');
+ var dateparts = document.getElementsByName('_datepart[]');
+ var ops = document.getElementsByName('_operator[]');
+ var advops = document.getElementsByName('_advoperator[]');
+ var targets = document.getElementsByName('_target[]');
+ var advtargets = document.getElementsByName('_advtarget[]');
+ var acts = document.getElementsByName('_act[]');
+ var folders = document.getElementsByName('_folder[]');
+ var customfolders = document.getElementsByName('_customfolder[]');
+ var addrs = document.getElementsByName('_redirect[]');
+ var rejects = document.getElementsByName('_reject[]');
+ var senders = document.getElementsByName('_vacfrom[]');
+ var aliases = document.getElementsByName('_vacto[]');
+ var days = document.getElementsByName('_day[]');
+ var subjects = document.getElementsByName('_subject[]');
+ var msgs = document.getElementsByName('_msg[]');
+ var nmethods = document.getElementsByName('_nmethod[]');
+ var nmsgs = document.getElementsByName('_nmsg[]');
+ var eheadernames = document.getElementsByName('_eheadname[]');
+ var eheadervals = document.getElementsByName('_eheadval[]');
+ var size_test = new RegExp('^[0-9]+$');
+ var spamtest_test = new RegExp('^[0-9]+$');
+ var header_test = new RegExp('^[a-zA-Z0-9\-]+( ?, ?[a-zA-Z0-9\-]+)*$');
+ var date_test = new RegExp('^[0-9]{4}\-[0-9]{2}\-[0-9]{2}$');
+ var time_test = new RegExp('^[0-9]{2}:[0-9]{2}:[0-9]{2}$');
+
+ if (input_name && input_name.value == '') {
+ alert(rcmail.gettext('norulename','sieverules'));
+ input_name.focus();
+ return false;
+ }
+
+ for (var i = 0; i < rows.length; i++) {
+ if (input_name.value == rows[i].obj.cells[0].innerHTML && i != rcmail.env.iid) {
+ alert(rcmail.gettext('ruleexists','sieverules'));
+ input_name.focus();
+ return false;
+ }
+ }
+
+ for (var i = 1; i < headers.length && (rule_join[0].checked || rule_join[1].checked); i++) {
+ if (headers[i].value == '') {
+ alert(rcmail.gettext('noheader','sieverules'));
+ headers[i].focus();
+ return false;
+ }
+
+ if (!header_test.test(headers[i].value)) {
+ alert(rcmail.gettext('headerbadchars','sieverules'));
+ headers[i].focus();
+ return false;
+ }
+
+ if (bodyparts[i].value == 'content' && contentparts[i].value == '') {
+ alert(rcmail.gettext('nobodycontentpart','sieverules'));
+ contentparts[i].focus();
+ return false;
+ }
+
+ if (targets[i] && dateparts[i].value != 'weekday' && ops[i].value.indexOf("exists") == -1 && ops[i].value.indexOf("advoptions") == -1 && targets[i].value == '') {
+ alert(rcmail.gettext('noheadervalue','sieverules'));
+ targets[i].focus();
+ return false;
+ }
+
+ if (advtargets[i] && dateparts[i].value != 'weekday' && ops[i].value.indexOf("advoptions") != -1 && advtargets[i].value == '') {
+ alert(rcmail.gettext('noheadervalue','sieverules'));
+ advtargets[i].focus();
+ return false;
+ }
+
+ if (headers[i].value == 'size' && !size_test.test(targets[i].value)) {
+ alert(rcmail.gettext('sizewrongformat','sieverules'));
+ targets[i].focus();
+ return false;
+ }
+
+ if (headers[i].value == 'spamtest') {
+ targets[i].value = document.getElementsByName('_spam_probability[]')[i].value;
+ }
+
+ if (headers[i].value == 'virustest') {
+ targets[i].value = document.getElementsByName('_virus_probability[]')[i].value;
+ }
+
+ if (headers[i].value == 'body' && (advops[i].value.indexOf('user') > -1 || advops[i].value.indexOf('detail') > -1 || advops[i].value.indexOf('domain') > -1)) {
+ alert(rcmail.gettext('badoperator','sieverules'));
+ advops[i].focus();
+ return false;
+ }
+
+ if ((headers[i].value == 'date' || headers[i].value == 'currentdate')) {
+ if (dateparts[i].value == 'date' && !date_test.test(targets[i].value)) {
+ alert(rcmail.gettext('baddateformat','sieverules'));
+ targets[i].focus();
+ return false;
+ }
+ else if (dateparts[i].value == 'time' && !time_test.test(targets[i].value)) {
+ alert(rcmail.gettext('badtimeformat','sieverules'));
+ targets[i].focus();
+ return false;
+ }
+ }
+ }
+
+ for (var i = 1; i < acts.length; i++) {
+ var idx = acts[i].selectedIndex;
+
+ if (acts[i][idx].value == 'fileinto' || acts[i][idx].value == 'fileinto_copy') {
+ if (folders[i].value == '@@newfolder' && customfolders[i].value == '') {
+ alert(rcmail.gettext('missingfoldername','sieverules'));
+ customfolders[i].focus();
+ return false;
+ }
+ }
+ else if (acts[i][idx].value == 'redirect' || acts[i][idx].value == 'redirect_copy') {
+ if (addrs[i].value == '') {
+ alert(rcmail.gettext('noredirect','sieverules'));
+ addrs[i].focus();
+ return false;
+ }
+
+ if (!rcube_check_email(addrs[i].value.replace(/^\s+/, '').replace(/[\s,;]+$/, ''), true)) {
+ alert(rcmail.gettext('redirectaddresserror','sieverules'));
+ addrs[i].focus();
+ return false;
+ }
+ }
+ else if (acts[i][idx].value == 'reject' || acts[i][idx].value == 'ereject') {
+ if (rejects[i].value == '') {
+ alert(rcmail.gettext('noreject','sieverules'));
+ rejects[i].focus();
+ return false;
+ }
+ }
+ else if (acts[i][idx].value == 'vacation') {
+ if (senders[i].value != '' && senders[i].value != 'auto' && !rcube_check_email(senders[i].value.replace(/^\s+/, '').replace(/[\s,;]+$/, ''), true) && !$.isNumeric(senders[i].value)) {
+ alert(rcmail.gettext('redirectaddresserror','sieverules'));
+ senders[i].focus();
+ return false;
+ }
+
+ if (aliases[i].value.indexOf(' ') > -1 || aliases[i].value.indexOf(';') > -1) {
+ alert(rcmail.gettext('vactoexp_err','sieverules'));
+ aliases[i].focus();
+ return false;
+ }
+
+ //if (days[i].value == '') {
+ // alert(rcmail.gettext('vacnodays','sieverules'));
+ // days[i].focus();
+ // return false;
+ //}
+
+ if (days[i].value != '' && (!size_test.test(days[i].value) || days[i].value < 1)) {
+ alert(rcmail.gettext('vacdayswrongformat','sieverules'));
+ days[i].focus();
+ return false;
+ }
+
+ //if (subjects[i].value == '') {
+ // alert(rcmail.gettext('vacnosubject','sieverules'));
+ // subjects[i].focus();
+ // return false;
+ //}
+
+ var editor = tinyMCE.get("rcmfd_sievevacmag_" + (i - 1));
+ if ((editor && editor.getContent() == '') || (!editor && msgs[i].value == '')) {
+ alert(rcmail.gettext('vacnomsg','sieverules'));
+ msgs[i].focus();
+ return false;
+ }
+ }
+ else if (acts[i][idx].value == 'notify' || acts[i][idx].value == 'enotify') {
+ if (nmethods[i].value == '') {
+ alert(rcmail.gettext('notifynomethod','sieverules'));
+ nmethods[i].focus();
+ return false;
+ }
+
+ if (acts[i][idx].value == 'enotify' && nmethods[i].value.indexOf(':') == -1) {
+ alert(rcmail.gettext('notifyinvalidmethod','sieverules'));
+ nmethods[i].focus();
+ return false;
+ }
+
+ if (nmsgs[i].value == '') {
+ alert(rcmail.gettext('notifynomsg','sieverules'));
+ nmsgs[i].focus();
+ return false;
+ }
+ }
+ else if (acts[i][idx].value == 'editheaderadd' || acts[i][idx].value == 'editheaderrem') {
+ if (eheadernames[i].value == '') {
+ alert(rcmail.gettext('eheadernoname','sieverules'));
+ eheadernames[i].focus();
+ return false;
+ }
+
+ if (acts[i][idx].value == 'editheaderadd') {
+ if (eheadervals[i].value == '') {
+ alert(rcmail.gettext('eheadernoval','sieverules'));
+ eheadervals[i].focus();
+ return false;
+ }
+ }
+ }
+ }
+
+ // enable the comparators field
+ for (var i = 0; i < document.getElementsByName('_comparator[]').length; i++)
+ document.getElementsByName('_comparator[]')[i].disabled = false;
+
+ rcmail.gui_objects.editform.submit();
+ }, true);
+
+ rcmail.register_command('plugin.sieverules.vacation_sig', function(id) {
+ var obj = document.getElementById("rcmfd_sievevacfrom_" + id);
+ var is_html = ($("#rcmfd_sievevachtmlcb_" + id).is(':checked'));
+
+ if (!obj || !obj.options)
+ return false;
+
+ var sig, id;
+ var sig_separator = '-- ';
+
+ if (obj.options[0].value == 'auto' || obj.options[0].value == '')
+ id = obj.selectedIndex;
+ else
+ id = obj.selectedIndex + 1;
+
+ if (is_html) {
+ var editor = tinyMCE.get("rcmfd_sievevacmag_" + id),
+ sigElem = editor.dom.get('_rc_sig');
+
+ // Append the signature as a div within the body
+ if (!sigElem) {
+ var body = editor.getBody(),
+ doc = editor.getDoc();
+
+ sigElem = doc.createElement('div');
+ sigElem.setAttribute('id', '_rc_sig');
+
+ if (bw.ie) // add empty line before signature on IE
+ body.appendChild(doc.createElement('br'));
+
+ body.appendChild(sigElem);
+ }
+
+ if (rcmail.env.signatures[id]) {
+ if (rcmail.env.signatures[id].is_html) {
+ sig = rcmail.env.signatures[id].text;
+ if (!rcmail.env.signatures[id].plain_text.match(/^--[ -]\r?\n/m))
+ sig = sig_separator + '<br />' + sig;
+ }
+ else {
+ sig = rcmail.env.signatures[id].text;
+ if (!sig.match(/^--[ -]\r?\n/m))
+ sig = sig_separator + '\n' + sig;
+
+ sig = '<pre>' + sig + '</pre>';
+ }
+
+ sigElem.innerHTML = sig;
+ }
+ }
+ else {
+ var input_message = $("#rcmfd_sievevacmag_" + id);
+ var message = input_message.val();
+
+ if (rcmail.env.signatures && rcmail.env.signatures[id]) {
+ sig = rcmail.env.signatures[id]['text'];
+ sig = sig.replace(/\r\n/g, '\n');
+
+ if (!sig.match(/^--[ -]\n/))
+ sig = sig_separator + '\n' + sig;
+
+ message = message.replace(/[\r\n]+$/, '');
+ message += '\n\n' + sig;
+ }
+
+ input_message.val(message);
+ }
+
+ return false;
+ }, false);
+
+ // enable commands
+ if (rcube_find_object('rules-table').tBodies[0].rows.length > 6)
+ rcmail.enable_command('plugin.sieverules.del_rule', true);
+
+ if (rcube_find_object('actions-table').tBodies[0].rows.length > 2)
+ rcmail.enable_command('plugin.sieverules.del_action', true);
+
+ rcmail.enable_command('toggle-editor', true);
+
+ // enable sig button
+ var acts = document.getElementsByName('_act[]');
+ for (var i = 1; i < acts.length; i++) {
+ var idx = acts[i].selectedIndex;
+
+ if (acts[i][idx].value == 'vacation')
+ rcmail.enable_sig(document.getElementsByName('_vacfrom[]')[i]);
+ }
+
+ // add input masks
+ rcmail.add_onload(function setup_inputmasks() {
+ // date/time inputs
+ headers = document.getElementsByName('_selheader[]');
+ for (var i = 0; i < headers.length; i++) {
+ if (headers[i].value.indexOf('date::') == 0) {
+ var obj = document.getElementsByName('_datepart[]')[i];
+ var target_obj = $("input[name='_target[]']")[i];
+
+ $(target_obj).datepicker("destroy");
+ $(target_obj).unmask();
+
+ if (obj.value == 'date')
+ $(target_obj).datepicker({ dateFormat: 'yy-mm-dd' });
+ else if (obj.value == 'time')
+ $(target_obj).mask('99:99:99', {example: 'HH:MM:SS', placeholder: '0'});
+ }
+
+ }
+ });
+ }
+ });
+ }
+}); \ No newline at end of file
diff --git a/plugins/sieverules/sieverules.php b/plugins/sieverules/sieverules.php
new file mode 100644
index 000000000..adb2bc16b
--- /dev/null
+++ b/plugins/sieverules/sieverules.php
@@ -0,0 +1,2331 @@
+<?php
+
+/**
+ * SieveRules
+ *
+ * Plugin to allow the user to manage their Sieve filters using the managesieve protocol
+ *
+ * @version @package_version@
+ * @requires jQueryUI plugin
+ * @author Philip Weir
+ * Based on the Managesieve plugin by Aleksander Machniak
+ */
+class sieverules extends rcube_plugin
+{
+ public $task = 'settings';
+ private $sieve;
+ private $sieve_error;
+ private $script;
+ private $action;
+ private $examples = array();
+ private $force_vacto = false;
+ private $show_vacfrom = false;
+ private $show_vachandle = false;
+ private $current_ruleset;
+
+ // default values: label => value
+ private $headers = array('subject' => 'header::Subject',
+ 'from' => 'address::From',
+ 'to' => 'address::To',
+ 'cc' => 'address::Cc',
+ 'bcc' => 'address::Bcc',
+ 'envelopeto' => 'envelope::To',
+ 'envelopefrom' => 'envelope::From'
+ );
+
+ private $operators = array('filtercontains' => 'contains',
+ 'filternotcontains' => 'notcontains',
+ 'filteris' => 'is',
+ 'filterisnot' => 'notis',
+ 'filterexists' => 'exists',
+ 'filternotexists' => 'notexists'
+ );
+
+ private $flags = array('flagread' => '\\\\Seen',
+ 'flagdeleted' => '\\\\Deleted',
+ 'flaganswered' => '\\\\Answered',
+ 'flagdraft' => '\\\\Draft',
+ 'flagflagged' => '\\\\Flagged'
+ );
+
+ function init()
+ {
+ $rcmail = rcube::get_instance();
+ $this->load_config();
+
+ // load required plugin
+ $this->require_plugin('jqueryui');
+
+ if ($rcmail->config->get('sieverules_multiplerules') && rcube_utils::get_input_value('_ruleset', rcube_utils::INPUT_GET, true))
+ $this->current_ruleset = rcube_utils::get_input_value('_ruleset', rcube_utils::INPUT_GET, true);
+ elseif ($rcmail->config->get('sieverules_multiplerules') && $_SESSION['sieverules_current_ruleset'])
+ $this->current_ruleset = $_SESSION['sieverules_current_ruleset'];
+ elseif ($rcmail->config->get('sieverules_multiplerules'))
+ $this->current_ruleset = false;
+ else
+ $this->current_ruleset = $rcmail->config->get('sieverules_ruleset_name');
+
+ // override default values
+ if ($rcmail->config->get('sieverules_default_headers'))
+ $this->headers = $rcmail->config->get('sieverules_default_headers');
+
+ if ($rcmail->config->get('sieverules_default_operators'))
+ $this->operators = $rcmail->config->get('sieverules_default_operators');
+
+ if ($rcmail->config->get('sieverules_default_flags'))
+ $this->flags = $rcmail->config->get('sieverules_default_flags');
+
+ $this->action = $rcmail->action;
+
+ $this->add_texts('localization/', array('filters', 'managefilters'));
+ $this->include_stylesheet($this->local_skin_path() . '/tabstyles.css');
+ $this->include_script('sieverules.js');
+
+ $this->register_action('plugin.sieverules', array($this, 'init_html'));
+ $this->register_action('plugin.sieverules.add', array($this, 'init_html'));
+ $this->register_action('plugin.sieverules.edit', array($this, 'init_html'));
+ $this->register_action('plugin.sieverules.setup', array($this, 'init_setup'));
+ $this->register_action('plugin.sieverules.advanced', array($this, 'init_html'));
+ $this->register_action('plugin.sieverules.move', array($this, 'move'));
+ $this->register_action('plugin.sieverules.save', array($this, 'save'));
+ $this->register_action('plugin.sieverules.delete', array($this, 'delete'));
+ $this->register_action('plugin.sieverules.import', array($this, 'import'));
+ $this->register_action('plugin.sieverules.update_list', array($this, 'gen_js_list'));
+ $this->register_action('plugin.sieverules.del_ruleset', array($this, 'delete_ruleset'));
+ $this->register_action('plugin.sieverules.rename_ruleset', array($this, 'rename_ruleset'));
+ $this->register_action('plugin.sieverules.enable_ruleset', array($this, 'enable_ruleset'));
+ $this->register_action('plugin.sieverules.copy_filter', array($this, 'copy_filter'));
+ }
+
+ function init_html()
+ {
+ $rcmail = rcube::get_instance();
+
+ // always include all identities when creating vacation messages
+ if ($rcmail->config->get('sieverules_force_vacto'))
+ $this->force_vacto = $rcmail->config->get('sieverules_force_vacto');
+
+ // include the 'from' option when creating vacation messages
+ if ($rcmail->config->get('sieverules_show_vacfrom'))
+ $this->show_vacfrom = $rcmail->config->get('sieverules_show_vacfrom');
+
+ // include the 'handle' option when creating vacation messages
+ if ($rcmail->config->get('sieverules_show_vachandle'))
+ $this->show_vachandle = $rcmail->config->get('sieverules_show_vachandle');
+
+ $this->_startup();
+
+ if ($rcmail->config->get('sieverules_multiplerules') && $this->current_ruleset === false) {
+ if ($ruleset = $this->sieve->get_active()) {
+ $this->current_ruleset = $this->sieve->get_active();
+ }
+ else {
+ $this->current_ruleset = $rcmail->config->get('sieverules_ruleset_name');
+ $this->_startup();
+ $rcmail->overwrite_action('plugin.sieverules.setup');
+ $this->action = 'plugin.sieverules.setup';
+ }
+ }
+
+ if ($rcmail->config->get('sieverules_multiplerules'))
+ $_SESSION['sieverules_current_ruleset'] = $this->current_ruleset;
+
+ $this->api->output->set_env('ruleset', $this->current_ruleset);
+ if ($rcmail->config->get('sieverules_adveditor') == 2 && rcube_utils::get_input_value('_override', rcube_utils::INPUT_GET) != '1' && $this->action == 'plugin.sieverules') {
+ $rcmail->overwrite_action('plugin.sieverules.advanced');
+ $this->action = 'plugin.sieverules.advanced';
+ }
+
+ $this->api->output->add_handlers(array(
+ 'sieveruleslist' => array($this, 'gen_list'),
+ 'sieverulesexamplelist' => array($this, 'gen_examples'),
+ 'sieverulessetup' => array($this, 'gen_setup'),
+ 'sieveruleform' => array($this, 'gen_form'),
+ 'advancededitor' => array($this, 'gen_advanced'),
+ 'advswitch' => array($this, 'gen_advswitch'),
+ 'rulelist' => array($this, 'gen_rulelist'),
+ 'sieverulesframe' => array($this, 'sieverules_frame'),
+ ));
+
+ if ($this->action != 'plugin.sieverules.advanced')
+ $this->api->output->include_script('list.js');
+
+ if (sizeof($this->examples) > 0)
+ $this->api->output->set_env('examples', 'true');
+
+ if ($this->action == 'plugin.sieverules.add' || $this->action == 'plugin.sieverules.edit') {
+ $rcmail->html_editor('sieverules');
+ $this->api->output->add_script(sprintf("window.rcmail_editor_settings = %s",
+ json_encode(array(
+ 'plugins' => 'paste,tabfocus',
+ 'theme_advanced_buttons1' => 'bold,italic,underline,strikethrough,justifyleft,justifycenter,justifyright,justifyfull,separator,outdent,indent,charmap,hr',
+ 'theme_advanced_buttons2' => 'link,unlink,code,forecolor,fontselect,fontsizeselect',
+ ))), 'head');
+
+ $this->api->output->set_pagetitle($this->action == 'plugin.sieverules.add' ? $this->gettext('newfilter') : $this->gettext('edititem'));
+ $this->api->output->send('sieverules.editsieverule');
+ }
+ elseif ($this->action == 'plugin.sieverules.setup') {
+ $this->api->output->set_pagetitle($this->gettext('filters'));
+ $this->api->output->add_script(rcmail_output::JS_OBJECT_NAME .".add_onload('". rcmail_output::JS_OBJECT_NAME .".sieverules_load_setup()');");
+ $this->api->output->send('sieverules.sieverules');
+ }
+ elseif ($this->action == 'plugin.sieverules.advanced') {
+ $this->api->output->set_pagetitle($this->gettext('filters'));
+ $this->api->output->send('sieverules.advancededitor');
+ }
+ else {
+ $this->api->output->set_pagetitle($this->gettext('filters'));
+ $this->api->output->send('sieverules.sieverules');
+ }
+ }
+
+ function init_setup()
+ {
+ $this->_startup();
+
+ $this->api->output->add_handlers(array(
+ 'sieverulessetup' => array($this, 'gen_setup'),
+ ));
+
+ $this->api->output->set_pagetitle($this->gettext('filters'));
+ $this->api->output->send('sieverules.setupsieverules');
+ }
+
+ function sieverules_frame($attrib)
+ {
+ if (!$attrib['id'])
+ $attrib['id'] = 'rcmprefsframe';
+
+ return $this->api->output->frame($attrib, true);
+ }
+
+ function gen_advanced($attrib)
+ {
+ list($form_start, $form_end) = get_form_tags($attrib, 'plugin.sieverules.save');
+ $out = $form_start;
+
+ $input_script = new html_textarea(array('id' => 'sieverules_adv', 'name' => '_script'));
+ $out .= $input_script->show($this->sieve->script->raw);
+
+ $out .= $form_end;
+
+ return $out;
+ }
+
+ function gen_list($attrib)
+ {
+ $this->api->output->add_label('sieverules.movingfilter', 'loading', 'sieverules.switchtoadveditor', 'sieverules.filterdeleteconfirm');
+ $this->api->output->add_gui_object('sieverules_list', 'sieverules-table');
+
+ $table = new html_table(array('id' => 'sieverules-table', 'class' => 'records-table', 'cellspacing' => '0', 'cols' => 2));
+
+ if (rcube::get_instance()->config->get('sieverules_multiplerules', false)) {
+ if ($this->current_ruleset == $this->sieve->get_active())
+ $status = html::img(array('id' => 'rulesetstatus', 'src' => $attrib['activeicon'], 'alt' => $this->gettext('isactive'), 'title' => $this->gettext('isactive')));
+ else
+ $status = html::img(array('id' => 'rulesetstatus', 'src' => $attrib['inactiveicon'], 'alt' => $this->gettext('isinactive'), 'title' => $this->gettext('isinactive')));
+
+ $table->add_header(array('colspan' => '2'), html::span(array('title' => $this->current_ruleset), $this->gettext(array('name' => 'filtersname', 'vars' => array('name' => $this->current_ruleset)))) . $status);
+ }
+ else {
+ $table->add_header(array('colspan' => 2), $this->gettext('filters'));
+ }
+
+ if (sizeof($this->script) == 0) {
+ $table->add(array('colspan' => '2'), rcube_utils::rep_specialchars_output($this->gettext('nosieverules')));
+ }
+ else foreach($this->script as $idx => $filter) {
+ $table->set_row_attribs(array('id' => 'rcmrow' . $idx));
+
+ if ($filter['disabled'] == 1)
+ $table->add(null, rcmail::Q($filter['name']) . ' (' . $this->gettext('disabled') . ')');
+ else
+ $table->add(null, rcmail::Q($filter['name']));
+
+ $dst = $idx - 1;
+ $up_link = $this->api->output->button(array('command' => 'plugin.sieverules.move', 'prop' => $dst, 'type' => 'link', 'class' => 'up_arrow', 'title' => 'sieverules.moveup', 'content' => ' '));
+ $dst = $idx + 2;
+ $down_link = $this->api->output->button(array('command' => 'plugin.sieverules.move', 'prop' => $dst, 'type' => 'link', 'class' => 'down_arrow', 'title' => 'sieverules.movedown', 'content' => ' '));
+
+ $table->add('control', $down_link . $up_link);
+ }
+
+ return html::tag('div', array('id' => 'sieverules-list-filters'), $table->show($attrib));
+ }
+
+ function gen_js_list()
+ {
+ $this->_startup();
+
+ if (sizeof($this->script) == 0) {
+ $this->api->output->command('sieverules_update_list', 'add-first', -1, rcube_utils::rep_specialchars_output($this->gettext('nosieverules')));
+ }
+ else foreach($this->script as $idx => $filter) {
+ if ($filter['disabled'] == 1)
+ $filter_name = $filter['name'] . ' (' . $this->gettext('disabled') . ')';
+ else
+ $filter_name = $filter['name'];
+
+ $tmp_output = new rcmail_output_html('settings');
+ $dst = $idx - 1;
+ $up_link = $tmp_output->button(array('command' => 'plugin.sieverules.move', 'prop' => $dst, 'type' => 'link', 'class' => 'up_arrow', 'title' => 'sieverules.moveup', 'content' => ' '));
+ $up_link = str_replace("'", "\'", $up_link);
+ $dst = $idx + 2;
+ $down_link = $tmp_output->button(array('command' => 'plugin.sieverules.move', 'prop' => $dst, 'type' => 'link', 'class' => 'down_arrow', 'title' => 'sieverules.movedown', 'content' => ' '));
+ $down_link = str_replace("'", "\'", $down_link);
+
+ $this->api->output->command('sieverules_update_list', $idx == 0 ? 'add-first' : 'add', 'rcmrow' . $idx, rcmail::JQ($filter_name), $down_link, $up_link);
+ }
+
+ $this->api->output->send();
+ }
+
+ function gen_examples($attrib)
+ {
+ if (sizeof($this->examples) > 0) {
+ $this->api->output->add_gui_object('sieverules_examples', 'sieverules-examples');
+
+ $examples = new html_table(array('id' => 'sieverules-examples', 'class' => 'records-table', 'cellspacing' => '0', 'cols' => 1));
+ $examples->add_header(null, $this->gettext('examplefilters'));
+
+ foreach($this->examples as $idx => $filter) {
+ $examples->set_row_attribs(array('id' => 'rcmrowex' . $idx));
+ $examples->add(null, rcmail::Q($filter['name']));
+ }
+
+ return html::tag('div', array('id' => 'sieverules-list-examples'), $examples->show($attrib));
+ }
+ else {
+ return '';
+ }
+
+ }
+
+ function gen_advswitch($attrib)
+ {
+ $input_adv = new html_checkbox(array('id' => 'adveditor', 'onclick' => rcmail_output::JS_OBJECT_NAME . '.sieverules_adveditor(this);', 'value' => '1'));
+ $out = html::label('adveditor', rcmail::Q($this->gettext('adveditor'))) . $input_adv->show($this->action == 'plugin.sieverules.advanced' ? '1' : '');
+ return html::tag('div', array('id' => 'advancedmode'), $out);
+ }
+
+ function gen_rulelist($attrib)
+ {
+ $this->api->output->add_label('sieverules.delrulesetconf', 'sieverules.rulesetexists');
+
+ $rulesets = array();
+ foreach ($this->sieve->list as $ruleset) {
+ array_push($rulesets, $ruleset);
+ }
+ sort($rulesets);
+ $activeruleset = $this->sieve->get_active();
+
+ $next_ruleset = '';
+ for ($i = 0; $i < sizeof($rulesets); $i++) {
+ if ($rulesets[$i] == $this->current_ruleset) {
+ $i++;
+
+ if ($i == sizeof($rulesets))
+ $i = sizeof($rulesets) - 2;
+
+ $next_ruleset = $rulesets[$i];
+ break;
+ }
+ }
+
+ $this->api->output->set_env('ruleset_total', sizeof($rulesets));
+ $this->api->output->set_env('ruleset_active', $this->current_ruleset == $activeruleset ? True : False);
+ $this->api->output->set_env('ruleset_next', $next_ruleset);
+
+ // new/rename ruleset dialog
+ $out = '';
+ $table = new html_table(array('cols' => 2, 'class' => 'propform'));
+ $table->set_row_attribs(array('id' => 'sieverulesrsdialog_input'));
+ $table->add('title', html::label('sieverulesrsdialog_name', rcmail::Q($this->gettext('name'))));
+ $table->add(null, html::tag('input', array('type' => 'text', 'id' => 'sieverulesrsdialog_name', 'name' => '_name', 'value' => '')));
+
+ $select_ruleset = new html_select(array('id' => 'sieverulesrsdialog_ruleset'));
+ if (sizeof($this->sieve->list) == 1) {
+ $select_ruleset->add(rcmail::Q($this->gettext('nosieverulesets')), '');
+ }
+ else foreach ($rulesets as $ruleset) {
+ if ($ruleset !== $this->current_ruleset)
+ $select_ruleset->add(rcmail::Q($ruleset), rcmail::Q($ruleset));
+ }
+
+ $table->set_row_attribs(array('id' => 'sieverulesrsdialog_select'));
+ $table->add('title', html::label('sieverulesrsdialog_ruleset', rcmail::Q($this->gettext('selectruleset'))));
+ $table->add(null, $select_ruleset->show());
+
+ $buttons = html::tag('input', array('type' => 'hidden', 'id' => 'sieverulesrsdialog_action', 'value' => ''));
+ $buttons .= html::tag('input', array('type' => 'button', 'class' => 'button mainaction', 'value' => $this->gettext('save'), 'onclick' => rcmail_output::JS_OBJECT_NAME . '.sieverulesdialog_submit();')) . '&nbsp;';
+
+ $out .= html::tag('h3', array('id' => 'sieverulesrsdialog_add'), rcmail::Q($this->gettext('newruleset')));
+ $out .= html::tag('h3', array('id' => 'sieverulesrsdialog_edit', 'style' => 'display: none;'), rcmail::Q($this->gettext('renameruleset')));
+ $out .= html::tag('h3', array('id' => 'sieverulesrsdialog_copyto', 'style' => 'display: none;'), rcmail::Q($this->gettext('copytoruleset')));
+ $out .= html::tag('h3', array('id' => 'sieverulesrsdialog_copyfrom', 'style' => 'display: none;'), rcmail::Q($this->gettext('copyfromruleset')));
+ $out .= $table->show();
+ $out .= html::p(array('class' => 'formbuttons'), $buttons);
+ $out = html::tag('form', array(), $out);
+ $out = html::div(array('id' => 'sieverulesrsdialog', 'style' => 'display: none;'), $out);
+
+ // add overlay input box to html page
+ $this->api->output->add_footer($out);
+
+ $action = ($this->action == 'plugin.sieverules.advanced') ? 'plugin.sieverules.advanced' : 'plugin.sieverules';
+ if ($attrib['type'] == 'link') {
+ $lis = '';
+
+ if (sizeof($this->sieve->list) == 0) {
+ $href = html::a(array('href' => "#", 'class' => 'active', 'onclick' => 'return false;'), rcmail::Q($this->gettext('nosieverulesets')));
+ $lis .= html::tag('li', $href);
+ }
+ else foreach ($rulesets as $ruleset) {
+ $class = 'active';
+ if ($ruleset === $this->current_ruleset)
+ $class .= ' selected';
+
+ $ruleset_text = $ruleset;
+ if ($ruleset === $activeruleset)
+ $ruleset_text = str_replace('%s', $ruleset, $this->gettext('activeruleset'));
+
+ $href = html::a(array('href' => "#", 'class' => $class, 'onclick' => rcmail_output::JS_OBJECT_NAME . '.sieverules_select_ruleset(\''. $ruleset .'\', \''. $action .'\');'), rcmail::Q($ruleset_text));
+ $lis .= html::tag('li', null, $href);
+ }
+
+ return $lis;
+ }
+ elseif ($attrib['type'] == 'select') {
+ $select_ruleset = new html_select(array('id' => 'rulelist', 'onchange' => rcmail_output::JS_OBJECT_NAME . '.sieverules_select_ruleset(this, \''. $action .'\');'));
+
+ if (sizeof($this->sieve->list) == 0) {
+ $select_ruleset->add(rcmail::Q($this->gettext('nosieverulesets')), '');
+ }
+ else foreach ($rulesets as $ruleset) {
+ if ($ruleset === $activeruleset)
+ $ruleset = str_replace('%s', $ruleset, $this->gettext('activeruleset'));
+
+ $select_ruleset->add(rcmail::Q($ruleset), rcmail::Q($ruleset));
+ }
+
+ return html::label('rulelist', rcmail::Q($this->gettext('selectruleset'))) . $select_ruleset->show(rcmail::Q($this->current_ruleset));
+ }
+ }
+
+ function gen_setup()
+ {
+ $rcmail = rcube::get_instance();
+ $text = '';
+ $buttons = '';
+
+ if ($rcmail->config->get('sieverules_default_file', false) && is_readable($rcmail->config->get('sieverules_default_file'))) {
+ $text .= "<br /><br />" . $this->gettext('importdefault');
+ $buttons .= $this->api->output->button(array('command' => 'plugin.sieverules.import', 'prop' => '_import=_default_', 'type' => 'input', 'class' => 'button', 'label' => 'sieverules.usedefaultfilter'));
+ }
+ elseif ($rcmail->config->get('sieverules_default_file', false) && !is_readable($rcmail->config->get('sieverules_default_file'))) {
+ rcube::raise_error(array(
+ 'code' => 600,
+ 'type' => 'php',
+ 'file' => __FILE__,
+ 'line' => __LINE__,
+ 'message' => "SieveRules plugin: Unable to open default rule file"
+ ), true, false);
+ }
+
+ $type = '';
+ $ruleset = '';
+ if (sizeof($this->sieve->list) > 0) {
+ if ($result = $this->sieve->check_import()) {
+ list($type, $name, $ruleset) = $result;
+ $text .= "<br /><br />" . str_replace('%s', $name, $this->gettext('importother'));
+ $buttons .= (strlen($buttons) > 0) ? '&nbsp;&nbsp;' : '';
+ $buttons .= $this->api->output->button(array('command' => 'plugin.sieverules.import', 'prop' => '_type=' . $type . '&_import=' . $ruleset, 'type' => 'input', 'class' => 'button', 'label' => 'sieverules.importfilter'));
+ }
+
+ if ($rcmail->config->get('sieverules_multiplerules', false)) {
+ $text .= "<br /><br />" . $this->gettext('copyexisting');
+ $buttons .= (strlen($buttons) > 0) ? '&nbsp;&nbsp;' : '';
+ $buttons .= $this->api->output->button(array('command' => 'plugin.sieverules.ruleset_dialog_setup', 'prop' => 'copyfrom_ruleset', 'type' => 'input', 'class' => 'button', 'label' => 'sieverules.copyexistingfilter'));
+ }
+ }
+
+ if ($rcmail->config->get('sieverules_auto_load_default') && !$rcmail->config->get('sieverules_multiplerules', false) && $type != '' && $ruleset != '' && $ruleset == $this->sieve->get_active()) {
+ $this->import($type, $ruleset, false);
+
+ if (isset($_GET['_framed']) || isset($_POST['_framed'])) {
+ $this->api->output->add_script("parent.". rcmail_output::JS_OBJECT_NAME .".goto_url('plugin.sieverules');");
+ }
+ else {
+ // go to sieverules page
+ $rcmail->overwrite_action('plugin.sieverules');
+ $this->api->output->send('sieverules.sieverules');
+ }
+ }
+ else if ($rcmail->config->get('sieverules_auto_load_default') && is_readable($rcmail->config->get('sieverules_default_file')) && strlen($text) > 0 && strlen($buttons) > 0 && $type == '' && $ruleset == '') {
+ $this->import($type, '_default_', false);
+
+ if (isset($_GET['_framed']) || isset($_POST['_framed'])) {
+ $this->api->output->add_script("parent.". rcmail_output::JS_OBJECT_NAME .".goto_url('plugin.sieverules');");
+ }
+ else {
+ // go to sieverules page
+ $rcmail->overwrite_action('plugin.sieverules');
+ $this->api->output->send('sieverules.sieverules');
+ }
+ }
+ else if (strlen($text) > 0 && strlen($buttons) > 0) {
+ $out = "<br />". $this->gettext('noexistingfilters') . $text . "<br /><br /><br />\n";
+ $out .= $buttons;
+ $out .= "&nbsp;&nbsp;" . $this->api->output->button(array('command' => 'plugin.sieverules.import', 'prop' => '_import=_none_', 'type' => 'input', 'class' => 'button', 'label' => 'cancel'));
+
+ $out = html::tag('p', array('style' => 'text-align: center; padding: 10px;'), "\n" . $out);
+ $out = html::tag('div', array('id' => 'prefs-title', 'class' => 'boxtitle'), rcmail::Q($this->gettext('importfilters'))) . $out;
+
+ return $out;
+ }
+ else {
+ if ($rcmail->config->get('sieverules_auto_load_default') && !is_readable($rcmail->config->get('sieverules_default_file')))
+ rcube::raise_error(array(
+ 'code' => 600,
+ 'type' => 'php',
+ 'file' => __FILE__,
+ 'line' => __LINE__,
+ 'message' => "SieveRules plugin: Unable to open default rule file"
+ ), true, false);
+
+ $this->sieve->save();
+ if (!($rcmail->config->get('sieverules_multiplerules', false) && sizeof($this->sieve->list) > 1))
+ $this->sieve->set_active($this->current_ruleset);
+
+ if (isset($_GET['_framed']) || isset($_POST['_framed'])) {
+ $this->api->output->add_script("parent.". rcmail_output::JS_OBJECT_NAME .".goto_url('plugin.sieverules');");
+ }
+ else {
+ // go to sieverules page
+ $rcmail->overwrite_action('plugin.sieverules');
+ $this->api->output->send('sieverules.sieverules');
+ }
+ }
+ }
+
+ function gen_form($attrib)
+ {
+ $rcmail = rcube::get_instance();
+ $this->include_script('jquery.maskedinput.js');
+ $this->api->output->add_label(
+ 'sieverules.norulename', 'sieverules.ruleexists', 'sieverules.noheader',
+ 'sieverules.headerbadchars', 'sieverules.noheadervalue', 'sieverules.sizewrongformat',
+ 'sieverules.noredirect', 'sieverules.redirectaddresserror', 'sieverules.noreject', 'sieverules.vacnodays',
+ 'sieverules.vacdayswrongformat', 'sieverules.vacnomsg', 'sieverules.notifynomethod', 'sieverules.missingfoldername',
+ 'sieverules.notifynomsg', 'sieverules.ruledeleteconfirm',
+ 'sieverules.actiondeleteconfirm', 'sieverules.notifyinvalidmethod', 'sieverules.nobodycontentpart',
+ 'sieverules.badoperator','sieverules.baddateformat','sieverules.badtimeformat','sieverules.vactoexp_err','editorwarning',
+ 'sieverules.eheadernoname','sieverules.eheadernoval');
+
+ $ext = $this->sieve->get_extensions();
+ $iid = rcube_utils::get_input_value('_iid', rcube_utils::INPUT_GPC);
+ if ($iid == '')
+ $iid = sizeof($this->script);
+
+ if (substr($iid, 0, 2) == 'ex') {
+ $cur_script = $this->examples[substr($iid, 2)];
+ $this->api->output->set_env('eid', $iid);
+ $iid = sizeof($this->script);
+ $this->api->output->set_env('iid', $iid);
+ $example = true;
+ }
+ else {
+ $cur_script = $this->script[$iid];
+ $this->api->output->set_env('iid', $iid);
+ $example = false;
+
+ if (isset($this->script[$iid]))
+ $this->api->output->add_script("parent.". rcmail_output::JS_OBJECT_NAME .".sieverules_ready('".$iid."');");
+ }
+
+ if (sizeof($rcmail->config->get('sieverules_predefined_rules')) > 0) {
+ $predefined = array();
+ foreach($rcmail->config->get('sieverules_predefined_rules') as $idx => $data)
+ array_push($predefined, array($data['type'], $data['header'], $data['operator'], $data['extra'], $data['target']));
+
+ $this->api->output->set_env('predefined_rules', $predefined);
+ }
+
+ list($form_start, $form_end) = get_form_tags($attrib, 'plugin.sieverules.save');
+
+ $out = $form_start;
+
+ $hidden_iid = new html_hiddenfield(array('name' => '_iid', 'value' => $iid));
+ $out .= $hidden_iid->show();
+
+ // 'any' flag
+ if (sizeof($cur_script['tests']) == 1 && $cur_script['tests'][0]['type'] == 'true' && !$cur_script['tests'][0]['not'])
+ $any = true;
+
+ // filter disable
+ $field_id = 'rcmfd_disable';
+ $input_disable = new html_checkbox(array('name' => '_disable', 'id' => $field_id, 'value' => 1));
+
+ $out .= html::span('disableLink', html::label($field_id, rcmail::Q($this->gettext('disablerule')))
+ . "&nbsp;" . $input_disable->show($cur_script['disabled']));
+
+ // filter name input
+ $field_id = 'rcmfd_name';
+ $input_name = new html_inputfield(array('name' => '_name', 'id' => $field_id));
+
+ $out .= html::label($field_id, rcmail::Q($this->gettext('filtername')));
+ $out .= "&nbsp;" . $input_name->show($cur_script['name']);
+
+ $out .= "<br /><br />";
+
+ if (sizeof($cur_script['tests']) == 1 && $cur_script['tests'][0]['type'] == 'true' && !$cur_script['tests'][0]['not'])
+ $join_any = true;
+
+ $field_id = 'rcmfd_join_all';
+ $input_join = new html_radiobutton(array('name' => '_join', 'id' => $field_id, 'value' => 'allof', 'onclick' => rcmail_output::JS_OBJECT_NAME . '.sieverules_rule_join_radio(\'allof\')'));
+ $join_type = $input_join->show($cur_script['join'] && !$join_any ? 'allof' : '');
+ $join_type .= "&nbsp;" . html::label($field_id, rcmail::Q($this->gettext('filterallof')));
+
+ $field_id = 'rcmfd_join_anyof';
+ $input_join = new html_radiobutton(array('name' => '_join', 'id' => $field_id, 'value' => 'anyof', 'onclick' => rcmail_output::JS_OBJECT_NAME . '.sieverules_rule_join_radio(\'anyof\')'));
+ $join_type .= "&nbsp;" . $input_join->show($cur_script['join'] && !$join_any ? '' : 'anyof');
+ $join_type .= "&nbsp;" . html::label($field_id, rcmail::Q($this->gettext('filteranyof')));
+
+ $field_id = 'rcmfd_join_any';
+ $input_join = new html_radiobutton(array('name' => '_join', 'id' => $field_id, 'value' => 'any', 'onclick' => rcmail_output::JS_OBJECT_NAME . '.sieverules_rule_join_radio(\'any\')'));
+ $join_type .= "&nbsp;" . $input_join->show($join_any ? 'any' : '');
+ $join_type .= "&nbsp;" . html::label($field_id, rcmail::Q($this->gettext('filterany')));
+
+ $rules_table = new html_table(array('id' => 'rules-table', 'class' => 'records-table', 'cellspacing' => '0', 'cols' => 5));
+ $rules_table = $this->_rule_row($ext, $rules_table, null, $rcmail->config->get('sieverules_predefined_rules'), $attrib);
+
+ if (!$join_any) {
+ if (!isset($cur_script))
+ $rules_table = $this->_rule_row($ext, $rules_table, array(), $rcmail->config->get('sieverules_predefined_rules'), $attrib);
+ else foreach ($cur_script['tests'] as $rules)
+ $rules_table = $this->_rule_row($ext, $rules_table, $rules, $rcmail->config->get('sieverules_predefined_rules'), $attrib);
+ }
+
+ $this->api->output->set_env('sieverules_rules', $rules_table->size());
+
+ $out .= html::tag('fieldset', null, html::tag('legend', null, rcmail::Q($this->gettext('messagesrules')))
+ . rcmail::Q((!$rcmail->config->get('sieverules_use_elsif', true)) ? $this->gettext('sieveruleexp_stop'): $this->gettext('sieveruleexp')) . "<br /><br />"
+ . $join_type . "<br /><br />"
+ . $rules_table->show($attrib));
+
+ $rcmail->storage_init();
+ $actions_table = new html_table(array('id' => 'actions-table', 'class' => 'records-table', 'cellspacing' => '0', 'cols' => 3));
+ $actions_table = $this->_action_row($ext, $actions_table, 'rowid', null, $attrib, $example);
+
+ if (!isset($cur_script))
+ $actions_table = $this->_action_row($ext, $actions_table, 0, array(), $attrib, $example);
+ else foreach ($cur_script['actions'] as $idx => $actions)
+ $actions_table = $this->_action_row($ext, $actions_table, $idx, $actions, $attrib, $example);
+
+ $this->api->output->set_env('sieverules_actions', $actions_table->size());
+ $this->api->output->set_env('sieverules_htmleditor', $rcmail->config->get('htmleditor'));
+
+ $out .= html::tag('fieldset', null, html::tag('legend', null, rcmail::Q($this->gettext('messagesactions')))
+ . rcmail::Q($this->gettext('sieveactexp')). "<br /><br />"
+ . $actions_table->show($attrib));
+
+ $out .= $form_end;
+
+ // output sigs for vacation messages
+ $user_identities = $rcmail->user->list_identities();
+ if (count($user_identities)) {
+ foreach ($user_identities as $sql_arr) {
+ // add signature to array
+ if (!empty($sql_arr['signature'])) {
+ $identity_id = $sql_arr['identity_id'];
+ $a_signatures[$identity_id]['text'] = $sql_arr['signature'];
+
+ if ($sql_arr['html_signature'] == 1) {
+ $h2t = new rcube_html2text($a_signatures[$identity_id]['text'], false, false);
+ $a_signatures[$identity_id]['text'] = trim($h2t->get_text());
+ }
+ }
+ }
+
+ $this->api->output->set_env('signatures', $a_signatures);
+ }
+
+ return $out;
+ }
+
+ function move()
+ {
+ $this->_startup();
+
+ $src = rcube_utils::get_input_value('_src', rcube_utils::INPUT_GET);
+ $dst = rcube_utils::get_input_value('_dst', rcube_utils::INPUT_GET);
+
+ $result = $this->sieve->script->move_rule($src, $dst);
+ $result = $this->sieve->save();
+
+ if ($result === true)
+ $this->api->output->command('sieverules_update_list', 'move', $src , $dst);
+ else
+ $this->api->output->command('display_message', $result !== false ? $result : $this->gettext('filtersaveerror'), 'error');
+
+ $this->api->output->send();
+ }
+
+ function save()
+ {
+ $rcmail = rcube::get_instance();
+ $this->_startup();
+
+ $script = trim(rcube_utils::get_input_value('_script', rcube_utils::INPUT_POST, true));
+ if ($script != '' && ($rcmail->config->get('sieverules_adveditor') == 1 || $rcmail->config->get('sieverules_adveditor') == 2)) {
+ $script = $this->_strip_val($script);
+ $save = $this->sieve->save($script);
+
+ if ($save === true) {
+ $this->api->output->command('display_message', $this->gettext('filtersaved'), 'confirmation');
+ $this->sieve->get_script();
+ }
+ else {
+ $this->api->output->command('display_message', $save !== false ? $save : $this->gettext('filtersaveerror'), 'error');
+ }
+
+ // go to next step
+ $rcmail->overwrite_action('plugin.sieverules.advanced');
+ $this->action = 'plugin.sieverules.advanced';
+ $this->init_html();
+ }
+ else {
+ // check if POST var limits have been reached
+ // code by Aleksander Machniak
+ $max_post = max(array(
+ ini_get('max_input_vars'),
+ ini_get('suhosin.request.max_vars'),
+ ini_get('suhosin.post.max_vars'),
+ ));
+
+ $max_depth = max(array(
+ ini_get('suhosin.request.max_array_depth'),
+ ini_get('suhosin.post.max_array_depth'),
+ ));
+
+ // check request size limit
+ if ($max_post && count($_POST, COUNT_RECURSIVE) >= $max_post) {
+ rcube::raise_error(array(
+ 'code' => 500,
+ 'type' => 'php',
+ 'file' => __FILE__,
+ 'line' => __LINE__,
+ 'message' => "SieveRules plugin: max_input_vars, suhosin.request.max_vars or suhosin.post.max_vars limit reached."
+ ), true, false);
+
+ $this->api->output->command('display_message', $this->gettext('filtersaveerror'), 'error');
+
+ // go to next step
+ $rcmail->overwrite_action('plugin.sieverules.edit');
+ $this->action = 'plugin.sieverules.edit';
+ $this->init_html();
+
+ return;
+ }
+ // check request depth limits
+ else if ($max_depth && count($_POST['_test']) > $max_depth) {
+ rcube::raise_error(array(
+ 'code' => 500,
+ 'type' => 'php',
+ 'file' => __FILE__,
+ 'line' => __LINE__,
+ 'message' => "SieveRules plugin: suhosin.request.max_array_depth or suhosin.post.max_array_depth limit reached."
+ ), true, false);
+
+ $this->api->output->command('display_message', $this->gettext('filtersaveerror'), 'error');
+
+ // go to next step
+ $rcmail->overwrite_action('plugin.sieverules.edit');
+ $this->action = 'plugin.sieverules.edit';
+ $this->init_html();
+
+ return;
+ }
+
+ $name = trim(rcube_utils::get_input_value('_name', rcube_utils::INPUT_POST, true));
+ $iid = trim(rcube_utils::get_input_value('_iid', rcube_utils::INPUT_POST));
+ $join = trim(rcube_utils::get_input_value('_join', rcube_utils::INPUT_POST));
+ $disabled = trim(rcube_utils::get_input_value('_disable', rcube_utils::INPUT_POST));
+
+ $tests = rcube_utils::get_input_value('_test', rcube_utils::INPUT_POST);
+ $headers = rcube_utils::get_input_value('_header', rcube_utils::INPUT_POST);
+ $bodyparts = rcube_utils::get_input_value('_bodypart', rcube_utils::INPUT_POST);
+ $ops = rcube_utils::get_input_value('_operator', rcube_utils::INPUT_POST);
+ $sizeops = rcube_utils::get_input_value('_size_operator', rcube_utils::INPUT_POST);
+ $dateops = rcube_utils::get_input_value('_date_operator', rcube_utils::INPUT_POST);
+ $spamtestops = rcube_utils::get_input_value('_spamtest_operator', rcube_utils::INPUT_POST);
+ $targets = rcube_utils::get_input_value('_target', rcube_utils::INPUT_POST, true);
+ $sizeunits = rcube_utils::get_input_value('_units', rcube_utils::INPUT_POST);
+ $contentparts = rcube_utils::get_input_value('_body_contentpart', rcube_utils::INPUT_POST);
+ $comparators = rcube_utils::get_input_value('_comparator', rcube_utils::INPUT_POST);
+ $advops = rcube_utils::get_input_value('_advoperator', rcube_utils::INPUT_POST);
+ $advtargets = rcube_utils::get_input_value('_advtarget', rcube_utils::INPUT_POST, true);
+ $actions = rcube_utils::get_input_value('_act', rcube_utils::INPUT_POST);
+ $folders = rcube_utils::get_input_value('_folder', rcube_utils::INPUT_POST);
+ $customfolders = rcube_utils::get_input_value('_customfolder', rcube_utils::INPUT_POST);
+ $addresses = rcube_utils::get_input_value('_redirect', rcube_utils::INPUT_POST);
+ $rejects = rcube_utils::get_input_value('_reject', rcube_utils::INPUT_POST);
+ $vacfroms = rcube_utils::get_input_value('_vacfrom', rcube_utils::INPUT_POST);
+ $vactos = rcube_utils::get_input_value('_vacto', rcube_utils::INPUT_POST);
+ $days = rcube_utils::get_input_value('_day', rcube_utils::INPUT_POST);
+ $handles = rcube_utils::get_input_value('_handle', rcube_utils::INPUT_POST);
+ $subjects = rcube_utils::get_input_value('_subject', rcube_utils::INPUT_POST, true);
+ $origsubjects = rcube_utils::get_input_value('_orig_subject', rcube_utils::INPUT_POST, true);
+ $msgs = rcube_utils::get_input_value('_msg', rcube_utils::INPUT_POST, true);
+ $htmlmsgs = rcube_utils::get_input_value('_htmlmsg', rcube_utils::INPUT_POST, true);
+ $charsets = rcube_utils::get_input_value('_vaccharset', rcube_utils::INPUT_POST);
+ $flags = rcube_utils::get_input_value('_imapflags', rcube_utils::INPUT_POST);
+ $nfroms = rcube_utils::get_input_value('_nfrom', rcube_utils::INPUT_POST);
+ $nimpts = rcube_utils::get_input_value('_nimpt', rcube_utils::INPUT_POST);
+ $nmethods = rcube_utils::get_input_value('_nmethod', rcube_utils::INPUT_POST);
+ $noptions = rcube_utils::get_input_value('_noption', rcube_utils::INPUT_POST);
+ $nmsgs = rcube_utils::get_input_value('_nmsg', rcube_utils::INPUT_POST, true);
+ $dateparts = rcube_utils::get_input_value('_datepart', rcube_utils::INPUT_POST);
+ $weekdays = rcube_utils::get_input_value('_weekday', rcube_utils::INPUT_POST);
+ $advweekdays = rcube_utils::get_input_value('_advweekday', rcube_utils::INPUT_POST);
+ $advweekdays = rcube_utils::get_input_value('_advweekday', rcube_utils::INPUT_POST);
+ $eheadnames = rcube_utils:: get_input_value('_eheadname', rcube_utils::INPUT_POST, true);
+ $eheadvals = rcube_utils::get_input_value('_eheadval', rcube_utils::INPUT_POST, true);
+ $eheadopps = rcube_utils::get_input_value('_eheadopp', rcube_utils::INPUT_POST);
+ $eheadindexes = rcube_utils::get_input_value('_eheadindex', rcube_utils::INPUT_POST);
+
+ $script = array();
+ $script['join'] = ($join == 'allof') ? true : false;
+ $script['name'] = $name;
+ $script['disabled'] = $disabled;
+ $script['tests'] = array();
+ $script['actions'] = array();
+
+ // rules
+ $i = 0;
+ if ($join == 'any') {
+ $script['tests'][0]['type'] = 'true';
+ }
+ else foreach($tests as $idx => $type) {
+ // ignore the first (default) row
+ if ($idx == 0)
+ continue;
+
+ $header = $this->_strip_val($headers[$idx]);
+ $op = $this->_strip_val($ops[$idx]);
+ $bodypart = $this->_strip_val($bodyparts[$idx]);
+ $advop = $this->_strip_val($advops[$idx]);
+ $contentpart = $this->_strip_val($contentparts[$idx]);
+ $target = $this->_strip_val($targets[$idx]);
+ $advtarget = $this->_strip_val($advtargets[$idx]);
+ $comparator = $this->_strip_val($comparators[$idx]);
+ $datepart = $this->_strip_val($dateparts[$idx]);
+ $weekday = $this->_strip_val($weekdays[$idx]);
+ $advweekday = $this->_strip_val($advweekdays[$idx]);
+
+ switch ($type) {
+ case 'size':
+ $sizeop = $this->_strip_val($sizeops[$idx]);
+ $sizeunit = $this->_strip_val($sizeunits[$idx]);
+
+ $script['tests'][$i]['type'] = 'size';
+ $script['tests'][$i]['operator'] = $sizeop;
+ $script['tests'][$i]['target'] = $target.$sizeunit;
+ break;
+ case 'spamtest':
+ case 'virustest':
+ $spamtestop = $this->_strip_val($spamtestops[$idx]);
+
+ $script['tests'][$i]['type'] = $type;
+ $script['tests'][$i]['operator'] = $spamtestop;
+ $script['tests'][$i]['target'] = $target;
+ break;
+ case 'date':
+ $op = $this->_strip_val($dateops[$idx]);
+
+ if ($datepart == 'weekday')
+ $target = $weekday;
+
+ $script['tests'][$i]['datepart'] = $datepart;
+ case 'body':
+ $script['tests'][$i]['bodypart'] = $bodypart;
+
+ if ($bodypart == 'content')
+ $script['tests'][$i]['contentpart'] = $contentpart;
+ else
+ $script['tests'][$i]['contentpart'] = '';
+ case 'exists':
+ case 'header':
+ case 'address':
+ case 'envelope':
+ if (preg_match('/^not/', $op) || preg_match('/^not/', $advop))
+ $script['tests'][$i]['not'] = true;
+ else
+ $script['tests'][$i]['not'] = '';
+
+ $op = preg_replace('/^not/', '', $op);
+ $advop = preg_replace('/^not/', '', $advop);
+ $header = preg_match('/[\s,]+/', $header) ? preg_split('/[\s,]+/', $header, -1, PREG_SPLIT_NO_EMPTY) : $header;
+
+ if ($op == 'exists') {
+ $script['tests'][$i]['type'] = 'exists';
+ $script['tests'][$i]['operator'] = 'exists';
+ $script['tests'][$i]['header'] = $header;
+ }
+ elseif ($op == 'advoptions') {
+ $script['tests'][$i]['type'] = $type;
+ $script['tests'][$i]['operator'] = $advop;
+ $script['tests'][$i]['header'] = $header;
+ $script['tests'][$i]['target'] = $advtarget;
+
+ if (substr($advop, 0, 5) == 'count' || substr($advop, 0, 5) == 'value')
+ $script['tests'][$i]['comparator'] = $comparator;
+ else
+ $script['tests'][$i]['comparator'] = '';
+ }
+ else {
+ $script['tests'][$i]['type'] = $type;
+ $script['tests'][$i]['operator'] = $op;
+ $script['tests'][$i]['header'] = $header;
+ $script['tests'][$i]['target'] = $target;
+ }
+ break;
+ }
+ $i++;
+ }
+
+ // actions
+ $i = 0;
+ foreach($actions as $idx => $type) {
+ // ignore the first (default) row
+ if ($idx == 0)
+ continue;
+
+ $type = $this->_strip_val($type);
+
+ $script['actions'][$i]['type'] = $type;
+
+ switch ($type) {
+ case 'fileinto':
+ case 'fileinto_copy':
+ $folder = $this->_strip_val($folders[$idx], false, false);
+ $rcmail = rcube::get_instance();
+ $rcmail->storage_init();
+ $script['actions'][$i]['create'] = false;
+ if ($folder == '@@newfolder') {
+ $script['actions'][$i]['create'] = true;
+ $folder = $this->_strip_val($customfolders[$idx]);
+ $folder = $rcmail->config->get('sieverules_include_imap_root', true) ? $rcmail->storage->mod_folder($folder, 'IN') : $folder;
+ }
+ $script['actions'][$i]['target'] = $rcmail->config->get('sieverules_include_imap_root', true) ? $folder : $rcmail->storage->mod_folder($folder);
+ if ($rcmail->config->get('sieverules_folder_delimiter', false))
+ $script['actions'][$i]['target'] = str_replace($rcmail->storage->get_hierarchy_delimiter(), $rcmail->config->get('sieverules_folder_delimiter'), $script['actions'][$i]['target']);
+ break;
+ case 'redirect':
+ case 'redirect_copy':
+ $address = $this->_strip_val($addresses[$idx]);
+ $script['actions'][$i]['target'] = $address;
+ break;
+ case 'reject':
+ case 'ereject':
+ $rejects = $this->_strip_val($rejects[$idx]);
+ $script['actions'][$i]['target'] = $rejects;
+ break;
+ case 'vacation':
+ $from = $this->_strip_val($vacfroms[$idx]);
+ $to = $this->_strip_val($vactos[$idx]);
+ $day = $this->_strip_val($days[$idx]);
+ $handle = $this->_strip_val($handles[$idx]);
+ $subject = $this->_strip_val($subjects[$idx]);
+ $origsubject = $this->_strip_val($origsubjects[$idx]);
+ $htmlmsg = $this->_strip_val($htmlmsgs[$idx]);
+ $msg = ($htmlmsg == "1") ? $msgs[$idx] : $this->_strip_val($msgs[$idx]);
+ $charset = $this->_strip_val($charsets[$idx]);
+
+ // format from address
+ if (is_numeric($from)) {
+ if (is_array($identity_arr = $this->_rcmail_get_identity($from))) {
+ if ($identity_arr['val_string'])
+ $from = $identity_arr['val_string'];
+ }
+ else {
+ $from = null;
+ }
+ }
+
+ $script['actions'][$i]['days'] = $day;
+ $script['actions'][$i]['subject'] = $subject;
+ $script['actions'][$i]['origsubject'] = $origsubject;
+ $script['actions'][$i]['from'] = $from;
+ $script['actions'][$i]['addresses'] = $to;
+ $script['actions'][$i]['handle'] = $handle;
+ $script['actions'][$i]['msg'] = $msg;
+ $script['actions'][$i]['htmlmsg'] = ($htmlmsg == "1") ? true : false;
+ $script['actions'][$i]['charset'] = $charset;
+ break;
+ case 'imapflags':
+ case 'imap4flags':
+ $flag = $this->_strip_val($flags[$idx]);
+ $script['actions'][$i]['target'] = $flag;
+ break;
+ case 'notify':
+ case 'enotify':
+ $from = $this->_strip_val($nfroms[$idx]);
+ $importance = $this->_strip_val($nimpts[$idx]);
+ $method = $this->_strip_val($nmethods[$idx]);
+ $option = $this->_strip_val($noptions[$idx]);
+ $msg = $this->_strip_val($nmsgs[$idx]);
+
+ // format from address
+ if (is_numeric($from)) {
+ if (is_array($identity_arr = $this->_rcmail_get_identity($from))) {
+ if ($identity_arr['val_string'])
+ $from = $identity_arr['val_string'];
+ }
+ else {
+ $from = null;
+ }
+ }
+
+ $script['actions'][$i]['from'] = $from;
+ $script['actions'][$i]['importance'] = $importance;
+ $script['actions'][$i]['method'] = $method;
+ $script['actions'][$i]['options'] = $option;
+ $script['actions'][$i]['msg'] = $msg;
+ break;
+ case 'editheaderadd':
+ case 'editheaderrem':
+ $name = $this->_strip_val($eheadnames[$idx]);
+ $value = $this->_strip_val($eheadvals[$idx]);
+ $script['actions'][$i]['name'] = $name;
+ $script['actions'][$i]['value'] = $value;
+ $script['actions'][$i]['index'] = $eheadindexes[$idx];
+
+ if (strlen($script['actions'][$i]['value']) > 0)
+ $script['actions'][$i]['operator'] = $eheadopps[$idx];
+
+ break;
+ }
+
+ $i++;
+ }
+
+ if (!isset($this->script[$iid]))
+ $result = $this->sieve->script->add_rule($script);
+ else
+ $result = $this->sieve->script->update_rule($iid, $script);
+
+ if ($result === true)
+ $save = $this->sieve->save();
+
+ if ($save === true && $result === true && !($rcmail->config->get('sieverules_multiplerules', false) && sizeof($this->sieve->list) > 1))
+ $save = $this->sieve->set_active($this->current_ruleset);
+
+ if ($save === true && $result === true) {
+ $this->api->output->command('display_message', $this->gettext('filtersaved'), 'confirmation');
+
+ if ($script['disabled'] == 1)
+ $filter_name = $script['name'] . ' (' . $this->gettext('disabled') . ')';
+ else
+ $filter_name = $script['name'];
+
+ $dst = $iid - 1;
+ $up_link = $this->api->output->button(array('command' => 'plugin.sieverules.move', 'prop' => $dst, 'type' => 'link', 'class' => 'up_arrow', 'title' => 'sieverules.moveup', 'content' => ' '));
+ $up_link = str_replace("'", "\'", $up_link);
+ $dst = $iid + 2;
+ $down_link = $this->api->output->button(array('command' => 'plugin.sieverules.move', 'prop' => $dst, 'type' => 'link', 'class' => 'down_arrow', 'title' => 'sieverules.movedown', 'content' => ' '));
+ $down_link = str_replace("'", "\'", $down_link);
+
+ if (!isset($this->script[$iid]) && sizeof($this->script) == 0)
+ $this->api->output->add_script("parent.". rcmail_output::JS_OBJECT_NAME .".sieverules_update_list('add-first', 'rcmrow". $iid ."', '". rcmail::Q($filter_name) ."', '". $down_link ."', '". $up_link ."');");
+ elseif (!isset($this->script[$iid]))
+ $this->api->output->add_script("parent.". rcmail_output::JS_OBJECT_NAME .".sieverules_update_list('add', 'rcmrow". $iid ."', '". rcmail::Q($filter_name) ."', '". $down_link ."', '". $up_link ."');");
+ else
+ $this->api->output->add_script("parent.". rcmail_output::JS_OBJECT_NAME .".sieverules_update_list('update', ". $iid .", '". rcmail::Q($filter_name) ."');");
+ }
+ else {
+ if ($result === SIEVE_ERROR_BAD_ACTION)
+ $this->api->output->command('display_message', $this->gettext('filteractionerror'), 'error');
+ elseif ($result === SIEVE_ERROR_NOT_FOUND)
+ $this->api->output->command('display_message', $this->gettext('filtermissingerror'), 'error');
+ else
+ $this->api->output->command('display_message', $save !== false ? $save : $this->gettext('filtersaveerror'), 'error');
+ }
+
+ // update rule list
+ if ($this->sieve_error)
+ $this->script = array();
+ else
+ $this->script = $this->sieve->script->as_array();
+
+ // go to next step
+ $rcmail->overwrite_action('plugin.sieverules.edit');
+ $this->action = 'plugin.sieverules.edit';
+ $this->init_html();
+ }
+ }
+
+ function delete()
+ {
+ $this->_startup();
+
+ $result = false;
+ $ids = rcube_utils::get_input_value('_iid', rcube_utils::INPUT_GET);
+ if (is_numeric($ids) && isset($this->script[$ids]) && !$this->sieve_error) {
+ $result = $this->sieve->script->delete_rule($ids);
+ if ($result === true)
+ $result = $this->sieve->save();
+ }
+
+ if ($result === true) {
+ $this->api->output->command('display_message', $this->gettext('filterdeleted'), 'confirmation');
+ $this->api->output->add_script("parent.". rcmail_output::JS_OBJECT_NAME .".sieverules_update_list('delete', ". $ids .");");
+ }
+ elseif ($result === SIEVE_ERROR_NOT_FOUND)
+ $this->api->output->command('display_message', $this->gettext('filtermissingerror'), 'error');
+ else
+ $this->api->output->command('display_message', $result !== false ? $result : $this->gettext('filterdeleteerror'), 'error');
+
+ // update rule list
+ if ($this->sieve_error)
+ $this->script = array();
+ else
+ $this->script = $this->sieve->script->as_array();
+
+ if (isset($_GET['_framed']) || isset($_POST['_framed'])) {
+ $this->api->output->add_script("parent.". rcmail_output::JS_OBJECT_NAME .".show_contentframe(false);");
+ }
+ else {
+ // go to sieverules page
+ rcube::get_instance()->overwrite_action('plugin.sieverules');
+ $this->action = 'plugin.sieverules';
+ $this->init_html();
+ }
+ }
+
+ function import($type = null, $ruleset = null, $redirect = true)
+ {
+ $rcmail = rcube::get_instance();
+ $this->_startup();
+
+ if (!$type && !$ruleset) {
+ $type = rcube_utils::get_input_value('_type', rcube_utils::INPUT_GET);
+ $ruleset = rcube_utils::get_input_value('_import', rcube_utils::INPUT_GET);
+ }
+
+ if ($ruleset == '_default_') {
+ if ($rcmail->config->get('sieverules_default_file', false) && is_readable($rcmail->config->get('sieverules_default_file'))) {
+ $this->sieve->script->add_text(file_get_contents($rcmail->config->get('sieverules_default_file')));
+ $save = $this->sieve->save();
+
+ if ($save === true && !($rcmail->config->get('sieverules_multiplerules', false) && sizeof($this->sieve->list) > 1))
+ $save = $this->sieve->set_active($this->current_ruleset);
+
+ if ($save === true)
+ $this->api->output->command('display_message', $this->gettext('filterimported'), 'confirmation');
+ else
+ $this->api->output->command('display_message', $save !== false ? $save : $this->gettext('filterimporterror'), 'error');
+
+ // update rule list
+ if ($this->sieve_error)
+ $this->script = array();
+ else
+ $this->script = $this->sieve->script->as_array();
+ }
+ elseif ($rcmail->config->get('sieverules_default_file', false) && !is_readable($rcmail->config->get('sieverules_default_file'))) {
+ rcube::raise_error(array(
+ 'code' => 600,
+ 'type' => 'php',
+ 'file' => __FILE__,
+ 'line' => __LINE__,
+ 'message' => "SieveRules plugin: Unable to open default rule file"
+ ), true, false);
+ }
+ }
+ elseif ($ruleset == '_example_') {
+ if (rcube_utils::get_input_value('_eids', rcube_utils::INPUT_GET)) {
+ $pos = rcube_utils::get_input_value('_pos', rcube_utils::INPUT_GET);
+ $eids = explode(",", rcube_utils::get_input_value('_eids', rcube_utils::INPUT_GET));
+
+ if ($pos == 'end')
+ $pos = null;
+ else
+ $pos = substr($pos, 6);
+
+ foreach ($eids as $eid) {
+ $this->sieve->script->add_rule($this->examples[substr($eid, 2)], $pos);
+ if ($pos) $pos++;
+ }
+
+ $this->sieve->save();
+ if (!($rcmail->config->get('sieverules_multiplerules', false) && sizeof($this->sieve->list) > 1))
+ $this->sieve->set_active($this->current_ruleset);
+
+ // update rule list
+ if ($this->sieve_error)
+ $this->script = array();
+ else
+ $this->script = $this->sieve->script->as_array();
+ }
+ }
+ elseif ($ruleset == '_none_') {
+ $this->sieve->save();
+ if (!($rcmail->config->get('sieverules_multiplerules', false) && sizeof($this->sieve->list) > 1))
+ $this->sieve->set_active($this->current_ruleset);
+ }
+ elseif ($ruleset == '_copy_') {
+ $this->rename_ruleset(true);
+ return;
+ }
+ elseif ($type != '' && $ruleset != '') {
+ $import = $this->sieve->do_import($type, $ruleset);
+
+ if ($import) {
+ $this->script = $this->sieve->script->as_array();
+ $this->sieve->save();
+
+ if (!($rcmail->config->get('sieverules_multiplerules', false) && sizeof($this->sieve->list) > 1))
+ $this->sieve->set_active($this->current_ruleset);
+
+ $this->api->output->command('display_message', $this->gettext('filterimported'), 'confirmation');
+ }
+ else {
+ $this->script = array();
+ if (!$redirect) $this->sieve->save();
+ $this->api->output->command('display_message', $this->gettext('filterimporterror'), 'error');
+ }
+ }
+
+ if ($redirect) {
+ // go to sieverules page
+ $rcmail->overwrite_action('plugin.sieverules');
+ $this->action = 'plugin.sieverules';
+ $this->init_html();
+ }
+ }
+
+ function delete_ruleset()
+ {
+ $this->_startup();
+ $this->sieve->del_script($this->current_ruleset);
+
+ $this->current_ruleset = rcube_utils::get_input_value('_next', rcube_utils::INPUT_GET);
+
+ rcube::get_instance()->overwrite_action('plugin.sieverules');
+ $this->action = 'plugin.sieverules';
+ $this->init_html();
+ }
+
+ function rename_ruleset($makeCopy = false)
+ {
+ $this->_startup();
+ $script = $this->sieve->script->as_text();
+ $active = $this->sieve->get_active() == $this->current_ruleset ? true : false;
+
+ $old_ruleset = $this->current_ruleset;
+ $this->current_ruleset = rcube_utils::get_input_value('_new', rcube_utils::INPUT_GET, true);
+ $this->sieve->set_ruleset($this->current_ruleset);
+ $this->sieve->save($script);
+
+ if (!$makeCopy) {
+ if ($active)
+ $this->sieve->set_active($this->current_ruleset);
+
+ $this->sieve->del_script($old_ruleset);
+ }
+
+ rcube::get_instance()->overwrite_action('plugin.sieverules');
+ $this->action = 'plugin.sieverules';
+ $this->init_html();
+ }
+
+ function enable_ruleset()
+ {
+ $this->_startup();
+ $activeruleset = rcube_utils::get_input_value('_ruleset', rcube_utils::INPUT_GET, true);
+ $this->sieve->set_active($activeruleset);
+
+ if (rcube_utils::get_input_value('_reload', rcube_utils::INPUT_GET, true) == "1") {
+ rcube::get_instance()->overwrite_action('plugin.sieverules');
+ $this->action = 'plugin.sieverules';
+ $this->init_html();
+ }
+ else {
+ $rulesets = array();
+ foreach ($this->sieve->list as $ruleset)
+ array_push($rulesets, $ruleset);
+
+ sort($rulesets);
+
+ foreach ($rulesets as $ruleset) {
+ if ($ruleset === $activeruleset)
+ $this->api->output->command('sieverules_add_ruleset', rcmail::Q($ruleset), rcmail::Q(str_replace('%s', $ruleset, $this->gettext('activeruleset'))));
+ else
+ $this->api->output->command('sieverules_add_ruleset', rcmail::Q($ruleset), rcmail::Q($ruleset));
+ }
+
+ $this->api->output->send();
+ }
+ }
+
+ function copy_filter()
+ {
+ $this->_startup();
+ $script = $this->script[rcube_utils::get_input_value('_iid', rcube_utils::INPUT_GET)];
+ $this->current_ruleset = rcube_utils::get_input_value('_dest', rcube_utils::INPUT_GET);
+ $this->_startup();
+ $this->sieve->script->add_rule($script);
+ $this->sieve->save();
+
+ $this->api->output->command('display_message', $this->gettext('filtercopied'), 'confirmation');
+ $this->api->output->send();
+ }
+
+ private function _startup()
+ {
+ $rcmail = rcube::get_instance();
+
+ if (!$this->sieve) {
+ include('lib/Net/Sieve.php');
+ include('include/rcube_sieve.php');
+ include('include/rcube_sieve_script.php');
+ $rcmail = rcube::get_instance();
+
+ // try to connect to managesieve server and to fetch the script
+ $this->sieve = new rcube_sieve($_SESSION['username'],
+ $rcmail->decrypt($_SESSION['password']),
+ rcube_utils::idn_to_ascii(rcube_utils::parse_host($rcmail->config->get('sieverules_host'))),
+ $rcmail->config->get('sieverules_port'), $rcmail->config->get('sieverules_auth_type', NULL),
+ $rcmail->config->get('sieverules_usetls'), $this->current_ruleset,
+ $this->home, $rcmail->config->get('sieverules_use_elsif', true),
+ $rcmail->config->get('sieverules_auth_cid', NULL), $rcmail->config->get('sieverules_auth_pw', NULL));
+
+ if ($rcmail->config->get('sieverules_debug', false))
+ $this->sieve->set_debug(true);
+
+ $this->sieve_error = $this->sieve->error();
+
+ if ($this->sieve_error == SIEVE_ERROR_NOT_EXISTS) {
+ // load default rule set
+ if (($rcmail->config->get('sieverules_default_file', false) && is_readable($rcmail->config->get('sieverules_default_file'))) || sizeof($this->sieve->list) > 0) {
+ $rcmail->overwrite_action('plugin.sieverules.setup');
+ $this->action = 'plugin.sieverules.setup';
+ }
+ elseif ($rcmail->config->get('sieverules_default_file', false) && !is_readable($rcmail->config->get('sieverules_default_file'))) {
+ rcube::raise_error(array(
+ 'code' => 600,
+ 'type' => 'php',
+ 'file' => __FILE__,
+ 'line' => __LINE__,
+ 'message' => "SieveRules plugin: Unable to open default rule file"
+ ), true, false);
+ }
+
+ // that's not exactly an error
+ $this->sieve_error = false;
+ }
+ elseif ($this->sieve_error) {
+ switch ($this->sieve_error) {
+ case SIEVE_ERROR_CONNECTION:
+ case SIEVE_ERROR_LOGIN:
+ $this->api->output->command('display_message', $this->gettext('filterconnerror'), 'error');
+ break;
+ default:
+ $this->api->output->command('display_message', $this->gettext('filterunknownerror'), 'error');
+ break;
+ }
+
+ $this->api->output->set_env('sieveruleserror', true);
+ }
+
+ // finally set script objects
+ if ($this->sieve_error) {
+ $this->script = array();
+ }
+ else {
+ $this->script = $this->sieve->script->as_array();
+
+ // load example filters
+ if ($rcmail->config->get('sieverules_example_file', false) && is_readable($rcmail->config->get('sieverules_example_file')))
+ $this->examples = $this->sieve->script->parse_text(file_get_contents($rcmail->config->get('sieverules_example_file')));
+ elseif ($rcmail->config->get('sieverules_example_file', false) && !is_readable($rcmail->config->get('sieverules_example_file')))
+ rcube::raise_error(array(
+ 'code' => 600,
+ 'type' => 'php',
+ 'file' => __FILE__,
+ 'line' => __LINE__,
+ 'message' => "SieveRules plugin: Unable to open example rule file"
+ ), true, false);
+ }
+ }
+ else {
+ $this->sieve->set_ruleset($this->current_ruleset);
+ $this->script = $this->sieve->script->as_array();
+ }
+ }
+
+ private function _rule_row($ext, $rules_table, $rule, $predefined_rules, $attrib)
+ {
+ $rcmail = rcube::get_instance();
+
+ if (!isset($rule))
+ $rules_table->set_row_attribs(array('style' => 'display: none;'));
+
+ if (in_array('regex', $ext) || in_array('relational', $ext) || in_array('subaddress', $ext))
+ $this->operators['filteradvoptions'] = 'advoptions';
+
+ $header_style = 'visibility: hidden;';
+ $op_style = '';
+ $sizeop_style = 'display: none;';
+ $dateop_style = 'display: none;';
+ $spamtestop_style = 'display: none;';
+ $target_style = '';
+ $units_style = 'display: none;';
+ $bodypart_style = 'display: none;';
+ $datepart_style = 'display: none;';
+ $advcontentpart_style = 'display: none;';
+ $spam_prob_style = 'display: none;';
+ $virus_prob_style = 'display: none;';
+ $weekdays_style = 'display: none;';
+ $advweekdays_style = 'display: none;';
+ $advtarget_style = '';
+
+ $test = 'header';
+ $selheader = 'Subject';
+ $header = 'Subject';
+ $op = 'contains';
+ $sizeop = 'under';
+ $spamtestop = 'ge';
+ $target = '';
+ $target_size = '';
+ $units = 'KB';
+ $bodypart = '';
+ $advcontentpart = '';
+
+ $predefined = -1;
+ foreach($predefined_rules as $idx => $data) {
+ if (($data['type'] == $rule['type'] || $rule['type'] == 'exists')
+ && $data['header'] == $rule['header']
+ && $data['operator'] == ($rule['not'] ? 'not' : '') . $rule['operator']
+ && $data['target'] == $rule['target']) {
+ $predefined = $idx;
+ break;
+ }
+ }
+
+ if ($predefined > -1) {
+ $op_style = 'display: none;';
+ $target_style = 'display: none;';
+ $selheader = $rule['type'] . '::predefined_' . $predefined;
+ $test = $rule['type'];
+
+ if ($rule['type'] == 'size') {
+ $header = 'size';
+ $sizeop = $rule['operator'];
+ preg_match('/^([0-9]+)(K|M|G)*$/', $rule['target'], $matches);
+ $target = $matches[1];
+ $target_size = 'short';
+ $units = $matches[2];
+ }
+ elseif ($rule['type'] == 'spamtest') {
+ $header = 'spamtest';
+ $spamtestop = $rule['operator'];
+ $target = $rule['target'];
+ }
+ elseif ($rule['type'] == 'virustest') {
+ $header = 'virustest';
+ $spamtestop = $rule['operator'];
+ $target = $rule['target'];
+ }
+ elseif ($rule['type'] == 'exists') {
+ $selheader = $predefined_rules[$predefined]['type'] . '::predefined_' . $predefined;
+ $header = $rule['header'];
+ $op = ($rule['not'] ? 'not' : '') . $rule['operator'];
+ }
+ else {
+ $header = $rule['header'];
+ $op = ($rule['not'] ? 'not' : '') . $rule['operator'];
+ $target = $rule['target'];
+ }
+ }
+ elseif ((isset($rule['type']) && $rule['type'] != 'exists') && in_array($rule['type'] . '::' . $rule['header'], $this->headers)) {
+ $target_style = $rule['operator'] == 'exists' ? 'display: none;' : '';
+
+ $selheader = $rule['type'] . '::' . $rule['header'];
+ $test = $rule['type'];
+ $header = $rule['header'];
+ $op = ($rule['not'] ? 'not' : '') . $rule['operator'];
+ $target = $rule['target'];
+ }
+ elseif ((isset($rule['type']) && $rule['type'] == 'exists') && $this->_in_headerarray($rule['header'], $this->headers) != false) {
+ $target_style = $rule['operator'] == 'exists' ? 'display: none;' : '';
+
+ $selheader = $this->_in_headerarray($rule['header'], $this->headers) . '::' . $rule['header'];
+ $test = $rule['type'];
+ $header = $rule['header'];
+ $op = ($rule['not'] ? 'not' : '') . $rule['operator'];
+ }
+ elseif (isset($rule['type']) && $rule['type'] == 'size') {
+ $op_style = 'display: none;';
+ $sizeop_style = '';
+ $units_style = '';
+
+ $selheader = 'size::size';
+ $header = 'size';
+ $test = 'size';
+ $sizeop = $rule['operator'];
+ preg_match('/^([0-9]+)(K|M|G)*$/', $rule['target'], $matches);
+ $target = $matches[1];
+ $target_size = 'short';
+ $units = $matches[2];
+ }
+ elseif (isset($rule['type']) && $rule['type'] == 'body') {
+ $bodypart_style = '';
+ $header_style = 'display: none;';
+
+ $selheader = 'body::body';
+ $header = 'body';
+ $test = 'body';
+ $bodypart = $rule['bodypart'];
+ $op = ($rule['not'] ? 'not' : '') . $rule['operator'];
+ $target = $rule['target'];
+
+ if ($rule['contentpart'] != '') {
+ $advcontentpart = $rule['contentpart'];
+ $advcontentpart_style = '';
+ }
+ }
+ elseif (isset($rule['type']) && $rule['type'] == 'spamtest') {
+ $op_style = 'display: none;';
+ $target_style = 'display: none;';
+ $spamtestop_style = '';
+ $spam_prob_style = '';
+
+ $test = $rule['type'];
+ $selheader = 'spamtest::spamtest';
+ $header = 'spamtest';
+ $spamtestop = $rule['operator'];
+ $target = $rule['target'];
+ $spam_probability = $rule['target'];
+ }
+ elseif (isset($rule['type']) && $rule['type'] == 'virustest') {
+ $op_style = 'display: none;';
+ $target_style = 'display: none;';
+ $spamtestop_style = '';
+ $virus_prob_style = '';
+
+ $test = $rule['type'];
+ $selheader = 'virustest::virustest';
+ $header = 'virustest';
+ $spamtestop = $rule['operator'];
+ $target = $rule['target'];
+ $virus_probability = $rule['target'];
+ }
+ elseif (isset($rule['type']) && $rule['type'] == 'date') {
+ $op_style = 'display: none;';
+ $dateop_style = '';
+ $header_style = 'display: none;';
+ $datepart_style = '';
+
+ if ($rule['datepart'] == 'weekday') {
+ $target_style = 'display: none;';
+ $advtarget_style = 'display: none;';
+ $weekdays_style = '';
+ $advweekdays_style = '';
+ }
+
+ $test = $rule['type'];
+ $selheader = 'date::' . $rule['header'];
+ $header = $rule['header'];
+ $datepart = $rule['datepart'];
+ $dateop = ($rule['not'] ? 'not' : '') . $rule['operator'];
+ $target = $rule['target'];
+ }
+ elseif (isset($rule['type']) && $rule['type'] != 'true') {
+ $header_style = '';
+ $target_style = $rule['operator'] == 'exists' ? 'display: none;' : '';
+
+ $selheader = 'header::other';
+ $test = 'header';
+ $header = is_array($rule['header']) ? join(', ', $rule['header']) : $rule['header'];
+ $op = ($rule['not'] ? 'not' : '') . $rule['operator'];
+ $target = $rule['target'];
+ }
+
+ // check for advanced options
+ $showadvanced = false;
+ if (!in_array($op, $this->operators) || $rule['comparator'] != '' || $rule['contentpart'] != '') {
+ $showadvanced = true;
+ $target_style = 'display: none;';
+ }
+
+ $select_header = new html_select(array('name' => "_selheader[]", 'onchange' => rcmail_output::JS_OBJECT_NAME . '.sieverules_header_select(this)'));
+ foreach($this->headers as $name => $val) {
+ if (($val == 'envelope' && in_array('envelope', $ext)) || $val != 'envelope')
+ $select_header->add(rcmail::Q($this->gettext($name)), rcmail::Q($val));
+ }
+
+ if (in_array('body', $ext))
+ $select_header->add(rcmail::Q($this->gettext('body')), rcmail::Q('body::body'));
+
+ if (in_array('spamtest', $ext))
+ $select_header->add(rcmail::Q($this->gettext('spamtest')), rcmail::Q('spamtest::spamtest'));
+
+ if (in_array('virustest', $ext))
+ $select_header->add(rcmail::Q($this->gettext('virustest')), rcmail::Q('virustest::virustest'));
+
+ foreach($predefined_rules as $idx => $data)
+ $select_header->add(rcmail::Q($data['name']), rcmail::Q($data['type'] . '::predefined_' . $idx));
+
+ if (in_array('date', $ext))
+ $select_header->add(rcmail::Q($this->gettext('arrival')), rcmail::Q('date::currentdate'));
+
+ $select_header->add(rcmail::Q($this->gettext('size')), rcmail::Q('size::size'));
+ $select_header->add(rcmail::Q($this->gettext('otherheader')), rcmail::Q('header::other'));
+ $input_test = new html_hiddenfield(array('name' => '_test[]', 'value' => $test));
+ $rules_table->add('selheader', $select_header->show($selheader) . $input_test->show());
+
+ $help_button = html::img(array('src' => $attrib['helpicon'], 'alt' => $this->gettext('sieveruleheaders'), 'border' => 0, 'style' => 'margin-left: 4px;'));
+ $help_button = html::a(array('name' => '_headerhlp', 'href' => "#", 'onclick' => 'return '. rcmail_output::JS_OBJECT_NAME .'.sieverules_xheaders(this);', 'title' => $this->gettext('sieveruleheaders'), 'style' => $header_style), $help_button);
+
+ $input_header = new html_inputfield(array('name' => '_header[]', 'style' => $header_style, 'class' => 'short'));
+ $select_bodypart = new html_select(array('name' => '_bodypart[]', 'onchange' => rcmail_output::JS_OBJECT_NAME . '.sieverules_bodypart_select(this)', 'style' => $bodypart_style));
+ $select_bodypart->add(rcmail::Q($this->gettext('auto')), rcmail::Q(''));
+ $select_bodypart->add(rcmail::Q($this->gettext('raw')), rcmail::Q('raw'));
+ $select_bodypart->add(rcmail::Q($this->gettext('text')), rcmail::Q('text'));
+ $select_bodypart->add(rcmail::Q($this->gettext('other')), rcmail::Q('content'));
+ $select_datepart = new html_select(array('name' => '_datepart[]', 'onchange' => rcmail_output::JS_OBJECT_NAME . '.sieverules_datepart_select(this)','style' => $datepart_style));
+ $select_datepart->add(rcmail::Q($this->gettext('date')), rcmail::Q('date'));
+ $select_datepart->add(rcmail::Q($this->gettext('time')), rcmail::Q('time'));
+ $select_datepart->add(rcmail::Q($this->gettext('weekday')), rcmail::Q('weekday'));
+ $rules_table->add('header', $input_header->show($header) . $help_button . $select_bodypart->show($bodypart) . $select_datepart->show($datepart));
+
+ $select_op = new html_select(array('name' => "_operator[]", 'onchange' => rcmail_output::JS_OBJECT_NAME . '.sieverules_rule_op_select(this)', 'style' => $op_style));
+ foreach($this->operators as $name => $val)
+ $select_op->add(rcmail::Q($this->gettext($name)), $val);
+
+ $select_size_op = new html_select(array('name' => "_size_operator[]", 'style' => $sizeop_style));
+ $select_size_op->add(rcmail::Q($this->gettext('filterunder')), 'under');
+ $select_size_op->add(rcmail::Q($this->gettext('filterover')), 'over');
+
+ $select_date_op = new html_select(array('name' => "_date_operator[]", 'style' => $dateop_style));
+ $select_date_op->add(rcmail::Q($this->gettext('filteris')), 'is');
+ $select_date_op->add(rcmail::Q($this->gettext('filterisnot')), 'notis');
+
+ if (in_array('relational', $ext)) {
+ $select_date_op->add(rcmail::Q($this->gettext('filterbefore')), 'value "lt"');
+ $select_date_op->add(rcmail::Q($this->gettext('filterafter')), 'value "gt"');
+ }
+
+ $select_spamtest_op = new html_select(array('name' => "_spamtest_operator[]", 'style' => $spamtestop_style));
+ $select_spamtest_op->add(rcmail::Q($this->gettext('spamlevelequals')), 'eq');
+ $select_spamtest_op->add(rcmail::Q($this->gettext('spamlevelislessthanequal')), 'le');
+ $select_spamtest_op->add(rcmail::Q($this->gettext('spamlevelisgreaterthanequal')), 'ge');
+
+ if ($showadvanced)
+ $rules_table->add('op', $select_op->show('advoptions') . $select_size_op->show($sizeop) . $select_date_op->show($dateop) . $select_spamtest_op->show($spamtestop));
+ else
+ $rules_table->add('op', $select_op->show($op) . $select_size_op->show($sizeop) . $select_date_op->show($dateop) . $select_spamtest_op->show($spamtestop));
+
+ $input_target = new html_inputfield(array('name' => '_target[]', 'style' => $target_style, 'class' => $target_size));
+
+ $select_units = new html_select(array('name' => "_units[]", 'style' => $units_style, 'class' => 'short'));
+ $select_units->add(rcmail::Q($this->gettext('B')), '');
+ $select_units->add(rcmail::Q($this->gettext('KB')), 'K');
+ $select_units->add(rcmail::Q($this->gettext('MB')), 'M');
+
+ $select_spam_probability = new html_select(array('name' => "_spam_probability[]", 'style' => $spam_prob_style, 'class' => 'long'));
+ $select_spam_probability->add(rcmail::Q($this->gettext('notchecked')), '0');
+ $select_spam_probability->add(rcmail::Q("0%"), '1');
+ $select_spam_probability->add(rcmail::Q("10%"), '2');
+ $select_spam_probability->add(rcmail::Q("20%"), '3');
+ $select_spam_probability->add(rcmail::Q("40%"), '4');
+ $select_spam_probability->add(rcmail::Q("50%"), '5');
+ $select_spam_probability->add(rcmail::Q("60%"), '6');
+ $select_spam_probability->add(rcmail::Q("70%"), '7');
+ $select_spam_probability->add(rcmail::Q("80%"), '8');
+ $select_spam_probability->add(rcmail::Q("90%"), '9');
+ $select_spam_probability->add(rcmail::Q("100%"), '10');
+
+ $select_virus_probability = new html_select(array('name' => "_virus_probability[]", 'style' => $virus_prob_style, 'class' => 'long'));
+ $select_virus_probability->add(rcmail::Q($this->gettext('notchecked')), '0');
+ $select_virus_probability->add(rcmail::Q($this->gettext('novirus')), '1');
+ $select_virus_probability->add(rcmail::Q($this->gettext('virusremoved')), '2');
+ $select_virus_probability->add(rcmail::Q($this->gettext('viruscured')), '3');
+ $select_virus_probability->add(rcmail::Q($this->gettext('possiblevirus')), '4');
+ $select_virus_probability->add(rcmail::Q($this->gettext('definitevirus')), '5');
+
+ $select_weekdays = new html_select(array('name' => "_weekday[]", 'style' => $weekdays_style, 'class' => 'long'));
+ $select_weekdays->add(rcmail::Q($this->gettext('sunday')), '0');
+ $select_weekdays->add(rcmail::Q($this->gettext('monday')), '1');
+ $select_weekdays->add(rcmail::Q($this->gettext('tuesday')), '2');
+ $select_weekdays->add(rcmail::Q($this->gettext('wednesday')), '3');
+ $select_weekdays->add(rcmail::Q($this->gettext('thursday')), '4');
+ $select_weekdays->add(rcmail::Q($this->gettext('friday')), '5');
+ $select_weekdays->add(rcmail::Q($this->gettext('saturday')), '6');
+
+ $rules_table->add('target', $select_weekdays->show($target) . $select_spam_probability->show($spam_probability) . $select_virus_probability->show($virus_probability) . $input_target->show($target) . "&nbsp;" . $select_units->show($units));
+
+ $add_button = $this->api->output->button(array('command' => 'plugin.sieverules.add_rule', 'type' => 'link', 'class' => 'add', 'title' => 'sieverules.addsieverule', 'content' => ' '));
+ $delete_button = $this->api->output->button(array('command' => 'plugin.sieverules.del_rule', 'type' => 'link', 'class' => 'delete', 'classact' => 'delete_act', 'title' => 'sieverules.deletesieverule', 'content' => ' '));
+ $rules_table->add('control', $delete_button . $add_button);
+
+ if (isset($rule))
+ $rowid = $rules_table->size();
+ else
+ $rowid = 'rowid';
+
+ $headers_table = new html_table(array('class' => 'records-table', 'cellspacing' => '0', 'cols' => 4));
+ $headers_table->add(array('colspan' => 4, 'style' => 'white-space: normal;'), rcmail::Q($this->gettext('sieveheadershlp')));
+
+ $col1 = '';
+ $col2 = '';
+ $col3 = '';
+ $col4 = '';
+ $other_headers = $rcmail->config->get('sieverules_other_headers');
+ sort($other_headers);
+ $col_length = sizeof($other_headers) / 4;
+ $col_length = ceil($col_length);
+ foreach ($other_headers as $idx => $xheader) {
+ $input_xheader = new html_radiobutton(array('id' => $xheader . '_' . $rowid, 'name' => '_xheaders_' . $rowid . '[]', 'value' => $xheader, 'onclick' => rcmail_output::JS_OBJECT_NAME . '.sieverules_set_xheader(this)', 'class' => 'radio'));
+ $xheader_show = $input_xheader->show($header) . "&nbsp;" . html::label($xheader . '_' . $rowid, rcmail::Q($xheader));
+
+ if ($idx < $col_length)
+ $col1 .= $xheader_show . "<br />";
+ elseif ($idx < $col_length * 2)
+ $col2 .= $xheader_show . "<br />";
+ elseif ($idx < $col_length * 3)
+ $col3 .= $xheader_show . "<br />";
+ elseif ($idx < $col_length * 4)
+ $col4 .= $xheader_show . "<br />";
+ }
+
+ $headers_table->add(array('style' => 'vertical-align: top; width: 25%;'), $col1);
+ $headers_table->add(array('style' => 'vertical-align: top; width: 25%;'), $col2);
+ $headers_table->add(array('style' => 'vertical-align: top; width: 25%;'), $col3);
+ $headers_table->add(array('style' => 'vertical-align: top; width: 25%;'), $col4);
+
+ $rules_table->set_row_attribs(array('style' => 'display: none;'));
+ $rules_table->add(array('colspan' => 5), $headers_table->show());
+
+ $advanced_table = new html_table(array('class' => 'records-table', 'cellspacing' => '0', 'cols' => 2));
+ $advanced_table->add(array('colspan' => 2, 'style' => 'white-space: normal;'), rcmail::Q($this->gettext('advancedoptions')));
+
+ $help_button = html::img(array('src' => $attrib['helpicon'], 'alt' => $this->gettext('contentpart'), 'border' => 0, 'style' => 'margin-left: 4px;'));
+ $help_button = html::a(array('href' => "#", 'onclick' => 'return '. rcmail_output::JS_OBJECT_NAME .'.sieverules_help(this, ' . $advanced_table->size() . ');', 'title' => $this->gettext('contentpart')), $help_button);
+
+ $field_id = 'rcmfd_advcontentpart_'. $rowid;
+ $advanced_table->set_row_attribs(array('style' => $advcontentpart_style));
+ $input_advcontentpart = new html_inputfield(array('id' => $field_id, 'name' => '_body_contentpart[]', 'class' => 'short'));
+ $advanced_table->add(array('style' => 'white-space: normal;', 'class' => 'selheader'), html::label($field_id, rcmail::Q($this->gettext('bodycontentpart'))));
+ $advanced_table->add(array('style' => 'white-space: normal;'), $input_advcontentpart->show($advcontentpart) . $help_button);
+
+ $advanced_table->set_row_attribs(array('class' => 'advhelp', 'style' => 'display: none;'));
+ $advanced_table->add(array('colspan' => 2, 'class' => 'vacdaysexp'), $this->gettext('contentpartexp'));
+
+ $field_id = 'rcmfd_advoperator_'. $rowid;
+ $select_advop = new html_select(array('id' => $field_id, 'name' => "_advoperator[]", 'onchange' => rcmail_output::JS_OBJECT_NAME . '.sieverules_rule_advop_select(this)'));
+
+ if (in_array('regex', $ext)) {
+ $select_advop->add(rcmail::Q($this->gettext('filterregex')), 'regex');
+ $select_advop->add(rcmail::Q($this->gettext('filternotregex')), 'notregex');
+ }
+
+ if (in_array('relational', $ext)) {
+ $select_advop->add(rcmail::Q($this->gettext('countisgreaterthan')), 'count "gt"');
+ $select_advop->add(rcmail::Q($this->gettext('countisgreaterthanequal')), 'count "ge"');
+ $select_advop->add(rcmail::Q($this->gettext('countislessthan')), 'count "lt"');
+ $select_advop->add(rcmail::Q($this->gettext('countislessthanequal')), 'count "le"');
+ $select_advop->add(rcmail::Q($this->gettext('countequals')), 'count "eq"');
+ $select_advop->add(rcmail::Q($this->gettext('countnotequals')), 'count "ne"');
+ $select_advop->add(rcmail::Q($this->gettext('valueisgreaterthan')), 'value "gt"');
+ $select_advop->add(rcmail::Q($this->gettext('valueisgreaterthanequal')), 'value "ge"');
+ $select_advop->add(rcmail::Q($this->gettext('valueislessthan')), 'value "lt"');
+ $select_advop->add(rcmail::Q($this->gettext('valueislessthanequal')), 'value "le"');
+ $select_advop->add(rcmail::Q($this->gettext('valueequals')), 'value "eq"');
+ $select_advop->add(rcmail::Q($this->gettext('valuenotequals')), 'value "ne"');
+ }
+
+ if (in_array('subaddress', $ext)) {
+ $select_advop->add(rcmail::Q($this->gettext('userpart')), 'user');
+ $select_advop->add(rcmail::Q($this->gettext('notuserpart')), 'notuser');
+ $select_advop->add(rcmail::Q($this->gettext('detailpart')), 'detail');
+ $select_advop->add(rcmail::Q($this->gettext('notdetailpart')), 'notdetail');
+ $select_advop->add(rcmail::Q($this->gettext('domainpart')), 'domain');
+ $select_advop->add(rcmail::Q($this->gettext('notdomainpart')), 'notdomain');
+ }
+
+ $advanced_table->add(array('style' => 'white-space: normal;', 'class' => 'selheader'), html::label($field_id, rcmail::Q($this->gettext('operator'))));
+ $advanced_table->add(array('style' => 'white-space: normal;'), $select_advop->show($op));
+
+ $field_id = 'rcmfd_comparator_'. $rowid;
+ if (substr($op, 0, 5) == 'count' || substr($op, 0, 5) == 'value')
+ $select_comparator = new html_select(array('id' => $field_id, 'name' => "_comparator[]"));
+ else
+ $select_comparator = new html_select(array('id' => $field_id, 'name' => "_comparator[]", 'disabled' => 'disabled'));
+
+ $select_comparator->add(rcmail::Q($this->gettext('i;ascii-casemap')), '');
+ $select_comparator->add(rcmail::Q($this->gettext('i;octet')), 'i;octet');
+
+ foreach ($ext as $extension) {
+ if (substr($extension, 0, 11) == 'comparator-' && $extension != 'comparator-i;ascii-casemap' && $extension != 'comparator-i;octet')
+ $select_comparator->add(rcmail::Q($this->gettext(substr($extension, 11))), substr($extension, 11));
+ }
+
+ $advanced_table->add(array('style' => 'white-space: normal;', 'class' => 'selheader'), html::label($field_id, rcmail::Q($this->gettext('comparator'))));
+ $advanced_table->add(array('style' => 'white-space: normal;'), $select_comparator->show($rule['comparator']));
+
+ $select_advweekdays = new html_select(array('name' => "_advweekday[]", 'style' => $advweekdays_style));
+ $select_advweekdays->add(rcmail::Q($this->gettext('sunday')), '0');
+ $select_advweekdays->add(rcmail::Q($this->gettext('monday')), '1');
+ $select_advweekdays->add(rcmail::Q($this->gettext('tuesday')), '2');
+ $select_advweekdays->add(rcmail::Q($this->gettext('wednesday')), '3');
+ $select_advweekdays->add(rcmail::Q($this->gettext('thursday')), '4');
+ $select_advweekdays->add(rcmail::Q($this->gettext('friday')), '5');
+ $select_advweekdays->add(rcmail::Q($this->gettext('saturday')), '6');
+
+ $field_id = 'rcmfd_advtarget_'. $rowid;
+ $input_advtarget = new html_inputfield(array('id' => $field_id, 'name' => '_advtarget[]', 'style' => $advtarget_style));
+ $advanced_table->add(array('style' => 'white-space: normal;', 'class' => 'selheader'), html::label($field_id, rcmail::Q($this->gettext('teststring'))));
+ $advanced_table->add(array('style' => 'white-space: normal;'), $input_advtarget->show($target) . $select_advweekdays->show($target));
+
+ if (!($showadvanced && $predefined == -1))
+ $rules_table->set_row_attribs(array('style' => 'display: none;'));
+ $rules_table->add(array('colspan' => 5), $advanced_table->show());
+
+ return $rules_table;
+ }
+
+ private function _action_row($ext, $actions_table, $rowid, $action, $attrib, $example)
+ {
+ $rcmail = rcube::get_instance();
+ static $a_mailboxes;
+
+ if (!isset($action))
+ $actions_table->set_row_attribs(array('style' => 'display: none;'));
+
+ $help_icon = html::img(array('src' => $attrib['helpicon'], 'alt' => $this->gettext('messagehelp'), 'border' => 0));
+
+ $vacadvstyle = ($action['type'] != 'vacation' && $this->force_vacto) ? '' : 'display: none;';
+ $vacadvstyle_from = ($this->show_vacfrom) ? $vacadvstyle : 'display: none;';
+ $vacadvstyle_handle = ($this->show_vachandle) ? $vacadvstyle : 'display: none;';
+ $vacadvclass_from = ($this->show_vacfrom) ? 'advanced' : 'disabled';
+ $vacadvclass_handle = ($this->show_vachandle) ? 'advanced' : 'disabled';
+ $vacshowadv = ($action['type'] != 'vacation' && $this->force_vacto) ? '1' : '';
+ $noteadvstyle = 'display: none;';
+ $noteshowadv = '';
+ $eheadadvstyle = 'display: none;';
+ $eheadshowadv = '';
+
+ // setup allowed actions
+ $allowed_actions = array();
+ $config_actions = $rcmail->config->get('sieverules_allowed_actions', array());
+ if (in_array('fileinto', $ext) && ($config_actions['fileinto'] || $action['type'] == 'fileinto'))
+ $allowed_actions['fileinto'] = $this->gettext('messagemoveto');
+ if (in_array('fileinto', $ext) && in_array('copy', $ext) && ($config_actions['fileinto'] || $action['type'] == 'fileinto'))
+ $allowed_actions['fileinto_copy'] = $this->gettext('messagecopyto');
+ if (in_array('vacation', $ext) && ($config_actions['vacation'] || $action['type'] == 'vacation'))
+ $allowed_actions['vacation'] = $this->gettext('messagevacation');
+ if (in_array('reject', $ext) && ($config_actions['reject'] || $action['type'] == 'reject'))
+ $allowed_actions['reject'] = $this->gettext('messagereject');
+ elseif (in_array('ereject', $ext) && ($config_actions['reject'] || $action['type'] == 'ereject'))
+ $allowed_actions['ereject'] = $this->gettext('messagereject');
+ if (in_array('imap4flags', $ext) && ($config_actions['imapflags'] || $action['type'] == 'imap4flags'))
+ $allowed_actions['imap4flags'] = $this->gettext('messageimapflags');
+ elseif (in_array('imapflags', $ext) && ($config_actions['imapflags'] || $action['type'] == 'imapflags'))
+ $allowed_actions['imapflags'] = $this->gettext('messageimapflags');
+ if (in_array('notify', $ext) && ($config_actions['notify'] || $action['type'] == 'notify'))
+ $allowed_actions['notify'] = $this->gettext('messagenotify');
+ elseif (in_array('enotify', $ext) && ($config_actions['notify'] || $action['type'] == 'enotify'))
+ $allowed_actions['enotify'] = $this->gettext('messagenotify');
+ if (in_array('editheader', $ext) && ($config_actions['editheaderadd'] || $action['type'] == 'editheaderadd'))
+ $allowed_actions['editheaderadd'] = $this->gettext('addheader');
+ if (in_array('editheader', $ext) && ($config_actions['editheaderrem'] || $action['type'] == 'editheaderrem'))
+ $allowed_actions['editheaderrem'] = $this->gettext('removeheader');
+ if ($config_actions['redirect'] || $action['type'] == 'redirect')
+ $allowed_actions['redirect'] = $this->gettext('messageredirect');
+ if (in_array('copy', $ext) && ($config_actions['redirect'] || $action['type'] == 'redirect_copy'))
+ $allowed_actions['redirect_copy'] = $this->gettext('messageredirectcopy');
+ if ($config_actions['keep'] || $action['type'] == 'keep')
+ $allowed_actions['keep'] = $this->gettext('messagekeep');
+ if ($config_actions['discard'] || $action['type'] == 'discard')
+ $allowed_actions['discard'] = $this->gettext('messagediscard');
+ if ($config_actions['stop'] || $action['type'] == 'stop')
+ $allowed_actions['stop'] = $this->gettext('messagestop');
+
+ // set the default action
+ reset($allowed_actions);
+ $method = key($allowed_actions);
+
+ $folder = 'INBOX';
+ $reject = '';
+
+ $identity = $rcmail->user->get_identity();
+ if ($this->show_vacfrom)
+ $vacfrom = (in_array('variables', $ext)) ? 'auto' : $identity['email'];
+ else
+ $vacfrom = null;
+
+ $vacto = null;
+ $address = '';
+ $days = '';
+ $handle = '';
+ $subject = '';
+ $origsubject = '';
+ $msg = '';
+ $charset = RCUBE_CHARSET;
+ $flags = '';
+ $nfrom = '';
+ $nimpt = '';
+ $nmethod = '';
+ $noptions = '';
+ $nmsg = '';
+
+ if ($action['type'] == 'fileinto' || $action['type'] == 'fileinto_copy') {
+ $method = $action['type'];
+ $folder = $rcmail->config->get('sieverules_include_imap_root', true) ? $action['target'] : $rcmail->storage->mod_folder($action['target'], 'IN');
+
+ if ($rcmail->config->get('sieverules_folder_delimiter', false))
+ $folder = str_replace($rcmail->storage->get_hierarchy_delimiter(), $rcmail->config->get('sieverules_folder_delimiter'), $folder);
+ }
+ elseif ($action['type'] == 'reject' || $action['type'] == 'ereject') {
+ $method = $action['type'];
+ $reject = $action['target'];
+ }
+ elseif ($action['type'] == 'vacation') {
+ $method = 'vacation';
+ $days = $action['days'];
+ $vacfrom_default = $vacfrom;
+ $vacfrom = $action['from'];
+ $vacto = $action['addresses'];
+ $handle = $action['handle'];
+ $subject = $action['subject'];
+ $origsubject = $action['origsubject'];
+ $msg = $action['msg'];
+ $htmlmsg = $action['htmlmsg'] ? '1' : '';
+ $charset = $action['charset'];
+
+ if ($htmlmsg == '1' && $rcmail->config->get('htmleditor') == '0') {
+ $h2t = new rcube_html2text($msg, false, true, 0);
+ $msg = $h2t->get_text();
+ $htmlmsg = '';
+ }
+ elseif ($htmlmsg == '' && $rcmail->config->get('htmleditor') == '1') {
+ $msg = $msg;
+ $msg = nl2br($msg);
+ $htmlmsg = '1';
+ }
+
+ if (!$example)
+ $this->force_vacto = false;
+
+ // check advanced enabled
+ if ((!empty($vacfrom) && $vacfrom != $vacfrom_default) || !empty($vacto) || !empty($handle) || !empty($days) || $charset != RCUBE_CHARSET || $this->force_vacto) {
+ $vacadvstyle = '';
+ $vacadvstyle_from = ($this->show_vacfrom) ? '' : 'display: none;';
+ $vacadvstyle_handle = ($this->show_vachandle) ? '' : 'display: none;';
+ $vacshowadv = '1';
+ }
+ }
+ elseif ($action['type'] == 'redirect' || $action['type'] == 'redirect_copy') {
+ $method = $action['type'];
+ $address = $action['target'];
+ }
+ elseif ($action['type'] == 'imapflags' || $action['type'] == 'imap4flags') {
+ $method = $action['type'];
+ $flags = $action['target'];
+ }
+ elseif ($action['type'] == 'notify' || $action['type'] == 'enotify') {
+ $method = $action['type'];
+ $nfrom = $action['from'];
+ $nimpt = $action['importance'];
+ $nmethod = $action['method'];
+ $noptions = $action['options'];
+ $nmsg = $action['msg'];
+
+ // check advanced enabled
+ if (!empty($nfrom) || !empty($nimpt)) {
+ $noteadvstyle = '';
+ $noteshowadv = '1';
+ }
+ }
+ elseif ($action['type'] == 'editheaderadd' || $action['type'] == 'editheaderrem') {
+ $method = $action['type'];
+ $headername = $action['name'];
+ $headerval = $action['value'];
+ $headerindex = $action['index'];
+ $headeropp = $action['operator'];
+
+ if ($action['type'] == 'editheaderrem' && (!empty($headerindex) || !empty($headerval))) {
+ $eheadadvstyle = '';
+ $eheadshowadv = '1';
+ }
+ }
+ elseif ($action['type'] == 'discard' || $action['type'] == 'keep' || $action['type'] == 'stop') {
+ $method = $action['type'];
+ }
+
+ $select_action = new html_select(array('name' => "_act[]", 'onchange' => rcmail_output::JS_OBJECT_NAME . '.sieverules_action_select(this)'));
+ foreach ($allowed_actions as $value => $text)
+ $select_action->add(rcmail::Q($text), $value);
+
+ $actions_table->add('action', $select_action->show($method));
+
+ $vacs_table = new html_table(array('class' => 'records-table', 'cellspacing' => '0', 'cols' => 3, 'style' => ($method == 'vacation') ? '' : 'display: none;'));
+
+ $to_addresses = "";
+ $vacto_arr = explode(",", $vacto);
+ $user_identities = $rcmail->user->list_identities();
+ if (count($user_identities)) {
+ $field_id = 'rcmfd_sievevacfrom_'. $rowid;
+ $select_id = new html_select(array('id' => $field_id, 'name' => "_vacfrom[]", 'class' => 'short', 'onchange' => rcmail_output::JS_OBJECT_NAME . '.enable_sig(this);'));
+
+ if ($this->show_vacfrom && in_array('variables', $ext))
+ $select_id->add(rcmail::Q($this->gettext('autodetect')), "auto");
+ elseif (!$this->show_vacfrom)
+ $select_id->add(rcmail::Q($this->gettext('autodetect')), "");
+
+ foreach ($user_identities as $sql_arr) {
+ $from = $this->_rcmail_get_identity($sql_arr['identity_id']);
+
+ // find currently selected from address
+ if ($vacfrom != '' && $vacfrom == rcmail::Q($from['string']))
+ $vacfrom = $sql_arr['identity_id'];
+ elseif ($vacfrom != '' && $vacfrom == $from['mailto'])
+ $vacfrom = $sql_arr['identity_id'];
+
+ $select_id->add($from['disp_string'], $sql_arr['identity_id']);
+
+ $ffield_id = 'rcmfd_vac_' . $rowid . '_' . $sql_arr['identity_id'];
+
+ if ($this->force_vacto) {
+ $curaddress = $sql_arr['email'];
+ $vacto .= (!empty($vacto) ? ',' : '') . $sql_arr['email'];
+ }
+ else {
+ $curaddress = in_array($sql_arr['email'], $vacto_arr) ? $sql_arr['email'] : "";
+ }
+
+ $input_address = new html_checkbox(array('id' => $ffield_id, 'name' => '_vacto_check_' . $rowid . '[]', 'value' => $sql_arr['email'], 'onclick' => rcmail_output::JS_OBJECT_NAME . '.sieverules_toggle_vac_to(this, '. $rowid .')', 'class' => 'checkbox'));
+ $to_addresses .= $input_address->show($curaddress) . "&nbsp;" . html::label($ffield_id, rcmail::Q($sql_arr['email'])) . "<br />";
+ }
+ }
+
+ if ($rcmail->config->get('sieverules_limit_vacto', true) && strlen($to_addresses) > 0) {
+ $vacs_table->set_row_attribs(array('class' => $vacadvclass_from, 'style' => $vacadvstyle_from));
+ $vacs_table->add(null, html::label($field_id, rcmail::Q($this->gettext('from'))));
+ $vacs_table->add(null, $select_id->show($vacfrom));
+
+ $sig_button = $this->api->output->button(array('command' => 'plugin.sieverules.vacation_sig', 'prop' => $rowid, 'type' => 'link', 'class' => 'vacsig', 'classact' => 'vacsig_act', 'title' => 'insertsignature', 'content' => ' '));
+ $vacs_table->add(null, $sig_button);
+
+ $field_id = 'rcmfd_sievevacto_'. $rowid;
+ $input_vacto = new html_hiddenfield(array('id' => $field_id, 'name' => '_vacto[]', 'value' => $vacto));
+ $vacs_table->set_row_attribs(array('class' => 'advanced', 'style' => $vacadvstyle));
+ $vacs_table->add(array('style' => 'vertical-align: top;'), rcmail::Q($this->gettext('sieveto')));
+ $vacs_table->add(null, $to_addresses . $input_vacto->show());
+ $help_button = html::a(array('href' => "#", 'onclick' => 'return ' . rcmail_output::JS_OBJECT_NAME . '.sieverules_help(this, ' . $vacs_table->size() . ');', 'title' => $this->gettext('messagehelp')), $help_icon);
+ $vacs_table->add(array('style' => 'vertical-align: top;'), $help_button);
+
+ $vacs_table->set_row_attribs(array('class' => 'advhelp', 'style' => 'display: none;'));
+ $vacs_table->add(array('colspan' => 3, 'class' => 'vacdaysexp'), $this->gettext('vactoexp'));
+ }
+ else {
+ $field_id = 'rcmfd_sievevacfrom_'. $rowid;
+ $input_vacfrom = new html_inputfield(array('id' => $field_id, 'name' => '_vacfrom[]'));
+ $vacs_table->set_row_attribs(array('class' => $vacadvclass_from, 'style' => $vacadvstyle_from));
+ $vacs_table->add(null, html::label($field_id, rcmail::Q($this->gettext('from'))));
+ $vacs_table->add(null, $input_vacfrom->show($vacfrom));
+
+ $sig_button = $this->api->output->button(array('command' => 'plugin.sieverules.vacation_sig', 'prop' => $rowid, 'type' => 'link', 'class' => 'vacsig', 'classact' => 'vacsig_act', 'title' => 'insertsignature', 'content' => ' '));
+ $vacs_table->add(null, $sig_button);
+
+ $field_id = 'rcmfd_sievevacto_'. $rowid;
+ $input_vacto = new html_inputfield(array('id' => $field_id, 'name' => '_vacto[]', 'class' => 'short'));
+ $vacs_table->set_row_attribs(array('class' => 'advanced', 'style' => $vacadvstyle));
+ $vacs_table->add(null, html::label($field_id, rcmail::Q($this->gettext('sieveto'))));
+ $vacs_table->add(null, $input_vacto->show($vacto));
+
+ $help_button = html::a(array('href' => "#", 'onclick' => 'return ' . rcmail_output::JS_OBJECT_NAME . '.sieverules_help(this, ' . $vacs_table->size() . ');', 'title' => $this->gettext('messagehelp')), $help_icon);
+ $vacs_table->add(null, $help_button);
+ $vacs_table->set_row_attribs(array('class' => 'advhelp', 'style' => 'display: none;'));
+ $vacs_table->add(array('colspan' => 3, 'class' => 'vacdaysexp'), $this->gettext('vactoexp') . '<br /><br />' . $this->gettext('vactoexp_adv'));
+ }
+
+ $field_id = 'rcmfd_sievevacdays_'. $rowid;
+ $input_day = new html_inputfield(array('id' => $field_id, 'name' => '_day[]', 'class' => 'short'));
+ $vacs_table->set_row_attribs(array('class' => 'advanced', 'style' => $vacadvstyle));
+ $vacs_table->add(null, html::label($field_id, rcmail::Q($this->gettext('days'))));
+ $vacs_table->add(null, $input_day->show($days));
+ $help_button = html::a(array('href' => "#", 'onclick' => 'return ' . rcmail_output::JS_OBJECT_NAME . '.sieverules_help(this, ' . $vacs_table->size() . ');', 'title' => $this->gettext('messagehelp')), $help_icon);
+ $vacs_table->add(null, $help_button);
+
+ $vacs_table->set_row_attribs(array('style' => 'display: none;'));
+ $vacs_table->add(array('colspan' => 3, 'class' => 'vacdaysexp'), $this->gettext('vacdaysexp'));
+
+ $field_id = 'rcmfd_sievevachandle_'. $rowid;
+ $input_handle = new html_inputfield(array('id' => $field_id, 'name' => '_handle[]', 'class' => 'short'));
+ $vacs_table->set_row_attribs(array('class' => $vacadvclass_handle, 'style' => $vacadvstyle_handle));
+ $vacs_table->add(null, html::label($field_id, rcmail::Q($this->gettext('sievevachandle'))));
+ $vacs_table->add(null, $input_handle->show($handle));
+ $help_button = html::a(array('href' => "#", 'onclick' => 'return ' . rcmail_output::JS_OBJECT_NAME . '.sieverules_help(this, ' . $vacs_table->size() . ');', 'title' => $this->gettext('messagehelp')), $help_icon);
+ $vacs_table->add(null, $help_button);
+
+ $vacs_table->set_row_attribs(array('class' => 'advhelp', 'style' => 'display: none;'));
+ $vacs_table->add(array('colspan' => 3, 'class' => 'vacdaysexp'), $this->gettext('vachandleexp'));
+
+ $field_id = 'rcmfd_sievevacsubject_'. $rowid;
+ $input_subject = new html_inputfield(array('id' => $field_id, 'name' => '_subject[]'));
+ $vacs_table->add(null, html::label($field_id, rcmail::Q($this->gettext('subject'))));
+ $vacs_table->add(array('colspan' => 2), $input_subject->show($subject));
+
+ if (in_array('variables', $ext)) {
+ $field_id = 'rcmfd_sievevacsubject_orig_'. $rowid;
+ $input_origsubject = new html_checkbox(array('id' => $field_id, 'value' => '1', 'onclick' => rcmail_output::JS_OBJECT_NAME . '.sieverules_toggle_vac_osubj(this, '. $rowid .')', 'class' => 'checkbox'));
+ $input_vacosubj = new html_hiddenfield(array('id' => 'rcmfd_sievevactoh_'. $rowid, 'name' => '_orig_subject[]', 'value' => $origsubject));
+ $vacs_table->add(null, '&nbsp;');
+ $vacs_table->add(array('colspan' => 2), $input_origsubject->show($origsubject) . "&nbsp;" . html::label($field_id, rcmail::Q($this->gettext('sieveorigsubj'))) . $input_vacosubj->show());
+ }
+
+ $field_id = 'rcmfd_sievevacmag_'. $rowid;
+ $input_msg = new html_textarea(array('id' => $field_id, 'name' => '_msg[]', 'rows' => '8', 'cols' => '40', 'class' => $htmlmsg == 1 ? 'mce_editor' : '', 'is_escaped' => $htmlmsg == 1 ? true : null));
+ $input_html = new html_checkbox(array('id' => 'rcmfd_sievevachtmlcb_'. $rowid, 'onclick' => rcmail_output::JS_OBJECT_NAME . '.sieverules_toggle_vac_html(this, '. $rowid .', \'' . $field_id .'\');', 'value' => '1', 'class' => 'checkbox'));
+ $input_htmlhd = new html_hiddenfield(array('id' => 'rcmfd_sievevachtmlhd_'. $rowid, 'name' => '_htmlmsg[]', 'value' => $htmlmsg));
+ $vacs_table->add('msg', html::label($field_id, rcmail::Q($this->gettext('message'))));
+ $vacs_table->add(array('colspan' => 2), $input_msg->show($msg) . html::tag('div', in_array('htmleditor', $rcmail->config->get('dont_override')) ? array('style' => 'display: none;') : null, $input_html->show($htmlmsg) . "&nbsp;" . html::label('rcmfd_sievevachtml_' . $rowid, rcmail::Q($this->gettext('htmlmessage')))) . $input_htmlhd->show());
+
+ $field_id = 'rcmfd_sievecharset_'. $rowid;
+ $vacs_table->set_row_attribs(array('class' => 'advanced', 'style' => $vacadvstyle));
+ $vacs_table->add(null, html::label($field_id, rcmail::Q($this->gettext('charset'))));
+ $vacs_table->add(array('colspan' => 2), $rcmail->output->charset_selector(array('id' => $field_id, 'name' => '_vaccharset[]', 'selected' => $charset)));
+
+ $input_advopts = new html_checkbox(array('id' => 'vadvopts' . $rowid, 'name' => '_vadv_opts[]', 'onclick' => rcmail_output::JS_OBJECT_NAME . '.sieverules_show_adv(this);', 'value' => '1', 'class' => 'checkbox'));
+ $vacs_table->add(array('colspan' => '3', 'style' => 'text-align: right'), html::label('vadvopts' . $rowid, rcmail::Q($this->gettext('advancedoptions'))) . $input_advopts->show($vacshowadv));
+
+ $notify_table = new html_table(array('class' => 'records-table', 'cellspacing' => '0', 'cols' => 3, 'style' => ($method == 'notify' || $method == 'enotify') ? '' : 'display: none;'));
+
+ $user_identities = $rcmail->user->list_identities();
+ if (count($user_identities)) {
+ $field_id = 'rcmfd_sievenotifyfrom_'. $rowid;
+ $select_id = new html_select(array('id' => $field_id, 'name' => "_nfrom[]"));
+ $select_id->add(rcmail::Q($this->gettext('autodetect')), "");
+
+ foreach ($user_identities as $sql_arr) {
+ $from = $this->_rcmail_get_identity($sql_arr['identity_id']);
+
+ // find currently selected from address
+ if ($nfrom != '' && $nfrom == rcmail::Q($from['string']))
+ $nfrom = $sql_arr['identity_id'];
+ elseif ($nfrom != '' && $nfrom == $from['mailto'])
+ $nfrom = $sql_arr['identity_id'];
+
+ $select_id->add($from['disp_string'], $sql_arr['identity_id']);
+ }
+
+ $notify_table->set_row_attribs(array('class' => 'advanced', 'style' => $noteadvstyle));
+ $notify_table->add(null, html::label($field_id, rcmail::Q($this->gettext('sievefrom'))));
+ $notify_table->add(array('colspan' => 2), $select_id->show($nfrom));
+ }
+
+ $field_id = 'rcmfd_nmethod_'. $rowid;
+ $input_method = new html_inputfield(array('id' => $field_id, 'name' => '_nmethod[]'));
+ $notify_table->add(null, html::label($field_id, rcmail::Q($this->gettext('method'))));
+ $notify_table->add(array('colspan' => 2), $input_method->show($nmethod));
+
+ $field_id = 'rcmfd_noption_'. $rowid;
+ $input_method = new html_inputfield(array('id' => $field_id, 'name' => '_noption[]'));
+ $notify_table->add(null, html::label($field_id, rcmail::Q($this->gettext('options'))));
+ $notify_table->add(array('colspan' => 2), $input_method->show($noptions));
+
+ $notify_table->set_row_attribs(array('style' => 'display: none;'));
+ $notify_table->add(array('colspan' => 3, 'class' => 'vacdaysexp'), $this->gettext('nmethodexp'));
+
+ $field_id = 'rcmfd_nimpt_'. $rowid;
+ $input_importance = new html_radiobutton(array('id' => $field_id . '_none', 'name' => '_notify_radio_' . $rowid, 'value' => 'none', 'onclick' => rcmail_output::JS_OBJECT_NAME . '.sieverules_notify_impt(this, '. $rowid .')', 'class' => 'radio'));
+ $importance_show = $input_importance->show($nimpt) . "&nbsp;" . html::label($field_id . '_none', rcmail::Q($this->gettext('importancen')));
+ $input_importance = new html_radiobutton(array('id' => $field_id . '_1', 'name' => '_notify_radio_' . $rowid, 'value' => '1', 'onclick' => rcmail_output::JS_OBJECT_NAME . '.sieverules_notify_impt(this, '. $rowid .')', 'class' => 'radio'));
+ $importance_show .= '&nbsp;&nbsp;' . $input_importance->show($nimpt) . "&nbsp;" . html::label($field_id . '_1', rcmail::Q($this->gettext('importance1')));
+ $input_importance = new html_radiobutton(array('id' => $field_id . '_2', 'name' => '_notify_radio_' . $rowid, 'value' => '2', 'onclick' => rcmail_output::JS_OBJECT_NAME . '.sieverules_notify_impt(this, '. $rowid .')', 'class' => 'radio'));
+ $importance_show .= '&nbsp;&nbsp;' . $input_importance->show($nimpt) . "&nbsp;" . html::label($field_id . '_2', rcmail::Q($this->gettext('importance2')));
+ $input_importance = new html_radiobutton(array('id' => $field_id . '_3', 'name' => '_notify_radio_' . $rowid, 'value' => '3', 'onclick' => rcmail_output::JS_OBJECT_NAME . '.sieverules_notify_impt(this, '. $rowid .')', 'class' => 'radio'));
+ $importance_show .= '&nbsp;&nbsp;' . $input_importance->show($nimpt) . "&nbsp;" . html::label($field_id . '_3', rcmail::Q($this->gettext('importance3')));
+ $input_importance = new html_hiddenfield(array('id' => 'rcmfd_sievenimpt_'. $rowid, 'name' => '_nimpt[]'));
+
+ $notify_table->set_row_attribs(array('class' => 'advanced', 'style' => $noteadvstyle));
+ $notify_table->add(null, rcmail::Q($this->gettext('flag')));
+ $notify_table->add(array('colspan' => 2), $importance_show . $input_importance->show($nimpt));
+
+ $field_id = 'rcmfd_nmsg_'. $rowid;
+ $input_msg = new html_inputfield(array('id' => $field_id, 'name' => '_nmsg[]'));
+ $notify_table->add(null, html::label($field_id, rcmail::Q($this->gettext('message'))));
+ $notify_table->add(array('colspan' => 2), $input_msg->show($nmsg));
+
+ if (in_array('enotify', $ext)) {
+ $input_advopts = new html_checkbox(array('id' => 'nadvopts' . $rowid, 'name' => '_nadv_opts[]', 'onclick' => rcmail_output::JS_OBJECT_NAME . '.sieverules_show_adv(this);', 'value' => '1', 'class' => 'checkbox'));
+ $notify_table->add(array('colspan' => '3', 'style' => 'text-align: right'), html::label('nadvopts' . $rowid, rcmail::Q($this->gettext('advancedoptions'))) . $input_advopts->show($noteshowadv));
+ }
+
+ $headers_table = new html_table(array('class' => 'records-table', 'cellspacing' => '0', 'cols' => 2, 'style' => ($method == 'editheaderadd' || $method == 'editheaderrem') ? '' : 'display: none;'));
+
+ $field_id = 'rcmfd_eheadname_'. $rowid;
+ $input_header = new html_inputfield(array('id' => $field_id, 'name' => '_eheadname[]'));
+ $headers_table->add(null, html::label($field_id, rcmail::Q($this->gettext('headername'))));
+ $headers_table->add(null, $input_header->show($headername));
+
+ $field_id = 'rcmfd_eheadindex_'. $rowid;
+ $select_index = new html_select(array('id' => $field_id, 'name' => "_eheadindex[]"));
+ $select_index->add(rcmail::Q($this->gettext('headerdelall')), "");
+ $select_index->add(rcmail::Q("1"), "1");
+ $select_index->add(rcmail::Q("2"), "2");
+ $select_index->add(rcmail::Q("3"), "3");
+ $select_index->add(rcmail::Q("4"), "4");
+ $select_index->add(rcmail::Q("5"), "5");
+ $select_index->add(rcmail::Q($this->gettext('last')), "last");
+
+ $headers_table->set_row_attribs(array('class' => 'advanced', 'style' => $eheadadvstyle));
+ $headers_table->add(null, html::label($field_id, rcmail::Q($this->gettext('headerindex'))));
+ $headers_table->add(null, $select_index->show($headerindex));
+
+ $field_id = 'rcmfd_eheadopp_'. $rowid;
+ $select_match = new html_select(array('id' => $field_id, 'name' => "_eheadopp[]"));
+ $select_match->add(rcmail::Q($this->gettext('filteris')), "");
+ $select_match->add(rcmail::Q($this->gettext('filtercontains')), "contains");
+
+ $headers_table->set_row_attribs(array('class' => 'advanced', 'style' => $eheadadvstyle));
+ $headers_table->add(null, html::label($field_id, rcmail::Q($this->gettext('operator'))));
+ $headers_table->add(null, $select_match->show($headeropp));
+
+ $field_id = 'rcmfd_eheadval_'. $rowid;
+ $input_header = new html_inputfield(array('id' => $field_id, 'name' => '_eheadval[]'));
+
+ if ($method == 'editheaderrem')
+ $headers_table->set_row_attribs(array('class' => 'advanced', 'style' => $eheadadvstyle));
+
+ $headers_table->add(null, html::label($field_id, rcmail::Q($this->gettext('headervalue'))));
+ $headers_table->add(null, $input_header->show($headerval));
+
+ if ($method == 'editheaderrem')
+ $headers_table->set_row_attribs(array('style' => 'display: none;'));
+
+ $field_id = 'rcmfd_eheadaddlast_'. $rowid;
+ $input_index = new html_checkbox(array('id' => $field_id, 'value' => 'last', 'onclick' => rcmail_output::JS_OBJECT_NAME . '.sieverules_toggle_eheadlast(this);', 'name' => '_eheadaddlast[]', 'class' => 'checkbox'));
+ $headers_table->add(null, '&nbsp;');
+ $headers_table->add(null, $input_index->show($headerindex) . "&nbsp;" . html::label($field_id, rcmail::Q($this->gettext('headerappend'))));
+
+ if ($method == 'editheaderadd')
+ $headers_table->set_row_attribs(array('style' => 'display: none;'));
+
+ $input_advopts = new html_checkbox(array('id' => 'hadvopts' . $rowid, 'name' => '_hadv_opts[]', 'onclick' => rcmail_output::JS_OBJECT_NAME . '.sieverules_show_adv(this);', 'value' => '1', 'class' => 'checkbox'));
+ $headers_table->add(array('colspan' => '3', 'style' => 'text-align: right'), html::label('nadvopts' . $rowid, rcmail::Q($this->gettext('advancedoptions'))) . $input_advopts->show($eheadshowadv));
+
+ // get mailbox list
+ $mbox_name = $rcmail->storage->get_folder();
+
+ // build the folders tree
+ if (empty($a_mailboxes)) {
+ // get mailbox list
+ if ($rcmail->config->get('sieverules_fileinto_options', 0) > 0)
+ $a_folders = $rcmail->storage->list_folders();
+ else
+ $a_folders = $rcmail->storage->list_folders_subscribed();
+
+ $delimiter = $rcmail->storage->get_hierarchy_delimiter();
+ $a_mailboxes = array();
+
+ foreach ($a_folders as $ifolder) {
+ if ($rcmail->config->get('sieverules_folder_encoding'))
+ $ifolder = $this->_mbox_encode($ifolder, $rcmail->config->get('sieverules_folder_encoding'));
+
+ if ($rcmail->config->get('sieverules_folder_delimiter', false))
+ $rcmail->build_folder_tree($a_mailboxes, str_replace($delimiter, $rcmail->config->get('sieverules_folder_delimiter'), $ifolder), $rcmail->config->get('sieverules_folder_delimiter'));
+ else
+ $rcmail->build_folder_tree($a_mailboxes, $ifolder, $delimiter);
+ }
+
+ if ($rcmail->config->get('sieverules_fileinto_options', 0) == 2 && in_array('mailbox', $ext))
+ array_push($a_mailboxes, array('id' => '@@newfolder', 'name' => $this->gettext('createfolder'), 'virtual' => '', 'folders' => array()));
+ }
+
+ $input_folderlist = new html_select(array('name' => '_folder[]', 'onchange' => rcmail_output::JS_OBJECT_NAME . '.sieverules_select_folder(this);', 'style' => ($method == 'fileinto' || $method == 'fileinto_copy') ? '' : 'display: none;', 'is_escaped' => true));
+ $rcmail->render_folder_tree_select($a_mailboxes, $mbox_name, 100, $input_folderlist, false);
+
+ $show_customfolder = 'display: none;';
+ if ($rcmail->config->get('sieverules_fileinto_options', 0) == 2 && !$rcmail->storage->folder_exists($folder)) {
+ $customfolder = $rcmail->storage->mod_folder($folder);
+ $folder = '@@newfolder';
+ $show_customfolder = '';
+ }
+
+ $input_customfolder = new html_inputfield(array('name' => '_customfolder[]'));
+ $otherfolders = html::span(array('id' => 'customfolder_rowid', 'style' => $show_customfolder), '<br />' . $input_customfolder->show($customfolder));
+
+ $input_address = new html_inputfield(array('name' => '_redirect[]', 'style' => ($method == 'redirect' || $method == 'redirect_copy') ? '' : 'display: none;'));
+ $input_reject = new html_textarea(array('name' => '_reject[]', 'rows' => '5', 'cols' => '40', 'style' => ($method == 'reject' || $method == 'ereject') ? '' : 'display: none;'));
+ $input_imapflags = new html_select(array('name' => '_imapflags[]', 'style' => ($method == 'imapflags' || $method == 'imap4flags') ? '' : 'display: none;'));
+ foreach($this->flags as $name => $val)
+ $input_imapflags->add(rcmail::Q($this->gettext($name)), rcmail::Q($val));
+
+ $actions_table->add('folder', $input_folderlist->show($folder) . $otherfolders . $input_address->show($address) . $vacs_table->show() . $notify_table->show() . $input_imapflags->show($flags) . $input_reject->show($reject) . $headers_table->show());
+
+ $add_button = $this->api->output->button(array('command' => 'plugin.sieverules.add_action', 'type' => 'link', 'class' => 'add', 'title' => 'sieverules.addsieveact', 'content' => ' '));
+ $delete_button = $this->api->output->button(array('command' => 'plugin.sieverules.del_action', 'type' => 'link', 'class' => 'delete', 'classact' => 'delete_act', 'title' => 'sieverules.deletesieveact', 'content' => ' '));
+
+ if ($rcmail->config->get('sieverules_multiple_actions'))
+ $actions_table->add('control', $delete_button . $add_button);
+ else
+ $actions_table->add('control', "&nbsp;");
+
+ return $actions_table;
+ }
+
+ private function _in_headerarray($needle, $haystack)
+ {
+ foreach ($haystack as $data) {
+ $args = explode("::", $data);
+ if ($args[1] == $needle)
+ return $args[0];
+ }
+
+ return false;
+ }
+
+ private function _strip_val($str, $allow_html = false, $trim = true)
+ {
+ $str = !$allow_html ? htmlspecialchars_decode($str) : $str;
+ $str = $trim ? trim($str) : $str;
+
+ return $str;
+ }
+
+ private function _mbox_encode($text, $encoding)
+ {
+ return rcube_charset::convert($text, 'UTF7-IMAP', $encoding);
+ }
+
+ // get identity record
+ private function _rcmail_get_identity($id)
+ {
+ $rcmail = rcube::get_instance();
+
+ if ($sql_arr = $rcmail->user->get_identity($id)) {
+ $out = $sql_arr;
+ $out['mailto'] = $sql_arr['email'];
+ $out['string'] = format_email_recipient($sql_arr['email'], rcube_charset::convert($sql_arr['name'], RCUBE_CHARSET, $this->api->output->get_charset()));
+
+ if ($rcmail->config->get('sieverules_from_format', 0) == 1) {
+ $out['disp_string'] = $out['string'];
+ $out['val_string'] = $out['string'];
+ }
+ else {
+ $out['disp_string'] = $out['mailto'];
+ $out['val_string'] = $out['mailto'];
+ }
+
+ return $out;
+ }
+
+ return FALSE;
+ }
+}
+
+?> \ No newline at end of file
diff --git a/plugins/sieverules/skins/classic/cross.gif b/plugins/sieverules/skins/classic/cross.gif
new file mode 100644
index 000000000..327052a23
--- /dev/null
+++ b/plugins/sieverules/skins/classic/cross.gif
Binary files differ
diff --git a/plugins/sieverules/skins/classic/help.gif b/plugins/sieverules/skins/classic/help.gif
new file mode 100644
index 000000000..ea7bbb363
--- /dev/null
+++ b/plugins/sieverules/skins/classic/help.gif
Binary files differ
diff --git a/plugins/sieverules/skins/classic/icons.gif b/plugins/sieverules/skins/classic/icons.gif
new file mode 100644
index 000000000..ba772f2ad
--- /dev/null
+++ b/plugins/sieverules/skins/classic/icons.gif
Binary files differ
diff --git a/plugins/sieverules/skins/classic/icons.png b/plugins/sieverules/skins/classic/icons.png
new file mode 100644
index 000000000..31a26491d
--- /dev/null
+++ b/plugins/sieverules/skins/classic/icons.png
Binary files differ
diff --git a/plugins/sieverules/skins/classic/ie6hacks.css b/plugins/sieverules/skins/classic/ie6hacks.css
new file mode 100644
index 000000000..a6b414034
--- /dev/null
+++ b/plugins/sieverules/skins/classic/ie6hacks.css
@@ -0,0 +1,10 @@
+/**
+ * SieveRules plugin styles (IE6 hacks)
+ */
+
+#sieverules-table tbody td.control a,
+#rules-table tbody td.control a,
+#actions-table tbody td.control a
+{
+ background-image: url(icons.gif);
+} \ No newline at end of file
diff --git a/plugins/sieverules/skins/classic/iehacks.css b/plugins/sieverules/skins/classic/iehacks.css
new file mode 100644
index 000000000..582f452a3
--- /dev/null
+++ b/plugins/sieverules/skins/classic/iehacks.css
@@ -0,0 +1,53 @@
+/**
+ * SieveRules plugin styles (IE hacks)
+ */
+
+#sieverules-list
+{
+ height: expression(parseInt(this.parentNode.offsetHeight)+'px');
+}
+
+.sieverules-boxcontent
+{
+ height: expression(parseInt(this.parentNode.offsetHeight)-25+'px');
+}
+
+#sieverules-list-filters
+{
+ height: expression(parseInt(this.parentNode.offsetHeight)+'px');
+ width: expression(parseInt(this.parentNode.offsetWidth)+'px');
+}
+
+#sieverules-list-examples
+{
+ width: expression(parseInt(this.parentNode.offsetWidth)+'px');
+}
+
+#sieverules-details
+{
+ height: expression(parseInt(this.parentNode.offsetHeight)+'px');
+ width: expression((parseInt(this.parentNode.offsetWidth)-250)+'px');
+}
+
+#sieverules-advanced
+{
+ height: expression((parseInt(document.documentElement.clientHeight)-130)+'px');
+ width: expression((parseInt(document.documentElement.clientWidth)-40)+'px');
+}
+
+table.records-table td.vacdaysexp
+{
+ word-wrap: break-word;
+}
+
+#sieverules-advancedbox
+{
+ height: expression((parseInt(document.documentElement.clientHeight)-177)+'px');
+ width: expression((parseInt(document.documentElement.clientWidth)-48)+'px');
+}
+
+#sieverules-advanced textarea
+{
+ height: expression((parseInt(document.documentElement.clientHeight)-177)+'px');
+ width: expression((parseInt(document.documentElement.clientWidth)-48)+'px');
+} \ No newline at end of file
diff --git a/plugins/sieverules/skins/classic/safari.css b/plugins/sieverules/skins/classic/safari.css
new file mode 100644
index 000000000..0add9e3d2
--- /dev/null
+++ b/plugins/sieverules/skins/classic/safari.css
@@ -0,0 +1,8 @@
+/**
+ * SieveRules plugin styles (safari hacks)
+ */
+
+table.records-table td.vacdaysexp
+{
+ word-wrap: break-word;
+} \ No newline at end of file
diff --git a/plugins/sieverules/skins/classic/sieverules.css b/plugins/sieverules/skins/classic/sieverules.css
new file mode 100644
index 000000000..54a1b0cfa
--- /dev/null
+++ b/plugins/sieverules/skins/classic/sieverules.css
@@ -0,0 +1,406 @@
+/**
+ * SieveRules plugin styles
+ */
+
+#sieverules-list
+{
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ width: 240px;
+}
+
+.sieverules-boxcontent
+{
+ position: absolute;
+ top: 0;
+ bottom: 23px;
+ width: 100%;
+}
+
+#sieverules-list-filters
+{
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ width: 100%;
+ border: 1px solid #999999;
+ overflow: auto;
+}
+
+#sieverules-list-filters thead td
+{
+ height: 20px;
+}
+
+#sieverules-list-filters thead td span
+{
+ position: absolute;
+ top: 2px;
+ left: 4px;
+ right: 25px;
+ height: 20px;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+
+#sieverules-list-filters thead td img
+{
+ position: absolute;
+ top: 2px;
+ right: 2px;
+}
+
+#sieverules-list-examples
+{
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ width: 100%;
+ border: 1px solid #999999;
+ overflow: auto;
+}
+
+#sieverules-list div.boxfooter
+{
+ border: 1px solid #999999;
+ border-top: 0;
+ width: 100%;
+}
+
+#sieverules-details
+{
+ position: absolute;
+ top: 0;
+ left: 250px;
+ right: 0;
+ bottom: 0;
+ border: 1px solid #999999;
+}
+
+#sieverules-advanced
+{
+ position: absolute;
+ top: 0;
+ left: 0;
+ bottom: 25px;
+ right: 0;
+ overflow: hidden;
+ border: 1px solid #999999;
+}
+
+span.disableLink
+{
+ float: right;
+ width: 200px;
+ text-align: right;
+}
+
+#sieverules-table,
+#sieverules-examples
+{
+ width: 100%;
+}
+
+#sieverules-table tbody td
+{
+ cursor: default;
+}
+
+#sieverules-table tbody td.control,
+#rules-table tbody td.control,
+#actions-table tbody td.control
+{
+ text-align: right;
+}
+
+#sieverules-table tbody td.control a,
+#rules-table tbody td.control a,
+#actions-table tbody td.control a
+{
+ display: block;
+ float: right;
+ width: 16px;
+ height: 16px;
+ background-image: url(icons.png);
+}
+
+#sieverules-table tbody td.control a.up_arrow
+{
+ background-position: 0 0;
+}
+
+#sieverules-table tbody td.control a.down_arrow
+{
+ background-position: 0 -18px;
+}
+
+#rules-table tbody td.control,
+#actions-table tbody td.control
+{
+ vertical-align: top;
+}
+
+#rules-table tbody td.control a.add,
+#actions-table tbody td.control a.add
+{
+ margin-left: 5px;
+ background-position: 0 -72px;
+}
+
+#rules-table tbody td.control a.delete,
+#actions-table tbody td.control a.delete
+{
+ background-position: 0 -54px;
+}
+
+#rules-table tbody td.control a.delete_act,
+#actions-table tbody td.control a.delete_act
+{
+ background-position: 0 -36px;
+}
+
+#actions-table tbody a.vacsig
+{
+ display: block;
+ width: 16px;
+ height: 16px;
+ background-image: url(icons.png);
+ background-position: 0 -108px;
+}
+
+#actions-table tbody a.vacsig_act
+{
+ display: block;
+ width: 16px;
+ height: 16px;
+ background-image: url(icons.png);
+ background-position: 0 -90px;
+}
+
+#rules-table,
+#actions-table,
+#rules-table td table.records-table
+{
+ width: 100%;
+}
+
+#rules-table td.selheader,
+#rules-table td.op
+{
+ width: 130px;
+}
+
+#rules-table td.header
+{
+ width: 135px;
+}
+
+#rules-table td.target
+{
+ width: 160px;
+}
+
+#rules-table input
+{
+ width: 150px;
+}
+
+#rules-table input.short
+{
+ width: 100px;
+}
+
+#rules-table select
+{
+ width: 123px;
+}
+
+#rules-table select.short
+{
+ width: 45px;
+}
+
+#rules-table select.long
+{
+ width: 157px;
+}
+
+#rules-table td table.records-table select
+{
+ width: 432px;
+}
+
+#rules-table td table.records-table input
+{
+ width: 426px;
+}
+
+#rules-table td table.records-table input.short
+{
+ width: 406px;
+}
+
+#rules-table td table.records-table input.radio
+{
+ width: auto;
+}
+
+#actions-table td.action
+{
+ width: 165px;
+ vertical-align: top;
+}
+
+#actions-table td.folder
+{
+ width: 420px;
+ vertical-align: top;
+}
+
+#actions-table td.action select
+{
+ width: 160px;
+}
+
+#actions-table td.folder input,
+#actions-table td.folder textarea
+{
+ width: 400px;
+}
+
+#actions-table td.folder select
+{
+ width: 408px;
+}
+
+#actions-table td.folder table.records-table select
+{
+ width: 337px;
+}
+
+#actions-table td.folder table.records-table input,
+#actions-table td.folder table.records-table textarea
+{
+ width: 330px;
+}
+
+#actions-table td.folder table.records-table input.short,
+#actions-table td.folder table.records-table select.short
+{
+ width: 310px;
+}
+
+#actions-table td.folder table.records-table input.checkbox,
+#actions-table td.folder table.records-table input.radio
+{
+ width: auto;
+}
+
+table.records-table td.msg
+{
+ vertical-align: top;
+}
+
+table.records-table td.vacdaysexp
+{
+ width: 398px;
+ white-space: -moz-pre-wrap !important;
+ white-space: pre-wrap !important;
+ white-space: pre;
+}
+
+#listbuttons
+{
+ position: absolute;
+ bottom: 18px;
+ left: 20px;
+}
+
+#advancedmode
+{
+ white-space: nowrap;
+ text-align: right;
+ position: absolute;
+ bottom: 30px;
+ right: 20px;
+ width: 460px;
+}
+
+#sieverules-advancedbox
+{
+ position: absolute;
+ top: 20px;
+ left: 0;
+ bottom: 26px;
+ right: 4px;
+}
+
+#sieverules-advanced textarea
+{
+ position: absolute;
+ top: 0;
+ left: 0;
+ border: 0;
+ width: 100%;
+ height: 100%;
+}
+
+.records-table tbody tr.droptarget td
+{
+ border-top: 2px solid #000000;
+}
+
+.records-table tbody tr.droptargetend td
+{
+ border-bottom: 2px solid #000000;
+}
+
+#sieverulesrsdialog h3
+{
+ color: #333;
+ font-size: normal;
+ margin-top: 0.5em;
+ margin-bottom: 1em;
+}
+
+#sieverulesrsdialog table td.title
+{
+ color: #666;
+ text-align: right;
+ padding-right: 1em;
+ white-space: nowrap;
+}
+
+#sieverulesrsdialog table td input
+{
+ width: 20em;
+}
+
+#sieverulesrsdialog .formbuttons
+{
+ margin-top: 1.5em;
+ text-align: center;
+}
+
+input.inputmask
+{
+ color: #999999;
+}
+
+#sieverulesactionsmenu a.selected
+{
+ font-weight: bold;
+}
+
+#sieverules-advbuttons
+{
+ position: absolute;
+ left: 0;
+ bottom: 0;
+} \ No newline at end of file
diff --git a/plugins/sieverules/skins/classic/tabstyles.css b/plugins/sieverules/skins/classic/tabstyles.css
new file mode 100644
index 000000000..b1b1c3f95
--- /dev/null
+++ b/plugins/sieverules/skins/classic/tabstyles.css
@@ -0,0 +1,3 @@
+/**
+ * SieveRules plugin styles (tab styles)
+ */
diff --git a/plugins/sieverules/skins/classic/templates/advancededitor.html b/plugins/sieverules/skins/classic/templates/advancededitor.html
new file mode 100644
index 000000000..e42e40195
--- /dev/null
+++ b/plugins/sieverules/skins/classic/templates/advancededitor.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title><roundcube:object name="pagetitle" /></title>
+<roundcube:include file="/includes/links.html" />
+<link rel="stylesheet" type="text/css" href="/this/sieverules.css" />
+<roundcube:if condition="browser:ie" />
+<link rel="stylesheet" type="text/css" href="/this/iehacks.css" />
+<roundcube:endif />
+<roundcube:if condition="browser:safari" />
+<link rel="stylesheet" type="text/css" href="/this/safari.css" />
+<roundcube:endif />
+<script type="text/javascript" src="/functions.js"></script>
+</head>
+<body onload="rcube_init_mail_ui(); rcmail_ui.popups.sieverulesmenu = {id: 'sieverulesactionsmenu', obj:$('#sieverulesactionsmenu'), above:1};">
+
+<roundcube:include file="/includes/taskbar.html" />
+<roundcube:include file="/includes/header.html" />
+<roundcube:include file="/includes/settingstabs.html" />
+
+<div id="mainscreen">
+
+<div id="sieverules-advanced">
+<div id="prefs-title" class="boxtitle"><roundcube:object name="steptitle" /></div>
+
+<div id="sieverules-advancedbox">
+<roundcube:object name="advancededitor" />
+</div>
+
+<div class="boxfooter">
+<roundcube:button name="sieverulesactions" id="sieverulesmenulink" type="link" title="sieverules.moreactions" class="button groupactions" onclick="rcmail_ui.show_popupmenu('sieverulesmenu'); return false" content=" " />
+</div>
+</div>
+
+<div id="sieverules-advbuttons">
+<roundcube:button command="plugin.sieverules.save" type="input" label="save" class="button mainaction" />
+</div>
+
+</div>
+
+<div id="sieverulesactionsmenu" class="popupmenu">
+ <ul>
+ <roundcube:if condition="config:sieverules_multiplerules == true" />
+ <li class="separator_below"><roundcube:button command="plugin.sieverules.ruleset_dialog" type="link" label="sieverules.newruleset" classAct="active" /></li>
+ <roundcube:object name="rulelist" type="link" />
+ <li class="separator_above"><roundcube:button command="plugin.sieverules.ruleset_dialog" prop="rename_ruleset" type="link" label="sieverules.renameruleset" classAct="active" /></li>
+ <li><roundcube:button command="plugin.sieverules.del_ruleset" type="link" label="sieverules.delruleset" classAct="active" /></li>
+ <li><roundcube:button command="plugin.sieverules.activate_ruleset" type="link" label="sieverules.activateruleset" classAct="active" /></li>
+ <roundcube:endif />
+ <li<roundcube:exp expression="config:sieverules_multiplerules == true ? ' class=separator_above' : ''" />><roundcube:button command="plugin.sieverules.sieverules_adveditor" prop="0" type="link" label="sieverules.stdeditor" classAct="active" /></li>
+ </ul>
+</div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/plugins/sieverules/skins/classic/templates/editsieverule.html b/plugins/sieverules/skins/classic/templates/editsieverule.html
new file mode 100644
index 000000000..58b4c966a
--- /dev/null
+++ b/plugins/sieverules/skins/classic/templates/editsieverule.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title><roundcube:object name="pagetitle" /></title>
+<roundcube:include file="/includes/links.html" />
+<link rel="stylesheet" type="text/css" href="/this/sieverules.css" />
+<roundcube:if condition="browser:ie" />
+<link rel="stylesheet" type="text/css" href="/this/iehacks.css" />
+<roundcube:endif />
+<roundcube:if condition="browser:safari" />
+<link rel="stylesheet" type="text/css" href="/this/safari.css" />
+<roundcube:endif />
+<!--[if lte IE 6]><link rel="stylesheet" type="text/css" href="/this//ie6hacks.css" /><![endif]-->
+<script type="text/javascript" src="/functions.js"></script>
+</head>
+<body class="iframe">
+<div id="prefs-title" class="boxtitle"><roundcube:object name="steptitle" /></div>
+
+<div class="boxcontent">
+<roundcube:object name="sieveruleform" helpIcon="/this/help.gif" />
+
+<p><br />
+<roundcube:button command="plugin.sieverules.copy_rule" type="input" class="button" label="sieverules.copy" condition="env:action=='plugin.sieverules.edit' && config:sieverules_multiplerules == true" style="margin-right:0.5em" />
+<roundcube:button command="plugin.sieverules.save" type="input" class="button mainaction" label="save" />
+</p>
+</div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/plugins/sieverules/skins/classic/templates/setupsieverules.html b/plugins/sieverules/skins/classic/templates/setupsieverules.html
new file mode 100644
index 000000000..a9e01f565
--- /dev/null
+++ b/plugins/sieverules/skins/classic/templates/setupsieverules.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title><roundcube:object name="pagetitle" /></title>
+<roundcube:include file="/includes/links.html" />
+<link rel="stylesheet" type="text/css" href="/this/sieverules.css" />
+<roundcube:if condition="browser:ie" />
+<link rel="stylesheet" type="text/css" href="/this/iehacks.css" />
+<roundcube:endif />
+<roundcube:if condition="browser:safari" />
+<link rel="stylesheet" type="text/css" href="/this/safari.css" />
+<roundcube:endif />
+<script type="text/javascript" src="/functions.js"></script>
+</head>
+<body onload="parent.rcmail.sieverules_disable_ruleset_options();" class="iframe">
+<roundcube:object name="sieverulessetup" />
+</body>
+</html> \ No newline at end of file
diff --git a/plugins/sieverules/skins/classic/templates/sieverules.html b/plugins/sieverules/skins/classic/templates/sieverules.html
new file mode 100644
index 000000000..66b2c0022
--- /dev/null
+++ b/plugins/sieverules/skins/classic/templates/sieverules.html
@@ -0,0 +1,93 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title><roundcube:object name="pagetitle" /></title>
+<roundcube:include file="/includes/links.html" />
+<link rel="stylesheet" type="text/css" href="/this/sieverules.css" />
+<roundcube:if condition="browser:ie" />
+<link rel="stylesheet" type="text/css" href="/this/iehacks.css" />
+<roundcube:endif />
+<roundcube:if condition="browser:safari" />
+<link rel="stylesheet" type="text/css" href="/this/safari.css" />
+<roundcube:endif />
+<!--[if lte IE 6]><link rel="stylesheet" type="text/css" href="/this//ie6hacks.css" /><![endif]-->
+<script type="text/javascript" src="/functions.js"></script>
+<script type="text/javascript" src="/splitter.js"></script>
+
+<style type="text/css">
+
+#sieverules-list { width: <roundcube:exp expression="!empty(cookie:sieverulesviewsplitter) ? cookie:sieverulesviewsplitter-5 : 240" />px; }
+<roundcube:if condition="env:examples" />
+#sieverules-list-filters {
+ bottom: <roundcube:exp expression="!empty(cookie:sievefiltersviewsplitter) ? cookie:sievefiltersviewsplitter+5 : 0" />px;
+ <roundcube:exp expression="browser:ie ? ('height:expression((parseInt(this.parentNode.offsetHeight)-'.(!empty(cookie:sievefiltersviewsplitter) ? cookie:sievefiltersviewsplitter+5 : 0).')+\\'px\\');') : ''" />
+}
+<roundcube:else />
+#sieverules-list-filters {
+ bottom: 0;
+ <roundcube:exp expression="browser:ie ? 'height:expression(parseInt(this.parentNode.offsetHeight)+\\'px\\');' : ''" />
+}
+<roundcube:endif />
+#sieverules-details {
+ left: <roundcube:exp expression="!empty(cookie:sieverulesviewsplitter) ? cookie:sieverulesviewsplitter+5 : 250" />px;
+ <roundcube:exp expression="browser:ie ? ('width:expression((parseInt(mainscreen.offsetWidth)-'.(!empty(cookie:sieverulesviewsplitter) ? cookie:sieverulesviewsplitter+5 : 250).')+\\'px\\');') : ''" />
+}
+</style>
+
+</head>
+<body onload="rcube_init_mail_ui(); rcmail_ui.popups.sieverulesmenu = {id: 'sieverulesactionsmenu', obj:$('#sieverulesactionsmenu'), above:1};">
+
+<roundcube:include file="/includes/taskbar.html" />
+<roundcube:include file="/includes/header.html" />
+<roundcube:include file="/includes/settingstabs.html" />
+
+<div id="mainscreen">
+
+<div id="sieverules-list">
+<div class="sieverules-boxcontent">
+<roundcube:object name="sieveruleslist" activeicon="/this/tick.gif" inactiveicon="/this/cross.gif" />
+<roundcube:object name="sieverulesexamplelist" />
+</div>
+<div class="boxfooter">
+<roundcube:button command="plugin.sieverules.add" type="link" title="sieverules.newfilter" class="buttonPas addgroup" classAct="button addgroup" content=" " />
+<roundcube:button command="plugin.sieverules.delete" type="link" title="delete" class="buttonPas delgroup" classAct="button delgroup" content=" " />
+<roundcube:if condition="config:sieverules_multiplerules == true || config:sieverules_adveditor == 1 || config:sieverules_adveditor == 2" />
+<roundcube:button name="sieverulesactions" id="sieverulesmenulink" type="link" title="sieverules.moreactions" class="button groupactions" onclick="rcmail_ui.show_popupmenu('sieverulesmenu'); return false" content=" " />
+<roundcube:endif />
+</div>
+</div>
+
+<script type="text/javascript">
+ var rulesviewsplit = new rcube_splitter({id:'sieverulesviewsplitter', p1: 'sieverules-list', p2: 'sieverules-details', orientation: 'v', relative: true, start: 245});
+ rcmail.add_onload('rulesviewsplit.init()');
+
+ if ($('#sieverules-list-examples').length > 0) {
+ var filtersHeight = parseInt($('#sieverules-list').height() - 210);
+ var filtersviewsplit = new rcube_splitter({id:'sievefiltersviewsplitter', p1: 'sieverules-list-filters', p2: 'sieverules-list-examples', orientation: 'h', relative: true, start: filtersHeight});
+ rcmail.add_onload('filtersviewsplit.init()');
+ }
+</script>
+
+<div id="sieverules-details">
+<roundcube:object name="sieverulesframe" id="prefs-frame" width="100%" height="100%" frameborder="0" src="/watermark.html" />
+</div>
+
+</div>
+
+<div id="sieverulesactionsmenu" class="popupmenu">
+ <ul>
+ <roundcube:if condition="config:sieverules_multiplerules == true" />
+ <li class="separator_below"><roundcube:button command="plugin.sieverules.ruleset_dialog" type="link" label="sieverules.newruleset" classAct="active" /></li>
+ <roundcube:object name="rulelist" type="link" />
+ <li class="separator_above"><roundcube:button command="plugin.sieverules.ruleset_dialog" prop="rename_ruleset" type="link" label="sieverules.renameruleset" classAct="active" /></li>
+ <li><roundcube:button command="plugin.sieverules.del_ruleset" type="link" label="sieverules.delruleset" classAct="active" /></li>
+ <li><roundcube:button command="plugin.sieverules.activate_ruleset" type="link" label="sieverules.activateruleset" classAct="active" /></li>
+ <roundcube:endif />
+ <roundcube:if condition="config:sieverules_adveditor == 1 || config:sieverules_adveditor == 2" />
+ <li<roundcube:exp expression="config:sieverules_multiplerules == true ? ' class=separator_above' : ''" />><roundcube:button command="plugin.sieverules.sieverules_adveditor" prop="1" type="link" label="sieverules.adveditor" classAct="active" /></li>
+ <roundcube:endif />
+ </ul>
+</div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/plugins/sieverules/skins/classic/tick.gif b/plugins/sieverules/skins/classic/tick.gif
new file mode 100644
index 000000000..08c3a3a13
--- /dev/null
+++ b/plugins/sieverules/skins/classic/tick.gif
Binary files differ
diff --git a/plugins/sieverules/skins/larry/cross.png b/plugins/sieverules/skins/larry/cross.png
new file mode 100644
index 000000000..8d8a13f47
--- /dev/null
+++ b/plugins/sieverules/skins/larry/cross.png
Binary files differ
diff --git a/plugins/sieverules/skins/larry/help.png b/plugins/sieverules/skins/larry/help.png
new file mode 100644
index 000000000..9f7a6ae44
--- /dev/null
+++ b/plugins/sieverules/skins/larry/help.png
Binary files differ
diff --git a/plugins/sieverules/skins/larry/icons.png b/plugins/sieverules/skins/larry/icons.png
new file mode 100644
index 000000000..db84da896
--- /dev/null
+++ b/plugins/sieverules/skins/larry/icons.png
Binary files differ
diff --git a/plugins/sieverules/skins/larry/iehacks.css b/plugins/sieverules/skins/larry/iehacks.css
new file mode 100644
index 000000000..e370e9300
--- /dev/null
+++ b/plugins/sieverules/skins/larry/iehacks.css
@@ -0,0 +1,53 @@
+/**
+ * SieveRules plugin styles (IE hacks)
+ */
+
+#sieverules-list
+{
+ height: expression(parseInt(this.parentNode.offsetHeight)+'px');
+}
+
+.sieverules-boxcontent
+{
+ height: expression(parseInt(this.parentNode.offsetHeight)-25+'px');
+}
+
+#sieverules-list-filters
+{
+ height: expression(parseInt(this.parentNode.offsetHeight)+'px');
+ width: expression(parseInt(this.parentNode.offsetWidth)+'px');
+}
+
+#sieverules-list-examples
+{
+ width: expression(parseInt(this.parentNode.offsetWidth)+'px');
+}
+
+#sieverules-details
+{
+ height: expression(parseInt(this.parentNode.offsetHeight)+'px');
+ width: expression((parseInt(this.parentNode.offsetWidth)-270)+'px');
+}
+
+#sieverules-advanced
+{
+ height: expression((parseInt(document.documentElement.clientHeight)-130)+'px');
+ width: expression((parseInt(document.documentElement.clientWidth)-40)+'px');
+}
+
+table.records-table td.vacdaysexp
+{
+ word-wrap: break-word;
+}
+
+#sieverules-advancedbox
+{
+ height: expression((parseInt(document.documentElement.clientHeight)-177)+'px');
+ width: expression((parseInt(document.documentElement.clientWidth)-48)+'px');
+}
+
+#sieverules-advanced textarea
+{
+ height: expression((parseInt(document.documentElement.clientHeight)-177)+'px');
+ width: expression((parseInt(document.documentElement.clientWidth)-48)+'px');
+} \ No newline at end of file
diff --git a/plugins/sieverules/skins/larry/listicons.png b/plugins/sieverules/skins/larry/listicons.png
new file mode 100644
index 000000000..f6889c4a0
--- /dev/null
+++ b/plugins/sieverules/skins/larry/listicons.png
Binary files differ
diff --git a/plugins/sieverules/skins/larry/safari.css b/plugins/sieverules/skins/larry/safari.css
new file mode 100644
index 000000000..0add9e3d2
--- /dev/null
+++ b/plugins/sieverules/skins/larry/safari.css
@@ -0,0 +1,8 @@
+/**
+ * SieveRules plugin styles (safari hacks)
+ */
+
+table.records-table td.vacdaysexp
+{
+ word-wrap: break-word;
+} \ No newline at end of file
diff --git a/plugins/sieverules/skins/larry/sieverules.css b/plugins/sieverules/skins/larry/sieverules.css
new file mode 100644
index 000000000..c726acfed
--- /dev/null
+++ b/plugins/sieverules/skins/larry/sieverules.css
@@ -0,0 +1,435 @@
+/**
+ * SieveRules plugin styles
+ */
+
+#sieverules-list
+{
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 260px;
+ bottom: 0;
+}
+
+#sieverules-list-filters
+{
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ width: 100%;
+ overflow: auto;
+}
+
+#sieverules-list-filters thead td
+{
+ height: 15px;
+}
+
+#sieverules-list-filters thead td span
+{
+ position: absolute;
+ top: 10px;
+ left: 8px;
+ right: 30px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+
+#sieverules-list-filters thead td img
+{
+ position: absolute;
+ top: 9px;
+ right: 8px;
+}
+
+#sieverules-list-examples
+{
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ width: 100%;
+ overflow: auto;
+}
+
+#sieverules-details
+{
+ position: absolute;
+ top: 0;
+ left: 270px;
+ right: 0;
+ bottom: 0;
+}
+
+#sieverules-advanced
+{
+ position: absolute;
+ top: 0;
+ left: 232px;
+ right: 0;
+ bottom: 0;
+}
+
+span.disableLink
+{
+ float: right;
+ width: 200px;
+ text-align: right;
+}
+
+#sieverules-table,
+#sieverules-examples
+{
+ width: 100%;
+}
+
+#sieverules-table tbody td
+{
+ cursor: default;
+}
+
+#sieverules-table tbody td.control,
+#rules-table tbody td.control,
+#actions-table tbody td.control
+{
+ text-align: right;
+}
+
+#sieverules-table tbody td.control a,
+#rules-table tbody td.control a,
+#actions-table tbody td.control a
+{
+ display: block;
+ float: right;
+ width: 16px;
+ height: 16px;
+ background-image: url(icons.png);
+}
+
+#sieverules-table tbody td.control a.up_arrow
+{
+ background-position: 0 0;
+}
+
+#sieverules-table tbody td.control a.down_arrow
+{
+ background-position: 0 -18px;
+}
+
+#rules-table tbody td.control,
+#actions-table tbody td.control
+{
+ vertical-align: top;
+}
+
+#rules-table tbody td.control a.add,
+#actions-table tbody td.control a.add
+{
+ margin-left: 5px;
+ background-position: 0 -78px;
+}
+
+#rules-table tbody td.control a.delete,
+#actions-table tbody td.control a.delete
+{
+ background-position: 0 -59px;
+}
+
+#rules-table tbody td.control a.delete_act,
+#actions-table tbody td.control a.delete_act
+{
+ background-position: 0 -39px;
+}
+
+#actions-table tbody a.vacsig
+{
+ display: block;
+ width: 16px;
+ height: 16px;
+ background-image: url(icons.png);
+ background-position: -1px -126px;
+}
+
+#actions-table tbody a.vacsig_act
+{
+ display: block;
+ width: 16px;
+ height: 16px;
+ background-image: url(icons.png);
+ background-position: -1px -102px;
+}
+
+table.records-table
+{
+ width: auto;
+ border: 0;
+}
+
+table.records-table tbody td,
+table.records-table thead td
+{
+ border: 0;
+}
+
+#rules-table,
+#actions-table
+{
+ width: 100%;
+}
+
+#rules-table td table.records-table
+{
+ width: auto;
+}
+
+#rules-table td,
+#actions-table td,
+#rules-table td table.records-table td
+{
+ width: auto;
+}
+
+#rules-table td.selheader,
+#rules-table td.op
+{
+ width: 130px;
+}
+
+#rules-table td.header
+{
+ width: 135px;
+}
+
+#rules-table td.target
+{
+ width: 180px;
+}
+
+#rules-table input
+{
+ width: 150px;
+}
+
+#rules-table input.short
+{
+ width: 100px;
+}
+
+#rules-table select
+{
+ width: 123px;
+}
+
+#rules-table select.short
+{
+ width: 45px;
+}
+
+#rules-table select.long
+{
+ width: 157px;
+}
+
+#rules-table td table.records-table select
+{
+ width: 432px;
+}
+
+#rules-table td table.records-table input
+{
+ width: 426px;
+}
+
+#rules-table td table.records-table input.short
+{
+ width: 406px;
+}
+
+#rules-table td table.records-table input.radio
+{
+ width: auto;
+}
+
+#actions-table td.action
+{
+ width: 165px;
+ vertical-align: top;
+}
+
+#actions-table td.folder
+{
+ width: 420px;
+ vertical-align: top;
+}
+
+#actions-table td.action select
+{
+ width: 160px;
+}
+
+#actions-table td.folder input,
+#actions-table td.folder textarea
+{
+ width: 400px;
+}
+
+#actions-table td.folder select
+{
+ width: 408px;
+}
+
+#actions-table td.folder table.records-table select
+{
+ width: 337px;
+}
+
+#actions-table td.folder table.records-table input,
+#actions-table td.folder table.records-table textarea
+{
+ width: 330px;
+}
+
+#actions-table td.folder table.records-table input.short,
+#actions-table td.folder table.records-table select.short
+{
+ width: 310px;
+}
+
+#actions-table td.folder table.records-table input.checkbox,
+#actions-table td.folder table.records-table input.radio
+{
+ width: auto;
+}
+
+table.records-table td.msg
+{
+ vertical-align: top;
+}
+
+table.records-table td.vacdaysexp
+{
+ width: 398px;
+ white-space: -moz-pre-wrap !important;
+ white-space: pre-wrap !important;
+ white-space: pre;
+}
+
+#advancedmode
+{
+ white-space: nowrap;
+ text-align: right;
+ position: absolute;
+ bottom: 30px;
+ right: 20px;
+ width: 460px;
+}
+
+#sieverules-advancedbox
+{
+ position: absolute;
+ top: 34px;
+ left: 0;
+ bottom: 100px;
+ right: 8px;
+}
+
+#sieverules-advanced textarea
+{
+ position: absolute;
+ top: 0;
+ left: 0;
+ border: 0;
+ width: 100%;
+ height: 100%;
+}
+
+.listing tbody tr.droptarget td
+{
+ border-top: 2px solid #0e5266;
+ background-color: #D9ECF4;
+}
+
+.listing tbody tr.droptargetend td
+{
+ border-bottom: 2px solid #0e5266;
+ background-color: #D9ECF4;
+}
+
+#sieverulesrsdialog h3
+{
+ color: #333;
+ font-size: medium;
+ margin-top: 0.5em;
+ margin-bottom: 1em;
+}
+
+#sieverulesrsdialog table td input
+{
+ width: 20em;
+}
+
+#sieverulesrsdialog .formbuttons
+{
+ margin-top: 1.5em;
+ text-align: center;
+}
+
+input.inputmask
+{
+ color: #999999;
+}
+
+#sieverulesactionsmenu a.selected
+{
+ font-weight: bold;
+}
+
+#sieverules-advbuttons
+{
+ position: absolute;
+ left: 0;
+ bottom: 45px;
+}
+
+#sieverules-advanced .boxfooter
+{
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ height: 27px;
+ padding-left: 1px;
+ border-top: 1px solid #ddd;
+ border-radius: 0 0 4px 4px;
+ background: #eaeaea;
+ background: -moz-linear-gradient(top, #eaeaea 0%, #c8c8c8 100%);
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#eaeaea), color-stop(100%,#c8c8c8));
+ background: -o-linear-gradient(top, #eaeaea 0%, #c8c8c8 100%);
+ background: -ms-linear-gradient(top, #eaeaea 0%, #c8c8c8 100%);
+ background: linear-gradient(top, #eaeaea 0%, #c8c8c8 100%);
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+#sieverules-advanced .boxfooter .listbutton
+{
+ background: #C4BEBE;
+}
+
+#sieverules-advanced .boxfooter .listbutton .inner
+{
+ height: 20px;
+ background-image: url(listicons.png);
+ background-position: 5px -52px;
+}
+
+#sieverules-advanced .boxfooter #message
+{
+ position: absolute;
+ top: 0;
+ left: 65px;
+} \ No newline at end of file
diff --git a/plugins/sieverules/skins/larry/tabstyles.css b/plugins/sieverules/skins/larry/tabstyles.css
new file mode 100644
index 000000000..a7c988240
--- /dev/null
+++ b/plugins/sieverules/skins/larry/tabstyles.css
@@ -0,0 +1,15 @@
+/**
+ * SieveRules plugin styles (tab styles)
+ */
+
+#settings-sections #settingstabpluginsieverules a
+{
+ background-image: url(listicons.png);
+ background-position: 6px -2px;
+}
+
+#settings-sections #settingstabpluginsieverules.selected a
+{
+ background-image: url(listicons.png);
+ background-position: 6px -25px;
+} \ No newline at end of file
diff --git a/plugins/sieverules/skins/larry/templates/advancededitor.html b/plugins/sieverules/skins/larry/templates/advancededitor.html
new file mode 100644
index 000000000..38186f049
--- /dev/null
+++ b/plugins/sieverules/skins/larry/templates/advancededitor.html
@@ -0,0 +1,60 @@
+<roundcube:object name="doctype" value="html5" />
+<html>
+<head>
+<title><roundcube:object name="pagetitle" /></title>
+<roundcube:include file="/includes/links.html" />
+<link rel="stylesheet" type="text/css" href="/this/sieverules.css" />
+<roundcube:if condition="browser:ie" />
+<link rel="stylesheet" type="text/css" href="/this/iehacks.css" />
+<roundcube:endif />
+<roundcube:if condition="browser:safari" />
+<link rel="stylesheet" type="text/css" href="/this/safari.css" />
+<roundcube:endif />
+</head>
+<body class="noscroll">
+
+<roundcube:include file="/includes/header.html" />
+
+<div id="mainscreen" class="offset">
+
+<roundcube:include file="/includes/settingstabs.html" />
+
+<div id="sieverules-advanced" class="uibox contentbox">
+
+<h1 class="boxtitle"><roundcube:object name="steptitle" /></h1>
+
+<div id="sieverules-advancedbox" class="boxcontent">
+<roundcube:object name="advancededitor" class="propform" />
+</div>
+
+<div id="sieverules-advbuttons">
+<div class="footerleft formbuttons">
+<roundcube:button command="plugin.sieverules.save" type="input" label="save" class="button mainaction" />
+</div>
+</div>
+
+<div class="boxfooter">
+<roundcube:button name="sieverulesactions" id="sieverulesactionsmenulink" type="link" title="sieverules.moreactions" class="listbutton groupactions" onclick="UI.show_popup('sieverulesactionsmenu', true, {id: 'sieverulesactionsmenu', obj:$('#sieverulesactionsmenu'), above:1}); return false" innerClass="inner" content="&#9881;" />
+<roundcube:object name="message" id="message" />
+</div>
+</div>
+
+</div>
+
+<roundcube:include file="/includes/footer.html" />
+
+<div id="sieverulesactionsmenu" class="popupmenu">
+<ul class="toolbarmenu">
+<roundcube:if condition="config:sieverules_multiplerules == true" />
+<li class="separator_below"><roundcube:button command="plugin.sieverules.ruleset_dialog" type="link" label="sieverules.newruleset" classAct="active" /></li>
+<roundcube:object name="rulelist" type="link" />
+<li class="separator_above"><roundcube:button command="plugin.sieverules.ruleset_dialog" prop="rename_ruleset" type="link" label="sieverules.renameruleset" classAct="active" /></li>
+<li><roundcube:button command="plugin.sieverules.del_ruleset" type="link" label="sieverules.delruleset" classAct="active" /></li>
+<li><roundcube:button command="plugin.sieverules.activate_ruleset" type="link" label="sieverules.activateruleset" classAct="active" /></li>
+<roundcube:endif />
+<li<roundcube:exp expression="config:sieverules_multiplerules == true ? ' class=separator_above' : ''" />><roundcube:button command="plugin.sieverules.sieverules_adveditor" prop="0" type="link" label="sieverules.stdeditor" classAct="active" /></li>
+</ul>
+</div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/plugins/sieverules/skins/larry/templates/editsieverule.html b/plugins/sieverules/skins/larry/templates/editsieverule.html
new file mode 100644
index 000000000..5b7fe285c
--- /dev/null
+++ b/plugins/sieverules/skins/larry/templates/editsieverule.html
@@ -0,0 +1,30 @@
+<roundcube:object name="doctype" value="html5" />
+<html>
+<head>
+<title><roundcube:object name="pagetitle" /></title>
+<roundcube:include file="/includes/links.html" />
+<link rel="stylesheet" type="text/css" href="/this/sieverules.css" />
+<roundcube:if condition="browser:ie" />
+<link rel="stylesheet" type="text/css" href="/this/iehacks.css" />
+<roundcube:endif />
+<roundcube:if condition="browser:safari" />
+<link rel="stylesheet" type="text/css" href="/this/safari.css" />
+<roundcube:endif />
+</head>
+<body class="iframe">
+
+<h1 class="boxtitle"><roundcube:object name="steptitle" /></h1>
+
+<div id="preferences-details" class="boxcontent">
+<roundcube:object name="sieveruleform" class="propform" helpIcon="/this/help.png" />
+</div>
+
+<div class="footerleft formbuttons">
+<roundcube:button command="plugin.sieverules.save" type="input" class="button mainaction" label="save" />
+<roundcube:button command="plugin.sieverules.copy_rule" type="input" class="button" label="sieverules.copy" condition="env:action=='plugin.sieverules.edit' && config:sieverules_multiplerules == true" />
+</div>
+
+<roundcube:include file="/includes/footer.html" />
+
+</body>
+</html> \ No newline at end of file
diff --git a/plugins/sieverules/skins/larry/templates/setupsieverules.html b/plugins/sieverules/skins/larry/templates/setupsieverules.html
new file mode 100644
index 000000000..0b11adbdd
--- /dev/null
+++ b/plugins/sieverules/skins/larry/templates/setupsieverules.html
@@ -0,0 +1,27 @@
+<roundcube:object name="doctype" value="html5" />
+<html>
+<head>
+<title><roundcube:object name="pagetitle" /></title>
+<roundcube:include file="/includes/links.html" />
+<link rel="stylesheet" type="text/css" href="/this/sieverules.css" />
+<roundcube:if condition="browser:ie" />
+<link rel="stylesheet" type="text/css" href="/this/iehacks.css" />
+<roundcube:endif />
+<roundcube:if condition="browser:safari" />
+<link rel="stylesheet" type="text/css" href="/this/safari.css" />
+<roundcube:endif />
+</head>
+<body class="iframe">
+
+<h1 class="boxtitle"><roundcube:object name="steptitle" /></h1>
+
+<div id="preferences-details" class="boxcontent">
+<roundcube:object name="sieverulessetup" class="propform" />
+</div>
+
+</div>
+
+<roundcube:include file="/includes/footer.html" />
+
+</body>
+</html> \ No newline at end of file
diff --git a/plugins/sieverules/skins/larry/templates/sieverules.html b/plugins/sieverules/skins/larry/templates/sieverules.html
new file mode 100644
index 000000000..694152076
--- /dev/null
+++ b/plugins/sieverules/skins/larry/templates/sieverules.html
@@ -0,0 +1,78 @@
+<roundcube:object name="doctype" value="html5" />
+<html>
+<head>
+<title><roundcube:object name="pagetitle" /></title>
+<roundcube:include file="/includes/links.html" />
+<link rel="stylesheet" type="text/css" href="/this/sieverules.css" />
+<roundcube:if condition="browser:ie" />
+<link rel="stylesheet" type="text/css" href="/this/iehacks.css" />
+<roundcube:endif />
+<roundcube:if condition="browser:safari" />
+<link rel="stylesheet" type="text/css" href="/this/safari.css" />
+<roundcube:endif />
+</head>
+<body class="noscroll">
+
+<roundcube:include file="/includes/header.html" />
+
+<div id="mainscreen" class="offset">
+
+<roundcube:include file="/includes/settingstabs.html" />
+
+<div id="settings-right">
+
+<div id="sieverules-list" class="uibox listbox">
+<div class="scroller withfooter">
+<roundcube:object name="sieveruleslist" class="listing" cellspacing="0" noheader="true" activeicon="/this/tick.png" inactiveicon="/this/cross.png" />
+<roundcube:object name="sieverulesexamplelist" class="listing" cellspacing="0" noheader="true" />
+</div>
+<div class="boxfooter">
+<roundcube:button command="plugin.sieverules.add" type="link" title="sieverules.newfilter" class="listbutton add disabled" classAct="listbutton add" innerClass="inner" content="+" /><roundcube:button command="plugin.sieverules.delete" type="link" title="delete" class="listbutton delete disabled" classAct="listbutton delete" innerClass="inner" content="-" /><roundcube:if condition="config:sieverules_multiplerules == true || config:sieverules_adveditor == 1 || config:sieverules_adveditor == 2" /><roundcube:button name="sieverulesactions" id="sieverulesactionsmenulink" type="link" title="sieverules.moreactions" class="listbutton groupactions" onclick="UI.show_popup('sieverulesactionsmenu', true, {id: 'sieverulesactionsmenu', obj:$('#sieverulesactionsmenu'), above:1}); return false" innerClass="inner" content="&#9881;" /><roundcube:endif />
+</div>
+</div>
+
+<div id="sieverules-details" class="uibox contentbox">
+<div class="iframebox">
+ <roundcube:object name="sieverulesframe" id="preferences-frame" style="width:100%; height:100%" frameborder="0" src="/watermark.html" />
+</div>
+<roundcube:object name="message" id="message" class="statusbar" />
+</div>
+
+</div>
+
+</div>
+
+<roundcube:include file="/includes/footer.html" />
+
+<div id="sieverulesactionsmenu" class="popupmenu">
+<ul class="toolbarmenu">
+<roundcube:if condition="config:sieverules_multiplerules == true" />
+<li class="separator_below"><roundcube:button command="plugin.sieverules.ruleset_dialog" type="link" label="sieverules.newruleset" classAct="active" /></li>
+<roundcube:object name="rulelist" type="link" />
+<li class="separator_above"><roundcube:button command="plugin.sieverules.ruleset_dialog" prop="rename_ruleset" type="link" label="sieverules.renameruleset" classAct="active" /></li>
+<li><roundcube:button command="plugin.sieverules.del_ruleset" type="link" label="sieverules.delruleset" classAct="active" /></li>
+<li><roundcube:button command="plugin.sieverules.activate_ruleset" type="link" label="sieverules.activateruleset" classAct="active" /></li>
+<roundcube:endif />
+<roundcube:if condition="config:sieverules_adveditor == 1 || config:sieverules_adveditor == 2" />
+<li<roundcube:exp expression="config:sieverules_multiplerules == true ? ' class=separator_above' : ''" />><roundcube:button command="plugin.sieverules.sieverules_adveditor" prop="1" type="link" label="sieverules.adveditor" classAct="active" /></li>
+<roundcube:endif />
+</ul>
+</div>
+
+<script type="text/javascript">
+/* <![CDATA[ */
+
+$(document).ready(function(){
+ new rcube_splitter({id:'sieverulesviewsplitter', p1: '#sieverules-list', p2: '#sieverules-details', orientation: 'v', relative: true, start: 240}).init();
+
+ if ($('#sieverules-list-examples').length > 0) {
+ var filtersHeight = parseInt($('#sieverules-list').height() - 210);
+ new rcube_splitter({id:'sievefiltersviewsplitter', p1: '#sieverules-list-filters', p2: '#sieverules-list-examples', orientation: 'h', relative: true, start: filtersHeight}).init();
+ }
+});
+
+/* ]]> */
+</script>
+
+</body>
+</html> \ No newline at end of file
diff --git a/plugins/sieverules/skins/larry/tick.png b/plugins/sieverules/skins/larry/tick.png
new file mode 100644
index 000000000..6a26a6a08
--- /dev/null
+++ b/plugins/sieverules/skins/larry/tick.png
Binary files differ
diff --git a/plugins/thunderbird_labels/localization/bg_BG.inc b/plugins/thunderbird_labels/localization/bg_BG.inc
new file mode 100644
index 000000000..d4f9e45ad
--- /dev/null
+++ b/plugins/thunderbird_labels/localization/bg_BG.inc
@@ -0,0 +1,17 @@
+<?php
+/**
+* Author:
+* Deyan Stoykov
+* http://code.google.com/p/rcmail-thunderbird-labels/
+*/
+
+$labels = array();
+$labels['label'] = 'Thunderbird етикети';
+$labels['label0'] = 'Без етикет';
+$labels['label1'] = 'Важно';
+$labels['label2'] = 'Работно';
+$labels['label3'] = 'Лично';
+$labels['label4'] = 'За изпълнение';
+$labels['label5'] = 'Отложено';
+
+$messages = array();
diff --git a/plugins/thunderbird_labels/localization/ca_ES.inc b/plugins/thunderbird_labels/localization/ca_ES.inc
new file mode 100644
index 000000000..d34c8efc8
--- /dev/null
+++ b/plugins/thunderbird_labels/localization/ca_ES.inc
@@ -0,0 +1,17 @@
+<?php
+/**
+* Author:
+* Lluís Forns Puigmartí
+* http://code.google.com/p/rcmail-thunderbird-labels/
+*/
+
+$labels = array();
+$labels['label'] = 'Etiquetes';
+$labels['label0'] = 'Cap etiqueta';
+$labels['label1'] = 'Important';
+$labels['label2'] = 'Feina';
+$labels['label3'] = 'Personal';
+$labels['label4'] = 'Per fer';
+$labels['label5'] = 'Més tard';
+
+$messages = array();
diff --git a/plugins/thunderbird_labels/localization/cs_CZ.inc b/plugins/thunderbird_labels/localization/cs_CZ.inc
new file mode 100644
index 000000000..d5fae12bb
--- /dev/null
+++ b/plugins/thunderbird_labels/localization/cs_CZ.inc
@@ -0,0 +1,18 @@
+<?php
+/**
+* Author:
+* Miroslav Zidek
+* http://code.google.com/p/rcmail-thunderbird-labels/
+*/
+
+$labels = array();
+$labels['label'] = 'Štítky Thunderbirdu';
+$labels['label0'] = 'Žádný štítek';
+$labels['label1'] = 'Důležité';
+$labels['label2'] = 'Pracovní';
+$labels['label3'] = 'Osobní';
+$labels['label4'] = 'Udělat';
+$labels['label5'] = 'Později';
+
+$messages = array();
+
diff --git a/plugins/thunderbird_labels/localization/de_DE.inc b/plugins/thunderbird_labels/localization/de_DE.inc
new file mode 100644
index 000000000..86473f60a
--- /dev/null
+++ b/plugins/thunderbird_labels/localization/de_DE.inc
@@ -0,0 +1,18 @@
+<?php
+/**
+* Author:
+* Michael Kefeder
+* http://code.google.com/p/rcmail-thunderbird-labels/
+*/
+
+$labels = array();
+$labels['label'] = 'Thunderbird Schlagwörter';
+$labels['label0'] = 'Alle Entfernen';
+$labels['label1'] = 'Wichtig';
+$labels['label2'] = 'Dienstlich';
+$labels['label3'] = 'Persönlich'; // grün
+$labels['label4'] = 'Zu Erledigen'; // blau
+$labels['label5'] = 'Später';
+
+$messages = array();
+
diff --git a/plugins/thunderbird_labels/localization/en_US.inc b/plugins/thunderbird_labels/localization/en_US.inc
new file mode 100644
index 000000000..2d4237e05
--- /dev/null
+++ b/plugins/thunderbird_labels/localization/en_US.inc
@@ -0,0 +1,18 @@
+<?php
+/**
+* Author:
+* Michael Kefeder
+* http://code.google.com/p/rcmail-thunderbird-labels/
+*/
+
+$labels = array();
+$labels['label'] = 'Thunderbird Labels';
+$labels['label0'] = 'No Label';
+$labels['label1'] = 'Important';
+$labels['label2'] = 'Work';
+$labels['label3'] = 'Personal';
+$labels['label4'] = 'To Do';
+$labels['label5'] = 'Later';
+
+$messages = array();
+
diff --git a/plugins/thunderbird_labels/localization/fr_FR.inc b/plugins/thunderbird_labels/localization/fr_FR.inc
new file mode 100644
index 000000000..e50690a2a
--- /dev/null
+++ b/plugins/thunderbird_labels/localization/fr_FR.inc
@@ -0,0 +1,17 @@
+<?php
+/**
+* Author:
+* Michael Kefeder
+* http://code.google.com/p/rcmail-thunderbird-labels/
+*/
+
+$labels = array();
+
+$labels['label'] = 'Thunderbird Etiquettes';
+$labels['label0'] = 'Enlever toutes les &eacute;tiquettes';
+$labels['label1'] = 'Important';
+$labels['label2'] = 'Travail';
+$labels['label3'] = 'Personnel';
+$labels['label4'] = 'A faire';
+$labels['label5'] = 'Plus tard';
+
diff --git a/plugins/thunderbird_labels/localization/hu_HU.inc b/plugins/thunderbird_labels/localization/hu_HU.inc
new file mode 100644
index 000000000..eb450d899
--- /dev/null
+++ b/plugins/thunderbird_labels/localization/hu_HU.inc
@@ -0,0 +1,18 @@
+<?php
+/**
+* Author:
+* Daniel P.
+* http://code.google.com/p/rcmail-thunderbird-labels/
+*/
+
+$labels = array();
+$labels['label'] = 'Thunderbird Cimkék';
+$labels['label0'] = 'Minden cimke törlése';
+$labels['label1'] = 'Fontos';
+$labels['label2'] = 'Munka';
+$labels['label3'] = 'Személyes';
+$labels['label4'] = 'Teendők';
+$labels['label5'] = 'Később';
+
+$messages = array();
+
diff --git a/plugins/thunderbird_labels/localization/lv_LV.inc b/plugins/thunderbird_labels/localization/lv_LV.inc
new file mode 100644
index 000000000..00d557c7b
--- /dev/null
+++ b/plugins/thunderbird_labels/localization/lv_LV.inc
@@ -0,0 +1,17 @@
+<?php
+/**
+* Author:
+* Artem Ushakov
+* http://code.google.com/p/rcmail-thunderbird-labels/
+*/
+
+$labels = array();
+$labels['label'] = 'Vēstules atzīme';
+$labels['label0'] = 'Izdzēst visas atzīmes';
+$labels['label1'] = 'Svarīgs';
+$labels['label2'] = 'Darba';
+$labels['label3'] = 'Personāls';
+$labels['label4'] = 'Izpildei';
+$labels['label5'] = 'Atlikts';
+
+$messages = array();
diff --git a/plugins/thunderbird_labels/localization/pl_PL.inc b/plugins/thunderbird_labels/localization/pl_PL.inc
new file mode 100644
index 000000000..52284a802
--- /dev/null
+++ b/plugins/thunderbird_labels/localization/pl_PL.inc
@@ -0,0 +1,18 @@
+<?php
+/**
+* Author:
+* master771
+* http://code.google.com/p/rcmail-thunderbird-labels/
+*/
+
+$labels = array();
+$labels['label'] = 'Etykiety';
+$labels['label0'] = 'Brak';
+$labels['label1'] = 'Ważne';
+$labels['label2'] = 'Praca';
+$labels['label3'] = 'Osobiste';
+$labels['label4'] = 'Do zrobienia';
+$labels['label5'] = 'Później';
+
+$messages = array();
+
diff --git a/plugins/thunderbird_labels/localization/ru_RU.inc b/plugins/thunderbird_labels/localization/ru_RU.inc
new file mode 100644
index 000000000..d3bfa3220
--- /dev/null
+++ b/plugins/thunderbird_labels/localization/ru_RU.inc
@@ -0,0 +1,18 @@
+<?php
+/**
+* Author:
+* Николай Николай
+* http://code.google.com/p/rcmail-thunderbird-labels/
+*/
+
+$labels = array();
+$labels['label'] = 'Метка Thunderbird';
+$labels['label0'] = 'Удалить все метки';
+$labels['label1'] = 'Важное';
+$labels['label2'] = 'Рабочее';
+$labels['label3'] = 'Личное';
+$labels['label4'] = 'К исполнению';
+$labels['label5'] = 'Отложено';
+
+$messages = array();
+
diff --git a/plugins/thunderbird_labels/skins/classic/tb_label.css b/plugins/thunderbird_labels/skins/classic/tb_label.css
new file mode 100644
index 000000000..3daf6a793
--- /dev/null
+++ b/plugins/thunderbird_labels/skins/classic/tb_label.css
@@ -0,0 +1,183 @@
+/**
+* Author:
+* Michael Kefeder
+* http://code.google.com/p/rcmail-thunderbird-labels/
+*
+* CSS is Based on a patch for roundcube 0.3 I found a long time ago
+*/
+
+#tb_label_popuplink {
+ background-image: url(thunderbird_32.png);
+ background-repeat: no-repeat;
+ width: 32px;
+ height: 32px;
+ padding: 0px;
+ margin: 0px 5px 0px 5px;
+}
+
+#tb_label_popup
+{
+ width: auto;
+ position: absolute;
+}
+
+#tb_label_popup a.active
+{
+ color: inherit; /* fix for firefox */
+}
+
+.toolbarmenu li.label0 a
+{
+ color: #CCC;
+}
+.toolbarmenu li.label0,
+.toolbarmenu li.label0 a.active
+{
+ color: #333;
+}
+.toolbarmenu li.label1 a
+{
+ color: #FCC;
+}
+.toolbarmenu li.label2 a
+{
+ color: #FC3;
+}
+.toolbarmenu li.label3 a
+{
+ color: #3C3;
+}
+.toolbarmenu li.label4 a
+{
+ color: #99F;
+}
+.toolbarmenu li.label5 a
+{
+ color: #C9C;
+}
+/* Colors for single/preview message window headers display */
+table.label1
+{
+ background-color: #FCC;
+}
+table.label2
+{
+ background-color: #FC3;
+}
+table.label3
+{
+ background-color: #3C3;
+}
+table.label4
+{
+ background-color: #99F;
+}
+table.label5
+{
+ background-color: #C9C;
+}
+
+/* Support for Thunderbird label: definition of the 5 label color */
+/* Unselected (unfocused) messages */
+#messagelist tr.label1 td,
+#messagelist tr.label1 td a,
+.toolbarmenu li.label1,
+.toolbarmenu li.label1 a.active
+{
+ color: #FF0000;
+}
+
+#messagelist tr.label2 td,
+#messagelist tr.label2 td a,
+.toolbarmenu li.label2,
+.toolbarmenu li.label2 a.active
+{
+ color: #FF9900;
+}
+
+#messagelist tr.label3 td,
+#messagelist tr.label3 td a,
+.toolbarmenu li.label3,
+.toolbarmenu li.label3 a.active
+{
+ color: #009900;
+}
+
+#messagelist tr.label4 td,
+#messagelist tr.label4 td a,
+.toolbarmenu li.label4,
+.toolbarmenu li.label4 a.active
+{
+ color: #3333FF;
+}
+
+#messagelist tr.label5 td,
+#messagelist tr.label5 td a,
+.toolbarmenu li.label5,
+.toolbarmenu li.label5 a.active
+{
+ color: #993399;
+}
+
+/* Selected messages */
+#messagelist tr.selected.label1 td,
+#messagelist tr.selected.label1 td a
+{
+ color: #FFFFFF;
+ background-color: #FF0000;
+}
+
+#messagelist tr.selected.label2 td,
+#messagelist tr.selected.label2 td a
+{
+ color: #FFFFFF;
+ background-color: #FF9900;
+}
+
+#messagelist tr.selected.label3 td,
+#messagelist tr.selected.label3 td a
+{
+ color: #FFFFFF;
+ background-color: #009900;
+}
+
+#messagelist tr.selected.label4 td,
+#messagelist tr.selected.label4 td a
+{
+ color: #FFFFFF;
+ background-color: #3333FF;
+}
+
+#messagelist tr.selected.label5 td,
+#messagelist tr.selected.label5 td a
+{
+ color: #FFFFFF;
+ background-color: #993399;
+}
+
+/* Non-labeled selected message: changed to make it look "like" Thunderbird */
+/*#messagelist tr.selected td
+{
+ color: #000000;
+ background-color: #F0CB82;
+}
+*/
+/* Addition for selected RCM "flagged" message */
+/*#messagelist tr.selected.flagged td
+{
+ color: #FFFFFF;
+ background-color: #CC3333;
+}
+*/
+/* Non specific message : changed to make it look like Thunderbird */
+/*#messagelist tr.selected td a
+{
+ color: #000000;
+}
+*/
+/* Addition for selected RCM "flagged" message */
+/*#messagelist tr.selected.flagged td a
+{
+ color: #FFFFFF;
+}
+*/
diff --git a/plugins/thunderbird_labels/skins/classic/thunderbird_32.png b/plugins/thunderbird_labels/skins/classic/thunderbird_32.png
new file mode 100644
index 000000000..b51af5e04
--- /dev/null
+++ b/plugins/thunderbird_labels/skins/classic/thunderbird_32.png
Binary files differ
diff --git a/plugins/thunderbird_labels/skins/default/tb_label.css b/plugins/thunderbird_labels/skins/default/tb_label.css
new file mode 100644
index 000000000..3daf6a793
--- /dev/null
+++ b/plugins/thunderbird_labels/skins/default/tb_label.css
@@ -0,0 +1,183 @@
+/**
+* Author:
+* Michael Kefeder
+* http://code.google.com/p/rcmail-thunderbird-labels/
+*
+* CSS is Based on a patch for roundcube 0.3 I found a long time ago
+*/
+
+#tb_label_popuplink {
+ background-image: url(thunderbird_32.png);
+ background-repeat: no-repeat;
+ width: 32px;
+ height: 32px;
+ padding: 0px;
+ margin: 0px 5px 0px 5px;
+}
+
+#tb_label_popup
+{
+ width: auto;
+ position: absolute;
+}
+
+#tb_label_popup a.active
+{
+ color: inherit; /* fix for firefox */
+}
+
+.toolbarmenu li.label0 a
+{
+ color: #CCC;
+}
+.toolbarmenu li.label0,
+.toolbarmenu li.label0 a.active
+{
+ color: #333;
+}
+.toolbarmenu li.label1 a
+{
+ color: #FCC;
+}
+.toolbarmenu li.label2 a
+{
+ color: #FC3;
+}
+.toolbarmenu li.label3 a
+{
+ color: #3C3;
+}
+.toolbarmenu li.label4 a
+{
+ color: #99F;
+}
+.toolbarmenu li.label5 a
+{
+ color: #C9C;
+}
+/* Colors for single/preview message window headers display */
+table.label1
+{
+ background-color: #FCC;
+}
+table.label2
+{
+ background-color: #FC3;
+}
+table.label3
+{
+ background-color: #3C3;
+}
+table.label4
+{
+ background-color: #99F;
+}
+table.label5
+{
+ background-color: #C9C;
+}
+
+/* Support for Thunderbird label: definition of the 5 label color */
+/* Unselected (unfocused) messages */
+#messagelist tr.label1 td,
+#messagelist tr.label1 td a,
+.toolbarmenu li.label1,
+.toolbarmenu li.label1 a.active
+{
+ color: #FF0000;
+}
+
+#messagelist tr.label2 td,
+#messagelist tr.label2 td a,
+.toolbarmenu li.label2,
+.toolbarmenu li.label2 a.active
+{
+ color: #FF9900;
+}
+
+#messagelist tr.label3 td,
+#messagelist tr.label3 td a,
+.toolbarmenu li.label3,
+.toolbarmenu li.label3 a.active
+{
+ color: #009900;
+}
+
+#messagelist tr.label4 td,
+#messagelist tr.label4 td a,
+.toolbarmenu li.label4,
+.toolbarmenu li.label4 a.active
+{
+ color: #3333FF;
+}
+
+#messagelist tr.label5 td,
+#messagelist tr.label5 td a,
+.toolbarmenu li.label5,
+.toolbarmenu li.label5 a.active
+{
+ color: #993399;
+}
+
+/* Selected messages */
+#messagelist tr.selected.label1 td,
+#messagelist tr.selected.label1 td a
+{
+ color: #FFFFFF;
+ background-color: #FF0000;
+}
+
+#messagelist tr.selected.label2 td,
+#messagelist tr.selected.label2 td a
+{
+ color: #FFFFFF;
+ background-color: #FF9900;
+}
+
+#messagelist tr.selected.label3 td,
+#messagelist tr.selected.label3 td a
+{
+ color: #FFFFFF;
+ background-color: #009900;
+}
+
+#messagelist tr.selected.label4 td,
+#messagelist tr.selected.label4 td a
+{
+ color: #FFFFFF;
+ background-color: #3333FF;
+}
+
+#messagelist tr.selected.label5 td,
+#messagelist tr.selected.label5 td a
+{
+ color: #FFFFFF;
+ background-color: #993399;
+}
+
+/* Non-labeled selected message: changed to make it look "like" Thunderbird */
+/*#messagelist tr.selected td
+{
+ color: #000000;
+ background-color: #F0CB82;
+}
+*/
+/* Addition for selected RCM "flagged" message */
+/*#messagelist tr.selected.flagged td
+{
+ color: #FFFFFF;
+ background-color: #CC3333;
+}
+*/
+/* Non specific message : changed to make it look like Thunderbird */
+/*#messagelist tr.selected td a
+{
+ color: #000000;
+}
+*/
+/* Addition for selected RCM "flagged" message */
+/*#messagelist tr.selected.flagged td a
+{
+ color: #FFFFFF;
+}
+*/
diff --git a/plugins/thunderbird_labels/skins/default/thunderbird_32.png b/plugins/thunderbird_labels/skins/default/thunderbird_32.png
new file mode 100644
index 000000000..b51af5e04
--- /dev/null
+++ b/plugins/thunderbird_labels/skins/default/thunderbird_32.png
Binary files differ
diff --git a/plugins/thunderbird_labels/skins/larry/tb_label.css b/plugins/thunderbird_labels/skins/larry/tb_label.css
new file mode 100644
index 000000000..1c6936cd7
--- /dev/null
+++ b/plugins/thunderbird_labels/skins/larry/tb_label.css
@@ -0,0 +1,170 @@
+/**
+* Author:
+* Michael Kefeder
+* http://code.google.com/p/rcmail-thunderbird-labels/
+*
+* CSS is Based on a patch for roundcube 0.3 I found a long time ago
+*/
+
+#tb_label_popuplink {
+ background-image: url(thunderbird_32.png);
+ /*background-repeat: repeat;*/
+ background-position: 50% 0px;
+ width: 32px;
+ height: 13px;
+ padding: 28px 2px 0px 2px;
+ margin: 0px 5px 0px 5px;
+}
+
+#tb_label_popup
+{
+ width: auto;
+ position: absolute;
+}
+
+#tb_label_popup a.active
+{
+ color: inherit; /* fix for firefox */
+}
+
+.toolbarmenu li.label0,
+.toolbarmenu li.label0 a.active
+{
+ color: #EEE;
+}
+/* Colors for single/preview message window headers display */
+table.label1
+{
+ background-color: #FCC;
+}
+table.label2
+{
+ background-color: #FC3;
+}
+table.label3
+{
+ background-color: #3C3;
+}
+table.label4
+{
+ background-color: #99F;
+}
+table.label5
+{
+ background-color: #C9C;
+}
+
+/* Support for Thunderbird label: definition of the 5 label color */
+/* Unselected (unfocused) messages */
+#messagelist tr.label1 td,
+#messagelist tr.label1 td a,
+.toolbarmenu li.label1,
+.toolbarmenu li.label1 a.active
+{
+ color: #FF0000;
+}
+
+#messagelist tr.label2 td,
+#messagelist tr.label2 td a,
+.toolbarmenu li.label2,
+.toolbarmenu li.label2 a.active
+{
+ color: #FF9900;
+}
+
+#messagelist tr.label3 td,
+#messagelist tr.label3 td a,
+.toolbarmenu li.label3,
+.toolbarmenu li.label3 a.active
+{
+ color: #009900;
+}
+
+#messagelist tr.label4 td,
+#messagelist tr.label4 td a
+{
+ color: #3333FF;
+}
+
+/* lighter blue for dark-grey popup... */
+.toolbarmenu li.label4,
+.toolbarmenu li.label4 a.active
+{
+ color: #0CF;
+}
+
+#messagelist tr.label5 td,
+#messagelist tr.label5 td a
+{
+ color: #993399;
+}
+
+/* lighter purple for dark-grey popup... */
+.toolbarmenu li.label5,
+.toolbarmenu li.label5 a.active
+{
+ color: #B6F;
+}
+
+/* Selected messages */
+#messagelist tr.selected.label1 td,
+#messagelist tr.selected.label1 td a
+{
+ color: #FFFFFF;
+ background-color: #FF0000;
+}
+
+#messagelist tr.selected.label2 td,
+#messagelist tr.selected.label2 td a
+{
+ color: #FFFFFF;
+ background-color: #FF9900;
+}
+
+#messagelist tr.selected.label3 td,
+#messagelist tr.selected.label3 td a
+{
+ color: #FFFFFF;
+ background-color: #009900;
+}
+
+#messagelist tr.selected.label4 td,
+#messagelist tr.selected.label4 td a
+{
+ color: #FFFFFF;
+ background-color: #3333FF;
+}
+
+#messagelist tr.selected.label5 td,
+#messagelist tr.selected.label5 td a
+{
+ color: #FFFFFF;
+ background-color: #993399;
+}
+
+/* Non-labeled selected message: changed to make it look "like" Thunderbird */
+/*#messagelist tr.selected td
+{
+ color: #000000;
+ background-color: #F0CB82;
+}
+*/
+/* Addition for selected RCM "flagged" message */
+/*#messagelist tr.selected.flagged td
+{
+ color: #FFFFFF;
+ background-color: #CC3333;
+}
+*/
+/* Non specific message : changed to make it look like Thunderbird */
+/*#messagelist tr.selected td a
+{
+ color: #000000;
+}
+*/
+/* Addition for selected RCM "flagged" message */
+/*#messagelist tr.selected.flagged td a
+{
+ color: #FFFFFF;
+}
+*/
diff --git a/plugins/thunderbird_labels/skins/larry/thunderbird_32.png b/plugins/thunderbird_labels/skins/larry/thunderbird_32.png
new file mode 100644
index 000000000..c8254dd65
--- /dev/null
+++ b/plugins/thunderbird_labels/skins/larry/thunderbird_32.png
Binary files differ
diff --git a/plugins/thunderbird_labels/tb_label.js b/plugins/thunderbird_labels/tb_label.js
new file mode 100644
index 000000000..a9239f30f
--- /dev/null
+++ b/plugins/thunderbird_labels/tb_label.js
@@ -0,0 +1,369 @@
+/**
+ * Version:
+ * $Revision: 26 $
+ * Author:
+ * Michael Kefeder
+ * http://code.google.com/p/rcmail-thunderbird-labels/
+ */
+
+// global variable for contextmenu actions
+rcmail.tb_label_no = '';
+
+function rcmail_tb_label_menu(p)
+{
+ if (typeof rcmail_ui == "undefined")
+ rcmail_ui = UI;
+ if (!rcmail_ui.check_tb_popup())
+ rcmail_ui.tb_label_popup_add();
+
+ // Show the popup menu with tags
+ // -- skin larry vs classic
+ if (typeof rcmail_ui.show_popupmenu == "undefined")
+ rcmail_ui.show_popup('tb_label_popup');
+ else
+ rcmail_ui.show_popupmenu('tb_label_popup');
+
+ return false;
+}
+
+/**
+* Shows the colors based on flag info like in Thunderbird
+*/
+function rcm_tb_label_insert(uid, row)
+{
+ var message = rcmail.env.messages[uid];
+
+ if (message.flags && message.flags.tb_labels)
+ {
+ var rowobj = $(row.obj);
+ for (idx in message.flags.tb_labels)
+ rowobj.addClass('label' + message.flags.tb_labels[idx]);
+ }
+}
+
+/**
+* Shows the submenu of thunderbird labels
+*/
+function rcm_tb_label_submenu(p)
+{
+ if (typeof rcmail_ui == "undefined")
+ rcmail_ui = UI;
+ // setup onclick and active/non active classes
+ rcm_tb_label_create_popupmenu();
+
+ // -- create sensible popup, using roundcubes internals
+ if (!rcmail_ui.check_tb_popup())
+ rcmail_ui.tb_label_popup_add();
+ // -- skin larry vs classic
+ if (typeof rcmail_ui.show_popupmenu == "undefined")
+ rcmail_ui.show_popup('tb_label_popup');
+ else
+ rcmail_ui.show_popupmenu('tb_label_popup');
+ return false;
+}
+
+function rcm_tb_label_flag_toggle(flag_uids, toggle_label_no, onoff)
+{
+ var headers_table = $('table.headers-table');
+ var preview_frame = $('#messagecontframe');
+ // preview frame exists, simulate environment of single message view
+ if (preview_frame.length)
+ {
+ tb_labels_for_message = preview_frame.get(0).contentWindow.tb_labels_for_message;
+ headers_table = preview_frame.contents().find('table.headers-table');
+ }
+
+ if (!rcmail.message_list
+ && !headers_table)
+ return;
+ // for single message view
+ if (headers_table.length && flag_uids.length)
+ {
+ if (onoff == true)
+ {
+ // add color
+ headers_table.addClass('label'+toggle_label_no);
+ // add to flag list
+ tb_labels_for_message.push(toggle_label_no);
+ }
+ else
+ {
+ // remove color
+ headers_table.removeClass('label'+toggle_label_no);
+ var pos = jQuery.inArray(toggle_label_no, tb_labels_for_message);
+ if (pos > -1)
+ tb_labels_for_message.splice(pos, 1);
+ }
+ // exit function when in detail mode. when preview is active keep going
+ if (!rcmail.env.messages)
+ return;
+ }
+ jQuery.each(flag_uids, function (idx, uid) {
+ var message = rcmail.env.messages[uid];
+ var row = rcmail.message_list.rows[uid];
+ if (onoff == true)
+ {
+ // add colors
+ var rowobj = $(row.obj);
+ rowobj.addClass('label'+toggle_label_no);
+ // add to flag list
+ message.flags.tb_labels.push(toggle_label_no);
+ }
+ else
+ {
+ // remove colors
+ var rowobj = $(row.obj);
+ rowobj.removeClass('label'+toggle_label_no);
+ // remove from flag list
+ var pos = jQuery.inArray(toggle_label_no, message.flags.tb_labels);
+ if (pos > -1)
+ message.flags.tb_labels.splice(pos, 1);
+ }
+ });
+}
+
+function rcm_tb_label_flag_msgs(flag_uids, toggle_label_no)
+{
+ rcm_tb_label_flag_toggle(flag_uids, toggle_label_no, true);
+}
+
+function rcm_tb_label_unflag_msgs(unflag_uids, toggle_label_no)
+{
+ rcm_tb_label_flag_toggle(unflag_uids, toggle_label_no, false);
+}
+
+// helper function to get selected/active messages
+function rcm_tb_label_get_selection()
+{
+ var selection = rcmail.message_list ? rcmail.message_list.get_selection() : [];
+ if (selection.length == 0 && rcmail.env.uid)
+ selection = [rcmail.env.uid, ];
+ return selection;
+}
+
+function rcm_tb_label_create_popupmenu()
+{
+ for (i = 0; i < 6; i++)
+ {
+ var cur_a = $('li.label' + i +' a');
+
+ // add/remove active class
+ var selection = rcm_tb_label_get_selection();
+
+ if (selection.length == 0)
+ cur_a.removeClass('active');
+ else
+ cur_a.addClass('active');
+ }
+}
+
+function rcm_tb_label_init_onclick()
+{
+ for (i = 0; i < 6; i++)
+ {
+ var cur_a = $('#tb_label_popup li.label' + i +' a');
+
+ // TODO check if click event is defined instead of unbinding?
+ cur_a.unbind('click');
+ cur_a.click(function() {
+ var toggle_label = $(this).parent().attr('class');
+ var toggle_label_no = parseInt(toggle_label.replace('label', ''));
+ var selection = rcm_tb_label_get_selection();
+
+ if (!selection.length)
+ return;
+
+ var from = toggle_label_no;
+ var to = toggle_label_no + 1;
+ var unset_all = false;
+ // special case flag 0 means remove all flags
+ if (toggle_label_no == 0)
+ {
+ from = 1;
+ to = 6;
+ unset_all = true;
+ }
+ for (i = from; i < to; i++)
+ {
+ toggle_label = 'label' + i;
+ toggle_label_no = i;
+ // compile list of unflag and flag msgs and then send command
+ // Thunderbird modifies multiple message flags like it did the first in the selection
+ // e.g. first message has flag1, you click flag1, every message select loses flag1, the ones not having flag1 don't get it!
+ var first_toggle_mode = 'on';
+ if (rcmail.env.messages)
+ {
+ var first_message = rcmail.env.messages[selection[0]];
+ if (first_message.flags
+ && jQuery.inArray(toggle_label_no,
+ first_message.flags.tb_labels) >= 0
+ )
+ first_toggle_mode = 'off';
+ else
+ first_toggle_mode = 'on';
+ }
+ else // single message display
+ {
+ // flag already set?
+ if (jQuery.inArray(toggle_label_no,
+ tb_labels_for_message) >= 0)
+ first_toggle_mode = 'off';
+ }
+ var flag_uids = [];
+ var unflag_uids = [];
+ jQuery.each(selection, function (idx, uid) {
+ // message list not available (example: in detailview)
+ if (!rcmail.env.messages)
+ {
+ if (first_toggle_mode == 'on')
+ flag_uids.push(uid);
+ else
+ unflag_uids.push(uid);
+ // make sure for unset all there is the single message id
+ if (unset_all && unflag_uids.length == 0)
+ unflag_uids.push(uid);
+ return;
+ }
+ var message = rcmail.env.messages[uid];
+ if (message.flags
+ && jQuery.inArray(toggle_label_no,
+ message.flags.tb_labels) >= 0
+ )
+ {
+ if (first_toggle_mode == 'off')
+ unflag_uids.push(uid);
+ }
+ else
+ {
+ if (first_toggle_mode == 'on')
+ flag_uids.push(uid);
+ }
+ });
+
+ if (unset_all)
+ flag_uids = [];
+
+ // skip sending flags to backend that are not set anywhere
+ if (flag_uids.length == 0
+ && unflag_uids.length == 0)
+ continue;
+
+ var str_flag_uids = flag_uids.join(',');
+ var str_unflag_uids = unflag_uids.join(',');
+
+ var lock = rcmail.set_busy(true, 'loading');
+ rcmail.http_request('plugin.thunderbird_labels.set_flags', '_flag_uids=' + str_flag_uids + '&_unflag_uids=' + str_unflag_uids + '&_mbox=' + urlencode(rcmail.env.mailbox) + "&_toggle_label=" + toggle_label, lock);
+
+ // remove/add classes and tb labels from messages in JS
+ rcm_tb_label_flag_msgs(flag_uids, toggle_label_no);
+ rcm_tb_label_unflag_msgs(unflag_uids, toggle_label_no);
+ }
+ });
+ }
+}
+
+function rcmail_ctxm_label(command, el, pos)
+{
+ // my code works only on selected rows, contextmenu also on unselected
+ // so if no selection is available, use the uid set by contextmenu plugin
+ var selection = rcmail.message_list ? rcmail.message_list.get_selection() : [];
+
+ if (!selection.length && !rcmail.env.uid)
+ return;
+ if (!selection.length && rcmail.env.uid)
+ rcmail.message_list.select_row(rcmail.env.uid);
+
+ var cur_a = $('#tb_label_popup li.label' + rcmail.tb_label_no +' a');
+ if (cur_a)
+ {
+ cur_a.click();
+ }
+
+ return;
+}
+
+function rcmail_ctxm_label_set(which)
+{
+ // hack for my contextmenu submenu hack to propagate the selected label-no
+ rcmail.tb_label_no = which;
+}
+
+
+$(document).ready(function() {
+ rcm_tb_label_init_onclick();
+ // add keyboard shortcuts for normal keyboard and keypad
+ $(document).keyup(function(e) {
+ //console.log('Handler for .keyup() called.' + e.which);
+ var k = e.which;
+ if ((k > 47 && k < 58) || (k > 95 && k < 106))
+ {
+ var label_no = k % 48;
+ var cur_a = $('#tb_label_popup li.label' + label_no + ' a');
+
+ if (cur_a)
+ {
+ cur_a.click();
+ }
+ }
+ });
+
+ // if exists add contextmenu entries
+ if (window.rcm_contextmenu_register_command) {
+ rcm_contextmenu_register_command('ctxm_tb_label', rcmail_ctxm_label, $('#tb_label_ctxm_mainmenu'), 'moreacts', 'after', true);
+ }
+
+ // single message displayed?
+ if (window.tb_labels_for_message)
+ {
+ jQuery.each(tb_labels_for_message, function(idx, val)
+ {
+ rcm_tb_label_flag_msgs([-1,], val);
+ }
+ );
+ }
+
+ // add roundcube events
+ rcmail.addEventListener('insertrow', function(event) { rcm_tb_label_insert(event.uid, event.row); });
+
+ rcmail.addEventListener('init', function(evt) {
+ // create custom button, JS method, broken layout in Firefox 9 using PHP method now
+ /*var button = $('<A>').attr('href', '#').attr('id', 'tb_label_popuplink').attr('title', rcmail.gettext('label', 'thunderbird_labels')).html('');
+
+ button.bind('click', function(e) {
+ rcmail.command('plugin.thunderbird_labels.rcm_tb_label_submenu', this);
+ return false;
+ });
+
+ // add and register
+ rcmail.add_element(button, 'toolbar');
+ rcmail.register_button('plugin.thunderbird_labels.rcm_tb_label_submenu', 'tb_label_popuplink', 'link');
+ */
+ rcmail.register_command('plugin.thunderbird_labels.rcm_tb_label_submenu', rcm_tb_label_submenu, true);
+ });
+
+ // -- add my submenu to roundcubes UI (for roundcube classic only?)
+ if (window.rcube_mail_ui)
+ rcube_mail_ui.prototype.tb_label_popup_add = function() {
+ add = {
+ tb_label_popup: {id:'tb_label_popup'}
+ };
+ this.popups = $.extend(this.popups, add);
+ var obj = $('#'+this.popups.tb_label_popup.id);
+ if (obj.length)
+ this.popups.tb_label_popup.obj = obj;
+ else
+ delete this.popups.tb_label_popup;
+ };
+
+ if (window.rcube_mail_ui)
+ rcube_mail_ui.prototype.check_tb_popup = function() {
+ // larry skin doesn't have that variable, popup works automagically, return true
+ if (typeof this.popups == 'undefined')
+ return true;
+ if (this.popups.tb_label_popup)
+ return true;
+ else
+ return false;
+ };
+});
+
diff --git a/plugins/thunderbird_labels/thunderbird_labels.php b/plugins/thunderbird_labels/thunderbird_labels.php
new file mode 100644
index 000000000..e6487ae95
--- /dev/null
+++ b/plugins/thunderbird_labels/thunderbird_labels.php
@@ -0,0 +1,210 @@
+<?php
+/**
+ * Thunderbird Labels Plugin for Roundcube Webmail
+ *
+ * Plugin to show the 5 Message Labels Thunderbird Email-Client provides for IMAP
+ *
+ * @version $Revision: 24 $
+ * @author Michael Kefeder
+ * @url http://code.google.com/p/rcmail-thunderbird-labels/
+ */
+class thunderbird_labels extends rcube_plugin
+{
+ public $task = 'mail';
+ private $map;
+
+ function init()
+ {
+ $rcmail = rcmail::get_instance();
+ # -- disable plugin when printing message
+ if ($rcmail->action == 'print')
+ return;
+
+ $this->include_script('tb_label.js');
+ $this->add_texts('localization/', true);
+ $this->add_hook('messages_list', array($this, 'read_flags'));
+ $this->add_hook('message_load', array($this, 'read_single_flags'));
+ $this->add_hook('template_object_messageheaders', array($this, 'color_headers'));
+ $this->add_hook('render_page', array($this, 'tb_label_popup'));
+ $this->include_stylesheet($this->local_skin_path() . '/tb_label.css');
+
+ $this->name = get_class($this);
+ $this->prefs = array('show_labels' => true);
+ # -- additional TB flags
+ $this->add_tb_flags = array(
+ 'LABEL1' => '$Label1',
+ 'LABEL2' => '$Label2',
+ 'LABEL3' => '$Label3',
+ 'LABEL4' => '$Label4',
+ 'LABEL5' => '$Label5',
+ );
+ $this->message_tb_labels = array();
+
+ $this->add_button(
+ array(
+ 'command' => 'plugin.thunderbird_labels.rcm_tb_label_submenu',
+ 'id' => 'tb_label_popuplink',
+ 'title' => 'label', # gets translated
+ 'domain' => $this->ID,
+ 'type' => 'link',
+ 'content' => ' ', # maybe put translated version of "Labels" here?
+ 'class' => ($rcmail->config->get('skin') == 'larry') ? 'button' : 'tb_noclass',
+ ),
+ 'toolbar'
+ );
+
+ $this->register_action('plugin.thunderbird_labels.set_flags', array($this, 'set_flags'));
+
+
+ if (method_exists($this, 'require_plugin')
+ && in_array('contextmenu', $rcmail->config->get('plugins'))
+ && $this->require_plugin('contextmenu'))
+ {
+ if ($rcmail->action == '')
+ $this->add_hook('render_mailboxlist', array($this, 'show_tb_label_contextmenu'));
+ }
+ }
+
+ public function show_tb_label_contextmenu($args)
+ {
+ $rcmail = rcmail::get_instance();
+ $this->add_texts('localization/');
+ #$this->api->output->add_label('copymessage.copyingmessage');
+
+ $li = html::tag('li', array('class' => 'submenu'), Q($this->gettext('label')) . $this->_gen_label_submenu($args, 'tb_label_ctxm_submenu'));
+ $out .= html::tag('ul', array('id' => 'tb_label_ctxm_mainmenu'), $li);
+ $this->api->output->add_footer(html::div(array('style' => 'display: none;'), $out));
+ }
+
+ private function _gen_label_submenu($args, $id)
+ {
+ $rcmail = rcmail::get_instance();
+ $out = '';
+ for ($i = 0; $i < 6; $i++)
+ {
+ $separator = ($i == 0)? ' separator_below' :'';
+ $out .= '<li class="label'.$i.$separator.' ctxm_tb_label"><a href="#ctxm_tb_label" class="active" onclick="rcmail_ctxm_label_set('.$i.')">'.$i.' '.$this->gettext('label'.$i).'</a></li>';
+ }
+ $out = html::tag('ul', array('class' => 'popupmenu toolbarmenu folders', 'id' => $id), $out);
+ return $out;
+ }
+
+ public function read_single_flags($args)
+ {
+ #write_log($this->name, print_r(($args['object']), true));
+ if (!count($this->prefs)
+ or !isset($args['object'])
+ )
+ return;
+
+ if (is_array($args['object']->headers->flags))
+ {
+ $this->message_tb_labels = array();
+ foreach ($args['object']->headers->flags as $flagname => $flagvalue)
+ {
+ $flag = is_numeric("$flagvalue")? $flagname:$flagvalue;// for compatibility with < 0.5.4
+ $flag = strtolower($flag);
+ if (preg_match('/^\$?label/', $flag))
+ {
+ $flag_no = preg_replace('/^\$?label/', '', $flag);
+ #write_log($this->name, "Single message Flag: ".$flag." Flag_no:".$flag_no);
+ $this->message_tb_labels[] = (int)$flag_no;
+ }
+ }
+ }
+ # -- no return value for this hook
+ }
+
+ /**
+ * Writes labelnumbers for single message display
+ * Coloring of Message header table happens via Javascript
+ */
+ public function color_headers($p)
+ {
+ #write_log($this->name, print_r($p, true));
+ # -- always write array, even when empty
+ $p['content'] .= '<script type="text/javascript">
+ var tb_labels_for_message = ['.join(',', $this->message_tb_labels).'];
+ </script>';
+ return $p;
+ }
+
+ public function read_flags($args)
+ {
+ #write_log($this->name, print_r($args, true));
+ // add color information for all messages
+ #$rcmail = rcmail::get_instance();
+ #$this->prefs = $rcmail->config->get('thunderbird_labels', array());
+ // dont loop over all messages if we dont have any highlights or no msgs
+ if (!count($this->prefs)
+ or !isset($args['messages'])
+ or !is_array($args['messages']))
+ return $args;
+
+ // loop over all messages and add $LabelX info to the extra_flags
+ foreach($args['messages'] as $message)
+ {
+ #write_log($this->name, print_r($message->flags, true));
+ $message->list_flags['extra_flags']['tb_labels'] = array(); # always set extra_flags, needed for javascript later!
+ if (is_array($message->flags))
+ foreach ($message->flags as $flagname => $flagvalue)
+ {
+ $flag = is_numeric("$flagvalue")? $flagname:$flagvalue;// for compatibility with < 0.5.4
+ $flag = strtolower($flag);
+ if (preg_match('/^\$?label/', $flag))
+ {
+ $flag_no = preg_replace('/^\$?label/', '', $flag);
+ #write_log($this->name, "Flag:".$flag." Flag_no:".$flag_no);
+ $message->list_flags['extra_flags']['tb_labels'][] = (int)$flag_no;
+ }
+ }
+ }
+ return($args);
+ }
+
+ function set_flags()
+ {
+ #write_log($this->name, print_r($_GET, true));
+
+ $rcmail = rcmail::get_instance();
+ $imap = $rcmail->imap;
+ $cbox = get_input_value('_cur', RCUBE_INPUT_GET);
+ $mbox = get_input_value('_mbox', RCUBE_INPUT_GET);
+ $toggle_label = get_input_value('_toggle_label', RCUBE_INPUT_GET);
+ $flag_uids = get_input_value('_flag_uids', RCUBE_INPUT_GET);
+ $flag_uids = explode(',', $flag_uids);
+ $unflag_uids = get_input_value('_unflag_uids', RCUBE_INPUT_GET);
+ $unflag_uids = explode(',', $unflag_uids);
+
+ $imap->conn->flags = array_merge($imap->conn->flags, $this->add_tb_flags);
+
+ #write_log($this->name, print_r($flag_uids, true));
+ #write_log($this->name, print_r($unflag_uids, true));
+
+ if (!is_array($unflag_uids)
+ || !is_array($flag_uids))
+ return false;
+
+ $imap->set_flag($flag_uids, $toggle_label, $mbox);
+ $imap->set_flag($unflag_uids, "UN$toggle_label", $mbox);
+
+ $this->api->output->send();
+ }
+
+ function tb_label_popup()
+ {
+ $rcmail = rcmail::get_instance();
+ $out = '<div id="tb_label_popup" class="popupmenu">
+ <ul class="toolbarmenu">';
+ for ($i = 0; $i < 6; $i++)
+ {
+ $separator = ($i == 0)? ' separator_below' :'';
+ $out .= '<li class="label'.$i.$separator.'"><a href="#" class="active">'.$i.' '.$this->gettext('label'.$i).'</a></li>';
+ }
+ $out .= '</ul>
+ </div>';
+ $rcmail->output->add_gui_object('tb_label_popup_obj', 'tb_label_popup');
+ $rcmail->output->add_footer($out);
+ }
+}
+?>