summaryrefslogtreecommitdiff
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
parentef14bd0d8d58ae0f57aa1969e31a5373aa441dba (diff)
Updates / Plugins
-rw-r--r--index.php2
-rw-r--r--main.inc.php.dist893
-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
-rw-r--r--program/localization/en_US/labels.inc.orig537
-rw-r--r--program/steps/mail/func.inc.orig1964
-rw-r--r--program/steps/mail/show.inc.orig315
346 files changed, 27403 insertions, 1 deletions
diff --git a/index.php b/index.php
index 1719abc48..727c66163 100644
--- a/index.php
+++ b/index.php
@@ -2,7 +2,7 @@
/*
+-------------------------------------------------------------------------+
| Roundcube Webmail IMAP Client |
- | Version 1.0-git |
+ | Version 0.9.2 |
| |
| Copyright (C) 2005-2013, The Roundcube Dev Team |
| |
diff --git a/main.inc.php.dist b/main.inc.php.dist
new file mode 100644
index 000000000..11297155f
--- /dev/null
+++ b/main.inc.php.dist
@@ -0,0 +1,893 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | Main configuration file |
+ | |
+ | This file is part of the Roundcube Webmail client |
+ | Copyright (C) 2005-2011, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+*/
+
+$rcmail_config = array();
+
+// ----------------------------------
+// LOGGING/DEBUGGING
+// ----------------------------------
+
+// system error reporting, sum of: 1 = log; 4 = show, 8 = trace
+$rcmail_config['debug_level'] = 1;
+
+// log driver: 'syslog' or 'file'.
+$rcmail_config['log_driver'] = 'file';
+
+// date format for log entries
+// (read http://php.net/manual/en/function.date.php for all format characters)
+$rcmail_config['log_date_format'] = 'd-M-Y H:i:s O';
+
+// Syslog ident string to use, if using the 'syslog' log driver.
+$rcmail_config['syslog_id'] = 'roundcube';
+
+// Syslog facility to use, if using the 'syslog' log driver.
+// For possible values see installer or http://php.net/manual/en/function.openlog.php
+$rcmail_config['syslog_facility'] = LOG_USER;
+
+// Log sent messages to <log_dir>/sendmail or to syslog
+$rcmail_config['smtp_log'] = true;
+
+// Log successful logins to <log_dir>/userlogins or to syslog
+$rcmail_config['log_logins'] = false;
+
+// Log session authentication errors to <log_dir>/session or to syslog
+$rcmail_config['log_session'] = false;
+
+// Log SQL queries to <log_dir>/sql or to syslog
+$rcmail_config['sql_debug'] = false;
+
+// Log IMAP conversation to <log_dir>/imap or to syslog
+$rcmail_config['imap_debug'] = false;
+
+// Log LDAP conversation to <log_dir>/ldap or to syslog
+$rcmail_config['ldap_debug'] = false;
+
+// Log SMTP conversation to <log_dir>/smtp or to syslog
+$rcmail_config['smtp_debug'] = false;
+
+// ----------------------------------
+// IMAP
+// ----------------------------------
+
+// The mail host chosen to perform the log-in.
+// Leave blank to show a textbox at login, give a list of hosts
+// to display a pulldown menu or set one host as string.
+// To use SSL/TLS connection, enter hostname with prefix ssl:// or tls://
+// Supported replacement variables:
+// %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
+// WARNING: After hostname change update of mail_host column in users table is
+// required to match old user data records with the new host.
+$rcmail_config['default_host'] = '';
+
+// TCP port used for IMAP connections
+$rcmail_config['default_port'] = 143;
+
+// IMAP AUTH type (DIGEST-MD5, CRAM-MD5, LOGIN, PLAIN or null to use
+// best server supported one)
+$rcmail_config['imap_auth_type'] = null;
+
+// If you know your imap's folder delimiter, you can specify it here.
+// Otherwise it will be determined automatically
+$rcmail_config['imap_delimiter'] = null;
+
+// If IMAP server doesn't support NAMESPACE extension, but you're
+// using shared folders or personal root folder is non-empty, you'll need to
+// set these options. All can be strings or arrays of strings.
+// Folders need to be ended with directory separator, e.g. "INBOX."
+// (special directory "~" is an exception to this rule)
+// These can be used also to overwrite server's namespaces
+$rcmail_config['imap_ns_personal'] = null;
+$rcmail_config['imap_ns_other'] = null;
+$rcmail_config['imap_ns_shared'] = null;
+
+// By default IMAP capabilities are readed after connection to IMAP server
+// In some cases, e.g. when using IMAP proxy, there's a need to refresh the list
+// after login. Set to True if you've got this case.
+$rcmail_config['imap_force_caps'] = false;
+
+// By default list of subscribed folders is determined using LIST-EXTENDED
+// extension if available. Some servers (dovecot 1.x) returns wrong results
+// for shared namespaces in this case. http://trac.roundcube.net/ticket/1486225
+// Enable this option to force LSUB command usage instead.
+$rcmail_config['imap_force_lsub'] = false;
+
+// Some server configurations (e.g. Courier) doesn't list folders in all namespaces
+// Enable this option to force listing of folders in all namespaces
+$rcmail_config['imap_force_ns'] = false;
+
+// IMAP connection timeout, in seconds. Default: 0 (no limit)
+$rcmail_config['imap_timeout'] = 0;
+
+// Optional IMAP authentication identifier to be used as authorization proxy
+$rcmail_config['imap_auth_cid'] = null;
+
+// Optional IMAP authentication password to be used for imap_auth_cid
+$rcmail_config['imap_auth_pw'] = null;
+
+// Type of IMAP indexes cache. Supported values: 'db', 'apc' and 'memcache'.
+$rcmail_config['imap_cache'] = null;
+
+// Enables messages cache. Only 'db' cache is supported.
+$rcmail_config['messages_cache'] = false;
+
+
+// ----------------------------------
+// SMTP
+// ----------------------------------
+
+// SMTP server host (for sending mails).
+// To use SSL/TLS connection, enter hostname with prefix ssl:// or tls://
+// If left blank, the PHP mail() function is used
+// Supported replacement variables:
+// %h - user's IMAP hostname
+// %n - hostname ($_SERVER['SERVER_NAME'])
+// %t - hostname without the first part
+// %d - domain (http hostname $_SERVER['HTTP_HOST'] without the first part)
+// %z - IMAP domain (IMAP hostname without the first part)
+// For example %n = mail.domain.tld, %t = domain.tld
+$rcmail_config['smtp_server'] = '';
+
+// SMTP port (default is 25; use 587 for STARTTLS or 465 for the
+// deprecated SSL over SMTP (aka SMTPS))
+$rcmail_config['smtp_port'] = 25;
+
+// SMTP username (if required) if you use %u as the username Roundcube
+// will use the current username for login
+$rcmail_config['smtp_user'] = '';
+
+// SMTP password (if required) if you use %p as the password Roundcube
+// will use the current user's password for login
+$rcmail_config['smtp_pass'] = '';
+
+// SMTP AUTH type (DIGEST-MD5, CRAM-MD5, LOGIN, PLAIN or empty to use
+// best server supported one)
+$rcmail_config['smtp_auth_type'] = '';
+
+// Optional SMTP authentication identifier to be used as authorization proxy
+$rcmail_config['smtp_auth_cid'] = null;
+
+// Optional SMTP authentication password to be used for smtp_auth_cid
+$rcmail_config['smtp_auth_pw'] = null;
+
+// SMTP HELO host
+// Hostname to give to the remote server for SMTP 'HELO' or 'EHLO' messages
+// Leave this blank and you will get the server variable 'server_name' or
+// localhost if that isn't defined.
+$rcmail_config['smtp_helo_host'] = '';
+
+// SMTP connection timeout, in seconds. Default: 0 (no limit)
+$rcmail_config['smtp_timeout'] = 0;
+
+// ----------------------------------
+// SYSTEM
+// ----------------------------------
+
+// THIS OPTION WILL ALLOW THE INSTALLER TO RUN AND CAN EXPOSE SENSITIVE CONFIG DATA.
+// ONLY ENABLE IT IF YOU'RE REALLY SURE WHAT YOU'RE DOING!
+$rcmail_config['enable_installer'] = false;
+
+// don't allow these settings to be overriden by the user
+$rcmail_config['dont_override'] = array();
+
+// provide an URL where a user can get support for this Roundcube installation
+// PLEASE DO NOT LINK TO THE ROUNDCUBE.NET WEBSITE HERE!
+$rcmail_config['support_url'] = '';
+
+// replace Roundcube logo with this image
+// specify an URL relative to the document root of this Roundcube installation
+$rcmail_config['skin_logo'] = null;
+
+// automatically create a new Roundcube user when log-in the first time.
+// a new user will be created once the IMAP login succeeds.
+// set to false if only registered users can use this service
+$rcmail_config['auto_create_user'] = true;
+
+// Enables possibility to log in using email address from user identities
+$rcmail_config['user_aliases'] = false;
+
+// use this folder to store log files (must be writeable for apache user)
+// This is used by the 'file' log driver.
+$rcmail_config['log_dir'] = 'logs/';
+
+// use this folder to store temp files (must be writeable for apache user)
+$rcmail_config['temp_dir'] = 'temp/';
+
+// lifetime of message cache
+// possible units: s, m, h, d, w
+$rcmail_config['message_cache_lifetime'] = '10d';
+
+// enforce connections over https
+// with this option enabled, all non-secure connections will be redirected.
+// set the port for the ssl connection as value of this option if it differs from the default 443
+$rcmail_config['force_https'] = false;
+
+// tell PHP that it should work as under secure connection
+// even if it doesn't recognize it as secure ($_SERVER['HTTPS'] is not set)
+// e.g. when you're running Roundcube behind a https proxy
+// this option is mutually exclusive to 'force_https' and only either one of them should be set to true.
+$rcmail_config['use_https'] = false;
+
+// Allow browser-autocompletion on login form.
+// 0 - disabled, 1 - username and host only, 2 - username, host, password
+$rcmail_config['login_autocomplete'] = 0;
+
+// Forces conversion of logins to lower case.
+// 0 - disabled, 1 - only domain part, 2 - domain and local part.
+// If users authentication is case-insensitive this must be enabled.
+// Note: After enabling it all user records need to be updated, e.g. with query:
+// UPDATE users SET username = LOWER(username);
+$rcmail_config['login_lc'] = 2;
+
+// Includes should be interpreted as PHP files
+$rcmail_config['skin_include_php'] = false;
+
+// display software version on login screen
+$rcmail_config['display_version'] = false;
+
+// Session lifetime in minutes
+$rcmail_config['session_lifetime'] = 10;
+
+// Session domain: .example.org
+$rcmail_config['session_domain'] = '';
+
+// Session name. Default: 'roundcube_sessid'
+$rcmail_config['session_name'] = null;
+
+// Session path. Defaults to PHP session.cookie_path setting.
+$rcmail_config['session_path'] = null;
+
+// Backend to use for session storage. Can either be 'db' (default) or 'memcache'
+// If set to memcache, a list of servers need to be specified in 'memcache_hosts'
+// Make sure the Memcache extension (http://pecl.php.net/package/memcache) version >= 2.0.0 is installed
+$rcmail_config['session_storage'] = 'db';
+
+// Use these hosts for accessing memcached
+// Define any number of hosts in the form of hostname:port or unix:///path/to/socket.file
+$rcmail_config['memcache_hosts'] = null; // e.g. array( 'localhost:11211', '192.168.1.12:11211', 'unix:///var/tmp/memcached.sock' );
+
+// check client IP in session athorization
+$rcmail_config['ip_check'] = false;
+
+// check referer of incoming requests
+$rcmail_config['referer_check'] = false;
+
+// X-Frame-Options HTTP header value sent to prevent from Clickjacking.
+// Possible values: sameorigin|deny. Set to false in order to disable sending them
+$rcmail_config['x_frame_options'] = 'sameorigin';
+
+// this key is used to encrypt the users imap password which is stored
+// in the session record (and the client cookie if remember password is enabled).
+// please provide a string of exactly 24 chars.
+$rcmail_config['des_key'] = 'rcmail-!24ByteDESkey*Str';
+
+// Automatically add this domain to user names for login
+// Only for IMAP servers that require full e-mail addresses for login
+// Specify an array with 'host' => 'domain' values to support multiple hosts
+// Supported replacement variables:
+// %h - user's IMAP hostname
+// %n - hostname ($_SERVER['SERVER_NAME'])
+// %t - hostname without the first part
+// %d - domain (http hostname $_SERVER['HTTP_HOST'] without the first part)
+// %z - IMAP domain (IMAP hostname without the first part)
+// For example %n = mail.domain.tld, %t = domain.tld
+$rcmail_config['username_domain'] = '';
+
+// This domain will be used to form e-mail addresses of new users
+// Specify an array with 'host' => 'domain' values to support multiple hosts
+// Supported replacement variables:
+// %h - user's IMAP hostname
+// %n - http hostname ($_SERVER['SERVER_NAME'])
+// %d - domain (http hostname without the first part)
+// %z - IMAP domain (IMAP hostname without the first part)
+// For example %n = mail.domain.tld, %t = domain.tld
+$rcmail_config['mail_domain'] = '';
+
+// Password charset.
+// Use it if your authentication backend doesn't support UTF-8.
+// Defaults to ISO-8859-1 for backward compatibility
+$rcmail_config['password_charset'] = 'ISO-8859-1';
+
+// How many seconds must pass between emails sent by a user
+$rcmail_config['sendmail_delay'] = 0;
+
+// Maximum number of recipients per message. Default: 0 (no limit)
+$rcmail_config['max_recipients'] = 0;
+
+// Maximum allowednumber of members of an address group. Default: 0 (no limit)
+// If 'max_recipients' is set this value should be less or equal
+$rcmail_config['max_group_members'] = 0;
+
+// add this user-agent to message headers when sending
+$rcmail_config['useragent'] = 'Roundcube Webmail/'.RCMAIL_VERSION;
+
+// use this name to compose page titles
+$rcmail_config['product_name'] = 'Roundcube Webmail';
+
+// try to load host-specific configuration
+// see http://trac.roundcube.net/wiki/Howto_Config for more details
+$rcmail_config['include_host_config'] = false;
+
+// path to a text file which will be added to each sent message
+// paths are relative to the Roundcube root folder
+$rcmail_config['generic_message_footer'] = '';
+
+// path to a text file which will be added to each sent HTML message
+// paths are relative to the Roundcube root folder
+$rcmail_config['generic_message_footer_html'] = '';
+
+// add a received header to outgoing mails containing the creators IP and hostname
+$rcmail_config['http_received_header'] = false;
+
+// Whether or not to encrypt the IP address and the host name
+// these could, in some circles, be considered as sensitive information;
+// however, for the administrator, these could be invaluable help
+// when tracking down issues.
+$rcmail_config['http_received_header_encrypt'] = false;
+
+// This string is used as a delimiter for message headers when sending
+// a message via mail() function. Leave empty for auto-detection
+$rcmail_config['mail_header_delimiter'] = NULL;
+
+// number of chars allowed for line when wrapping text.
+// text wrapping is done when composing/sending messages
+$rcmail_config['line_length'] = 72;
+
+// send plaintext messages as format=flowed
+$rcmail_config['send_format_flowed'] = true;
+
+// According to RFC2298, return receipt envelope sender address must be empty.
+// If this option is true, Roundcube will use user's identity as envelope sender for MDN responses.
+$rcmail_config['mdn_use_from'] = false;
+
+// Set identities access level:
+// 0 - many identities with possibility to edit all params
+// 1 - many identities with possibility to edit all params but not email address
+// 2 - one identity with possibility to edit all params
+// 3 - one identity with possibility to edit all params but not email address
+// 4 - one identity with possibility to edit only signature
+$rcmail_config['identities_level'] = 0;
+
+// Mimetypes supported by the browser.
+// attachments of these types will open in a preview window
+// either a comma-separated list or an array: 'text/plain,text/html,text/xml,image/jpeg,image/gif,image/png,application/pdf'
+$rcmail_config['client_mimetypes'] = null; # null == default
+
+// Path to a local mime magic database file for PHPs finfo extension.
+// Set to null if the default path should be used.
+$rcmail_config['mime_magic'] = null;
+
+// Absolute path to a local mime.types mapping table file.
+// This is used to derive mime-types from the filename extension or vice versa.
+// Such a file is usually part of the apache webserver. If you don't find a file named mime.types on your system,
+// download it from http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
+$rcmail_config['mime_types'] = null;
+
+// path to imagemagick identify binary
+$rcmail_config['im_identify_path'] = null;
+
+// path to imagemagick convert binary
+$rcmail_config['im_convert_path'] = null;
+
+// Size of thumbnails from image attachments displayed below the message content.
+// Note: whether images are displayed at all depends on the 'inline_images' option.
+// Set to 0 to display images in full size.
+$rcmail_config['image_thumbnail_size'] = 240;
+
+// maximum size of uploaded contact photos in pixel
+$rcmail_config['contact_photo_size'] = 160;
+
+// Enable DNS checking for e-mail address validation
+$rcmail_config['email_dns_check'] = false;
+
+// Disables saving sent messages in Sent folder (like gmail) (Default: false)
+// Note: useful when SMTP server stores sent mail in user mailbox
+$rcmail_config['no_save_sent_messages'] = false;
+
+// ----------------------------------
+// PLUGINS
+// ----------------------------------
+
+// List of active plugins (in plugins/ directory)
+$rcmail_config['plugins'] = array();
+
+// ----------------------------------
+// USER INTERFACE
+// ----------------------------------
+
+// default messages sort column. Use empty value for default server's sorting,
+// or 'arrival', 'date', 'subject', 'from', 'to', 'fromto', 'size', 'cc'
+$rcmail_config['message_sort_col'] = '';
+
+// default messages sort order
+$rcmail_config['message_sort_order'] = 'DESC';
+
+// These cols are shown in the message list. Available cols are:
+// subject, from, to, fromto, cc, replyto, date, size, status, flag, attachment, 'priority'
+$rcmail_config['list_cols'] = array('subject', 'status', 'fromto', 'date', 'size', 'flag', 'attachment');
+
+// the default locale setting (leave empty for auto-detection)
+// RFC1766 formatted language name like en_US, de_DE, de_CH, fr_FR, pt_BR
+$rcmail_config['language'] = null;
+
+// use this format for date display (date or strftime format)
+$rcmail_config['date_format'] = 'Y-m-d';
+
+// give this choice of date formats to the user to select from
+$rcmail_config['date_formats'] = array('Y-m-d', 'd-m-Y', 'Y/m/d', 'm/d/Y', 'd/m/Y', 'd.m.Y', 'j.n.Y');
+
+// use this format for time display (date or strftime format)
+$rcmail_config['time_format'] = 'H:i';
+
+// give this choice of time formats to the user to select from
+$rcmail_config['time_formats'] = array('G:i', 'H:i', 'g:i a', 'h:i A');
+
+// use this format for short date display (derived from date_format and time_format)
+$rcmail_config['date_short'] = 'D H:i';
+
+// use this format for detailed date/time formatting (derived from date_format and time_format)
+$rcmail_config['date_long'] = 'Y-m-d H:i';
+
+// store draft message is this mailbox
+// leave blank if draft messages should not be stored
+// NOTE: Use folder names with namespace prefix (INBOX. on Courier-IMAP)
+$rcmail_config['drafts_mbox'] = 'Drafts';
+
+// store spam messages in this mailbox
+// NOTE: Use folder names with namespace prefix (INBOX. on Courier-IMAP)
+$rcmail_config['junk_mbox'] = 'Junk';
+
+// store sent message is this mailbox
+// leave blank if sent messages should not be stored
+// NOTE: Use folder names with namespace prefix (INBOX. on Courier-IMAP)
+$rcmail_config['sent_mbox'] = 'Sent';
+
+// move messages to this folder when deleting them
+// leave blank if they should be deleted directly
+// NOTE: Use folder names with namespace prefix (INBOX. on Courier-IMAP)
+$rcmail_config['trash_mbox'] = 'Trash';
+
+// display these folders separately in the mailbox list.
+// these folders will also be displayed with localized names
+// NOTE: Use folder names with namespace prefix (INBOX. on Courier-IMAP)
+$rcmail_config['default_folders'] = array('INBOX', 'Drafts', 'Sent', 'Junk', 'Trash');
+
+// automatically create the above listed default folders on first login
+$rcmail_config['create_default_folders'] = false;
+
+// protect the default folders from renames, deletes, and subscription changes
+$rcmail_config['protect_default_folders'] = true;
+
+// if in your system 0 quota means no limit set this option to true
+$rcmail_config['quota_zero_as_unlimited'] = false;
+
+// Make use of the built-in spell checker. It is based on GoogieSpell.
+// Since Google only accepts connections over https your PHP installatation
+// requires to be compiled with Open SSL support
+$rcmail_config['enable_spellcheck'] = true;
+
+// Enables spellchecker exceptions dictionary.
+// Setting it to 'shared' will make the dictionary shared by all users.
+$rcmail_config['spellcheck_dictionary'] = false;
+
+// Set the spell checking engine. 'googie' is the default. 'pspell' is also available,
+// but requires the Pspell extensions. When using Nox Spell Server, also set 'googie' here.
+$rcmail_config['spellcheck_engine'] = 'pspell';
+
+// For a locally installed Nox Spell Server, please specify the URI to call it.
+// Get Nox Spell Server from http://orangoo.com/labs/?page_id=72
+// Leave empty to use the Google spell checking service, what means
+// that the message content will be sent to Google in order to check spelling
+$rcmail_config['spellcheck_uri'] = '';
+
+// These languages can be selected for spell checking.
+// Configure as a PHP style hash array: array('en'=>'English', 'de'=>'Deutsch');
+// Leave empty for default set of available language.
+$rcmail_config['spellcheck_languages'] = NULL;
+
+// Makes that words with all letters capitalized will be ignored (e.g. GOOGLE)
+$rcmail_config['spellcheck_ignore_caps'] = false;
+
+// Makes that words with numbers will be ignored (e.g. g00gle)
+$rcmail_config['spellcheck_ignore_nums'] = false;
+
+// Makes that words with symbols will be ignored (e.g. g@@gle)
+$rcmail_config['spellcheck_ignore_syms'] = false;
+
+// Use this char/string to separate recipients when composing a new message
+$rcmail_config['recipients_separator'] = ',';
+
+// don't let users set pagesize to more than this value if set
+$rcmail_config['max_pagesize'] = 200;
+
+// Minimal value of user's 'refresh_interval' setting (in seconds)
+$rcmail_config['min_refresh_interval'] = 60;
+
+// Enables files upload indicator. Requires APC installed and enabled apc.rfc1867 option.
+// By default refresh time is set to 1 second. You can set this value to true
+// or any integer value indicating number of seconds.
+$rcmail_config['upload_progress'] = false;
+
+// Specifies for how many seconds the Undo button will be available
+// after object delete action. Currently used with supporting address book sources.
+// Setting it to 0, disables the feature.
+$rcmail_config['undo_timeout'] = 0;
+
+// ----------------------------------
+// ADDRESSBOOK SETTINGS
+// ----------------------------------
+
+// This indicates which type of address book to use. Possible choises:
+// 'sql' (default), 'ldap' and ''.
+// If set to 'ldap' then it will look at using the first writable LDAP
+// address book as the primary address book and it will not display the
+// SQL address book in the 'Address Book' view.
+// If set to '' then no address book will be displayed or only the
+// addressbook which is created by a plugin (like CardDAV).
+$rcmail_config['address_book_type'] = 'sql';
+
+// In order to enable public ldap search, configure an array like the Verisign
+// example further below. if you would like to test, simply uncomment the example.
+// Array key must contain only safe characters, ie. a-zA-Z0-9_
+$rcmail_config['ldap_public'] = array();
+
+// If you are going to use LDAP for individual address books, you will need to
+// set 'user_specific' to true and use the variables to generate the appropriate DNs to access it.
+//
+// The recommended directory structure for LDAP is to store all the address book entries
+// under the users main entry, e.g.:
+//
+// o=root
+// ou=people
+// uid=user@domain
+// mail=contact@contactdomain
+//
+// So the base_dn would be uid=%fu,ou=people,o=root
+// The bind_dn would be the same as based_dn or some super user login.
+/*
+ * example config for Verisign directory
+ *
+$rcmail_config['ldap_public']['Verisign'] = array(
+ 'name' => 'Verisign.com',
+ // Replacement variables supported in host names:
+ // %h - user's IMAP hostname
+ // %n - hostname ($_SERVER['SERVER_NAME'])
+ // %t - hostname without the first part
+ // %d - domain (http hostname $_SERVER['HTTP_HOST'] without the first part)
+ // %z - IMAP domain (IMAP hostname without the first part)
+ // For example %n = mail.domain.tld, %t = domain.tld
+ 'hosts' => array('directory.verisign.com'),
+ 'port' => 389,
+ 'use_tls' => false,
+ 'ldap_version' => 3, // using LDAPv3
+ 'network_timeout' => 10, // The timeout (in seconds) for connect + bind arrempts. This is only supported in PHP >= 5.3.0 with OpenLDAP 2.x
+ 'user_specific' => false, // If true the base_dn, bind_dn and bind_pass default to the user's IMAP login.
+ // %fu - The full username provided, assumes the username is an email
+ // address, uses the username_domain value if not an email address.
+ // %u - The username prior to the '@'.
+ // %d - The domain name after the '@'.
+ // %dc - The domain name hierarchal string e.g. "dc=test,dc=domain,dc=com"
+ // %dn - DN found by ldap search when search_filter/search_base_dn are used
+ 'base_dn' => '',
+ 'bind_dn' => '',
+ 'bind_pass' => '',
+ // It's possible to bind for an individual address book
+ // The login name is used to search for the DN to bind with
+ 'search_base_dn' => '',
+ 'search_filter' => '', // e.g. '(&(objectClass=posixAccount)(uid=%u))'
+ // DN and password to bind as before searching for bind DN, if anonymous search is not allowed
+ 'search_bind_dn' => '',
+ 'search_bind_pw' => '',
+ // Default for %dn variable if search doesn't return DN value
+ 'search_dn_default' => '',
+ // Optional authentication identifier to be used as SASL authorization proxy
+ // bind_dn need to be empty
+ 'auth_cid' => '',
+ // SASL authentication method (for proxy auth), e.g. DIGEST-MD5
+ 'auth_method' => '',
+ // Indicates if the addressbook shall be hidden from the list.
+ // With this option enabled you can still search/view contacts.
+ 'hidden' => false,
+ // Indicates if the addressbook shall not list contacts but only allows searching.
+ 'searchonly' => false,
+ // Indicates if we can write to the LDAP directory or not.
+ // If writable is true then these fields need to be populated:
+ // LDAP_Object_Classes, required_fields, LDAP_rdn
+ 'writable' => false,
+ // To create a new contact these are the object classes to specify
+ // (or any other classes you wish to use).
+ 'LDAP_Object_Classes' => array('top', 'inetOrgPerson'),
+ // The RDN field that is used for new entries, this field needs
+ // to be one of the search_fields, the base of base_dn is appended
+ // to the RDN to insert into the LDAP directory.
+ 'LDAP_rdn' => 'cn',
+ // The required fields needed to build a new contact as required by
+ // the object classes (can include additional fields not required by the object classes).
+ 'required_fields' => array('cn', 'sn', 'mail'),
+ 'search_fields' => array('mail', 'cn'), // fields to search in
+ // mapping of contact fields to directory attributes
+ // for every attribute one can specify the number of values (limit) allowed.
+ // default is 1, a wildcard * means unlimited
+ 'fieldmap' => array(
+ // Roundcube => LDAP:limit
+ 'name' => 'cn',
+ 'surname' => 'sn',
+ 'firstname' => 'givenName',
+ 'jobtitle' => 'title',
+ 'email' => 'mail:*',
+ 'phone:home' => 'homePhone',
+ 'phone:work' => 'telephoneNumber',
+ 'phone:mobile' => 'mobile',
+ 'phone:pager' => 'pager',
+ 'street' => 'street',
+ 'zipcode' => 'postalCode',
+ 'region' => 'st',
+ 'locality' => 'l',
+ // if you country is a complex object, you need to configure 'sub_fields' below
+ 'country' => 'c',
+ 'organization' => 'o',
+ 'department' => 'ou',
+ 'jobtitle' => 'title',
+ 'notes' => 'description',
+ // these currently don't work:
+ // 'phone:workfax' => 'facsimileTelephoneNumber',
+ // 'photo' => 'jpegPhoto',
+ // 'manager' => 'manager',
+ // 'assistant' => 'secretary',
+ ),
+ // Map of contact sub-objects (attribute name => objectClass(es)), e.g. 'c' => 'country'
+ 'sub_fields' => array(),
+ // Generate values for the following LDAP attributes automatically when creating a new record
+ 'autovalues' => array(
+ // 'uid' => 'md5(microtime())', // You may specify PHP code snippets which are then eval'ed
+ // 'mail' => '{givenname}.{sn}@mydomain.com', // or composite strings with placeholders for existing attributes
+ ),
+ 'sort' => 'cn', // The field to sort the listing by.
+ 'scope' => 'sub', // search mode: sub|base|list
+ 'filter' => '(objectClass=inetOrgPerson)', // used for basic listing (if not empty) and will be &'d with search queries. example: status=act
+ 'fuzzy_search' => true, // server allows wildcard search
+ 'vlv' => false, // Enable Virtual List View to more efficiently fetch paginated data (if server supports it)
+ 'numsub_filter' => '(objectClass=organizationalUnit)', // with VLV, we also use numSubOrdinates to query the total number of records. Set this filter to get all numSubOrdinates attributes for counting
+ 'sizelimit' => '0', // Enables you to limit the count of entries fetched. Setting this to 0 means no limit.
+ 'timelimit' => '0', // Sets the number of seconds how long is spend on the search. Setting this to 0 means no limit.
+ 'referrals' => true|false, // Sets the LDAP_OPT_REFERRALS option. Mostly used in multi-domain Active Directory setups
+
+ // definition for contact groups (uncomment if no groups are supported)
+ // for the groups base_dn, the user replacements %fu, %u, $d and %dc work as for base_dn (see above)
+ // if the groups base_dn is empty, the contact base_dn is used for the groups as well
+ // -> in this case, assure that groups and contacts are separated due to the concernig filters!
+ 'groups' => array(
+ 'base_dn' => '',
+ 'scope' => 'sub', // search mode: sub|base|list
+ 'filter' => '(objectClass=groupOfNames)',
+ 'object_classes' => array("top", "groupOfNames"),
+ 'member_attr' => 'member', // name of the member attribute, e.g. uniqueMember
+ 'name_attr' => 'cn', // attribute to be used as group name
+ ),
+);
+*/
+
+// An ordered array of the ids of the addressbooks that should be searched
+// when populating address autocomplete fields server-side. ex: array('sql','Verisign');
+$rcmail_config['autocomplete_addressbooks'] = array('sql');
+
+// The minimum number of characters required to be typed in an autocomplete field
+// before address books will be searched. Most useful for LDAP directories that
+// may need to do lengthy results building given overly-broad searches
+$rcmail_config['autocomplete_min_length'] = 1;
+
+// Number of parallel autocomplete requests.
+// If there's more than one address book, n parallel (async) requests will be created,
+// where each request will search in one address book. By default (0), all address
+// books are searched in one request.
+$rcmail_config['autocomplete_threads'] = 0;
+
+// Max. numer of entries in autocomplete popup. Default: 15.
+$rcmail_config['autocomplete_max'] = 15;
+
+// show address fields in this order
+// available placeholders: {street}, {locality}, {zipcode}, {country}, {region}
+$rcmail_config['address_template'] = '{street}<br/>{locality} {zipcode}<br/>{country} {region}';
+
+// Matching mode for addressbook search (including autocompletion)
+// 0 - partial (*abc*), default
+// 1 - strict (abc)
+// 2 - prefix (abc*)
+// Note: For LDAP sources fuzzy_search must be enabled to use 'partial' or 'prefix' mode
+$rcmail_config['addressbook_search_mode'] = 0;
+
+// ----------------------------------
+// USER PREFERENCES
+// ----------------------------------
+
+// Use this charset as fallback for message decoding
+$rcmail_config['default_charset'] = 'UTF-8';
+
+// skin name: folder from skins/
+$rcmail_config['skin'] = 'larry';
+
+// show up to X items in messages list view
+$rcmail_config['mail_pagesize'] = 50;
+
+// show up to X items in contacts list view
+$rcmail_config['addressbook_pagesize'] = 50;
+
+// sort contacts by this col (preferably either one of name, firstname, surname)
+$rcmail_config['addressbook_sort_col'] = 'surname';
+
+// the way how contact names are displayed in the list
+// 0: display name
+// 1: (prefix) firstname middlename surname (suffix)
+// 2: (prefix) surname firstname middlename (suffix)
+// 3: (prefix) surname, firstname middlename (suffix)
+$rcmail_config['addressbook_name_listing'] = 0;
+
+// use this timezone to display date/time
+// valid timezone identifers are listed here: php.net/manual/en/timezones.php
+// 'auto' will use the browser's timezone settings
+$rcmail_config['timezone'] = 'auto';
+
+// prefer displaying HTML messages
+$rcmail_config['prefer_html'] = true;
+
+// display remote inline images
+// 0 - Never, always ask
+// 1 - Ask if sender is not in address book
+// 2 - Always show inline images
+$rcmail_config['show_images'] = 0;
+
+// open messages in new window
+$rcmail_config['message_extwin'] = false;
+
+// open message compose form in new window
+$rcmail_config['compose_extwin'] = false;
+
+// compose html formatted messages by default
+// 0 - never, 1 - always, 2 - on reply to HTML message, 3 - on forward or reply to HTML message
+$rcmail_config['htmleditor'] = 0;
+
+// show pretty dates as standard
+$rcmail_config['prettydate'] = true;
+
+// save compose message every 300 seconds (5min)
+$rcmail_config['draft_autosave'] = 300;
+
+// default setting if preview pane is enabled
+$rcmail_config['preview_pane'] = false;
+
+// Mark as read when viewed in preview pane (delay in seconds)
+// Set to -1 if messages in preview pane should not be marked as read
+$rcmail_config['preview_pane_mark_read'] = 0;
+
+// Clear Trash on logout
+$rcmail_config['logout_purge'] = false;
+
+// Compact INBOX on logout
+$rcmail_config['logout_expunge'] = false;
+
+// Display attached images below the message body
+$rcmail_config['inline_images'] = true;
+
+// Encoding of long/non-ascii attachment names:
+// 0 - Full RFC 2231 compatible
+// 1 - RFC 2047 for 'name' and RFC 2231 for 'filename' parameter (Thunderbird's default)
+// 2 - Full 2047 compatible
+$rcmail_config['mime_param_folding'] = 1;
+
+// Set true if deleted messages should not be displayed
+// This will make the application run slower
+$rcmail_config['skip_deleted'] = false;
+
+// Set true to Mark deleted messages as read as well as deleted
+// False means that a message's read status is not affected by marking it as deleted
+$rcmail_config['read_when_deleted'] = true;
+
+// Set to true to never delete messages immediately
+// Use 'Purge' to remove messages marked as deleted
+$rcmail_config['flag_for_deletion'] = false;
+
+// Default interval for auto-refresh requests (in seconds)
+// These are requests for system state updates e.g. checking for new messages, etc.
+// Setting it to 0 disables the feature.
+$rcmail_config['refresh_interval'] = 60;
+
+// If true all folders will be checked for recent messages
+$rcmail_config['check_all_folders'] = false;
+
+// If true, after message delete/move, the next message will be displayed
+$rcmail_config['display_next'] = true;
+
+// 0 - Do not expand threads
+// 1 - Expand all threads automatically
+// 2 - Expand only threads with unread messages
+$rcmail_config['autoexpand_threads'] = 0;
+
+// When replying:
+// -1 - don't cite the original message
+// 0 - place cursor below the original message
+// 1 - place cursor above original message (top posting)
+$rcmail_config['reply_mode'] = 0;
+
+// When replying strip original signature from message
+$rcmail_config['strip_existing_sig'] = true;
+
+// Show signature:
+// 0 - Never
+// 1 - Always
+// 2 - New messages only
+// 3 - Forwards and Replies only
+$rcmail_config['show_sig'] = 1;
+
+// Use MIME encoding (quoted-printable) for 8bit characters in message body
+$rcmail_config['force_7bit'] = false;
+
+// Defaults of the search field configuration.
+// The array can contain a per-folder list of header fields which should be considered when searching
+// The entry with key '*' stands for all folders which do not have a specific list set.
+// Please note that folder names should to be in sync with $rcmail_config['default_folders']
+$rcmail_config['search_mods'] = null; // Example: array('*' => array('subject'=>1, 'from'=>1), 'Sent' => array('subject'=>1, 'to'=>1));
+
+// Defaults of the addressbook search field configuration.
+$rcmail_config['addressbook_search_mods'] = null; // Example: array('name'=>1, 'firstname'=>1, 'surname'=>1, 'email'=>1, '*'=>1);
+
+// 'Delete always'
+// This setting reflects if mail should be always deleted
+// when moving to Trash fails. This is necessary in some setups
+// when user is over quota and Trash is included in the quota.
+$rcmail_config['delete_always'] = false;
+
+// Directly delete messages in Junk instead of moving to Trash
+$rcmail_config['delete_junk'] = false;
+
+// Behavior if a received message requests a message delivery notification (read receipt)
+// 0 = ask the user, 1 = send automatically, 2 = ignore (never send or ask)
+// 3 = send automatically if sender is in addressbook, otherwise ask the user
+// 4 = send automatically if sender is in addressbook, otherwise ignore
+$rcmail_config['mdn_requests'] = 0;
+
+// Return receipt checkbox default state
+$rcmail_config['mdn_default'] = 0;
+
+// Delivery Status Notification checkbox default state
+$rcmail_config['dsn_default'] = 0;
+
+// Place replies in the folder of the message being replied to
+$rcmail_config['reply_same_folder'] = false;
+
+// Sets default mode of Forward feature to "forward as attachment"
+$rcmail_config['forward_attachment'] = false;
+
+// Defines address book (internal index) to which new contacts will be added
+// By default it is the first writeable addressbook.
+// Note: Use '0' for built-in address book.
+$rcmail_config['default_addressbook'] = null;
+
+// Enables spell checking before sending a message.
+$rcmail_config['spellcheck_before_send'] = false;
+
+// Skip alternative email addresses in autocompletion (show one address per contact)
+$rcmail_config['autocomplete_single'] = false;
+
+// Default font for composed HTML message.
+// Supported values: Andale Mono, Arial, Arial Black, Book Antiqua, Courier New,
+// Georgia, Helvetica, Impact, Tahoma, Terminal, Times New Roman, Trebuchet MS, Verdana
+$rcmail_config['default_font'] = 'Verdana';
+
+// end of config file
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);
+ }
+}
+?>
diff --git a/program/localization/en_US/labels.inc.orig b/program/localization/en_US/labels.inc.orig
new file mode 100644
index 000000000..d49e44b2c
--- /dev/null
+++ b/program/localization/en_US/labels.inc.orig
@@ -0,0 +1,537 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | localization/<lang>/labels.inc |
+ | |
+ | Localization file of the Roundcube Webmail client |
+ | Copyright (C) 2005-2012, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/labels/
+*/
+
+$labels = array();
+
+// login page
+$labels['welcome'] = 'Welcome to $product';
+$labels['username'] = 'Username';
+$labels['password'] = 'Password';
+$labels['server'] = 'Server';
+$labels['login'] = 'Login';
+
+// taskbar
+$labels['logout'] = 'Logout';
+$labels['mail'] = 'Mail';
+$labels['settings'] = 'Settings';
+$labels['addressbook'] = 'Address Book';
+
+// mailbox names
+$labels['inbox'] = 'Inbox';
+$labels['drafts'] = 'Drafts';
+$labels['sent'] = 'Sent';
+$labels['trash'] = 'Trash';
+$labels['junk'] = 'Junk';
+
+// message listing
+$labels['subject'] = 'Subject';
+$labels['from'] = 'From';
+$labels['sender'] = 'Sender';
+$labels['to'] = 'To';
+$labels['cc'] = 'Cc';
+$labels['bcc'] = 'Bcc';
+$labels['replyto'] = 'Reply-To';
+$labels['followupto'] = 'Followup-To';
+$labels['date'] = 'Date';
+$labels['size'] = 'Size';
+$labels['priority'] = 'Priority';
+$labels['organization'] = 'Organization';
+$labels['readstatus'] = 'Read status';
+$labels['listoptions'] = 'List options...';
+
+$labels['mailboxlist'] = 'Folders';
+$labels['messagesfromto'] = 'Messages $from to $to of $count';
+$labels['threadsfromto'] = 'Threads $from to $to of $count';
+$labels['messagenrof'] = 'Message $nr of $count';
+$labels['fromtoshort'] = '$from – $to of $count';
+
+$labels['copy'] = 'Copy';
+$labels['move'] = 'Move';
+$labels['moveto'] = 'Move to...';
+$labels['download'] = 'Download';
+$labels['showattachment'] = 'Show';
+$labels['showanyway'] = 'Show it anyway';
+
+$labels['filename'] = 'File name';
+$labels['filesize'] = 'File size';
+
+$labels['addtoaddressbook'] = 'Add to address book';
+
+// weekdays short
+$labels['sun'] = 'Sun';
+$labels['mon'] = 'Mon';
+$labels['tue'] = 'Tue';
+$labels['wed'] = 'Wed';
+$labels['thu'] = 'Thu';
+$labels['fri'] = 'Fri';
+$labels['sat'] = 'Sat';
+
+// weekdays long
+$labels['sunday'] = 'Sunday';
+$labels['monday'] = 'Monday';
+$labels['tuesday'] = 'Tuesday';
+$labels['wednesday'] = 'Wednesday';
+$labels['thursday'] = 'Thursday';
+$labels['friday'] = 'Friday';
+$labels['saturday'] = 'Saturday';
+
+// months short
+$labels['jan'] = 'Jan';
+$labels['feb'] = 'Feb';
+$labels['mar'] = 'Mar';
+$labels['apr'] = 'Apr';
+$labels['may'] = 'May';
+$labels['jun'] = 'Jun';
+$labels['jul'] = 'Jul';
+$labels['aug'] = 'Aug';
+$labels['sep'] = 'Sep';
+$labels['oct'] = 'Oct';
+$labels['nov'] = 'Nov';
+$labels['dec'] = 'Dec';
+
+// months long
+$labels['longjan'] = 'January';
+$labels['longfeb'] = 'February';
+$labels['longmar'] = 'March';
+$labels['longapr'] = 'April';
+$labels['longmay'] = 'May';
+$labels['longjun'] = 'June';
+$labels['longjul'] = 'July';
+$labels['longaug'] = 'August';
+$labels['longsep'] = 'September';
+$labels['longoct'] = 'October';
+$labels['longnov'] = 'November';
+$labels['longdec'] = 'December';
+
+$labels['today'] = 'Today';
+
+// toolbar buttons
+$labels['refresh'] = 'Refresh';
+$labels['checkmail'] = 'Check for new messages';
+$labels['compose'] = 'Compose';
+$labels['writenewmessage'] = 'Create a new message';
+$labels['reply'] = 'Reply';
+$labels['replytomessage'] = 'Reply to sender';
+$labels['replytoallmessage'] = 'Reply to list or to sender and all recipients';
+$labels['replyall'] = 'Reply all';
+$labels['replylist'] = 'Reply list';
+$labels['forward'] = 'Forward';
+$labels['forwardinline'] = 'Forward inline';
+$labels['forwardattachment'] = 'Forward as attachment';
+$labels['forwardmessage'] = 'Forward the message';
+$labels['deletemessage'] = 'Delete message';
+$labels['movemessagetotrash'] = 'Move message to trash';
+$labels['printmessage'] = 'Print this message';
+$labels['previousmessage'] = 'Show previous message';
+$labels['firstmessage'] = 'Show first message';
+$labels['nextmessage'] = 'Show next message';
+$labels['lastmessage'] = 'Show last message';
+$labels['backtolist'] = 'Back to message list';
+$labels['viewsource'] = 'Show source';
+$labels['mark'] = 'Mark';
+$labels['markmessages'] = 'Mark messages';
+$labels['markread'] = 'As read';
+$labels['markunread'] = 'As unread';
+$labels['markflagged'] = 'As flagged';
+$labels['markunflagged'] = 'As unflagged';
+$labels['moreactions'] = 'More actions...';
+$labels['more'] = 'More';
+$labels['back'] = 'Back';
+$labels['options'] = 'Options';
+
+$labels['select'] = 'Select';
+$labels['all'] = 'All';
+$labels['none'] = 'None';
+$labels['currpage'] = 'Current page';
+$labels['unread'] = 'Unread';
+$labels['flagged'] = 'Flagged';
+$labels['unanswered'] = 'Unanswered';
+$labels['deleted'] = 'Deleted';
+$labels['undeleted'] = 'Not deleted';
+$labels['invert'] = 'Invert';
+$labels['filter'] = 'Filter';
+$labels['list'] = 'List';
+$labels['threads'] = 'Threads';
+$labels['expand-all'] = 'Expand All';
+$labels['expand-unread'] = 'Expand Unread';
+$labels['collapse-all'] = 'Collapse All';
+$labels['threaded'] = 'Threaded';
+
+$labels['autoexpand_threads'] = 'Expand message threads';
+$labels['do_expand'] = 'all threads';
+$labels['expand_only_unread'] = 'only with unread messages';
+$labels['fromto'] = 'From/To';
+$labels['flag'] = 'Flag';
+$labels['attachment'] = 'Attachment';
+$labels['nonesort'] = 'None';
+$labels['sentdate'] = 'Sent date';
+$labels['arrival'] = 'Arrival date';
+$labels['asc'] = 'ascending';
+$labels['desc'] = 'descending';
+$labels['listcolumns'] = 'List columns';
+$labels['listsorting'] = 'Sorting column';
+$labels['listorder'] = 'Sorting order';
+$labels['listmode'] = 'List view mode';
+
+$labels['folderactions'] = 'Folder actions...';
+$labels['compact'] = 'Compact';
+$labels['empty'] = 'Empty';
+
+$labels['quota'] = 'Disk usage';
+$labels['unknown'] = 'unknown';
+$labels['unlimited'] = 'unlimited';
+
+$labels['quicksearch'] = 'Quick search';
+$labels['resetsearch'] = 'Reset search';
+$labels['searchmod'] = 'Search modifiers';
+$labels['msgtext'] = 'Entire message';
+$labels['body'] = 'Body';
+
+$labels['openinextwin'] = 'Open in new window';
+$labels['emlsave'] = 'Download (.eml)';
+
+// message compose
+$labels['editasnew'] = 'Edit as new';
+$labels['send'] = 'Send';
+$labels['sendmessage'] = 'Send message';
+$labels['savemessage'] = 'Save as draft';
+$labels['addattachment'] = 'Attach a file';
+$labels['charset'] = 'Charset';
+$labels['editortype'] = 'Editor type';
+$labels['returnreceipt'] = 'Return receipt';
+$labels['dsn'] = 'Delivery status notification';
+$labels['mailreplyintro'] = 'On $date, $sender wrote:';
+$labels['originalmessage'] = 'Original Message';
+
+$labels['editidents'] = 'Edit identities';
+$labels['spellcheck'] = 'Spell';
+$labels['checkspelling'] = 'Check spelling';
+$labels['resumeediting'] = 'Resume editing';
+$labels['revertto'] = 'Revert to';
+
+$labels['attach'] = 'Attach';
+$labels['attachments'] = 'Attachments';
+$labels['upload'] = 'Upload';
+$labels['uploadprogress'] = '$percent ($current from $total)';
+$labels['close'] = 'Close';
+$labels['messageoptions'] = 'Message options...';
+
+$labels['low'] = 'Low';
+$labels['lowest'] = 'Lowest';
+$labels['normal'] = 'Normal';
+$labels['high'] = 'High';
+$labels['highest'] = 'Highest';
+
+$labels['nosubject'] = '(no subject)';
+$labels['showimages'] = 'Display images';
+$labels['alwaysshow'] = 'Always show images from $sender';
+$labels['isdraft'] = 'This is a draft message.';
+$labels['andnmore'] = '$nr more...';
+$labels['togglemoreheaders'] = 'Show more message headers';
+$labels['togglefullheaders'] = 'Toggle raw message headers';
+
+$labels['htmltoggle'] = 'HTML';
+$labels['plaintoggle'] = 'Plain text';
+$labels['savesentmessagein'] = 'Save sent message in';
+$labels['dontsave'] = 'don\'t save';
+$labels['maxuploadsize'] = 'Maximum allowed file size is $size';
+
+$labels['addcc'] = 'Add Cc';
+$labels['addbcc'] = 'Add Bcc';
+$labels['addreplyto'] = 'Add Reply-To';
+$labels['addfollowupto'] = 'Add Followup-To';
+
+// mdn
+$labels['mdnrequest'] = 'The sender of this message has asked to be notified when you read this message. Do you wish to notify the sender?';
+$labels['receiptread'] = 'Return Receipt (read)';
+$labels['yourmessage'] = 'This is a Return Receipt for your message';
+$labels['receiptnote'] = 'Note: This receipt only acknowledges that the message was displayed on the recipient\'s computer. There is no guarantee that the recipient has read or understood the message contents.';
+
+// address boook
+$labels['name'] = 'Display Name';
+$labels['firstname'] = 'First Name';
+$labels['surname'] = 'Last Name';
+$labels['middlename'] = 'Middle Name';
+$labels['nameprefix'] = 'Prefix';
+$labels['namesuffix'] = 'Suffix';
+$labels['nickname'] = 'Nickname';
+$labels['jobtitle'] = 'Job Title';
+$labels['department'] = 'Department';
+$labels['gender'] = 'Gender';
+$labels['maidenname'] = 'Maiden Name';
+$labels['email'] = 'Email';
+$labels['phone'] = 'Phone';
+$labels['address'] = 'Address';
+$labels['street'] = 'Street';
+$labels['locality'] = 'City';
+$labels['zipcode'] = 'ZIP Code';
+$labels['region'] = 'State/Province';
+$labels['country'] = 'Country';
+$labels['birthday'] = 'Birthday';
+$labels['anniversary'] = 'Anniversary';
+$labels['website'] = 'Website';
+$labels['instantmessenger'] = 'IM';
+$labels['notes'] = 'Notes';
+$labels['male'] = 'male';
+$labels['female'] = 'female';
+$labels['manager'] = 'Manager';
+$labels['assistant'] = 'Assistant';
+$labels['spouse'] = 'Spouse';
+$labels['allfields'] = 'All fields';
+$labels['search'] = 'Search';
+$labels['advsearch'] = 'Advanced Search';
+$labels['advanced'] = 'Advanced';
+$labels['other'] = 'Other';
+
+$labels['typehome'] = 'Home';
+$labels['typework'] = 'Work';
+$labels['typeother'] = 'Other';
+$labels['typemobile'] = 'Mobile';
+$labels['typemain'] = 'Main';
+$labels['typehomefax'] = 'Home Fax';
+$labels['typeworkfax'] = 'Work Fax';
+$labels['typecar'] = 'Car';
+$labels['typepager'] = 'Pager';
+$labels['typevideo'] = 'Video';
+$labels['typeassistant'] = 'Assistant';
+$labels['typehomepage'] = 'Home Page';
+$labels['typeblog'] = 'Blog';
+$labels['typeprofile'] = 'Profile';
+
+$labels['addfield'] = 'Add field...';
+$labels['addcontact'] = 'Add new contact';
+$labels['editcontact'] = 'Edit contact';
+$labels['contacts'] = 'Contacts';
+$labels['contactproperties'] = 'Contact properties';
+$labels['personalinfo'] = 'Personal information';
+
+$labels['edit'] = 'Edit';
+$labels['cancel'] = 'Cancel';
+$labels['save'] = 'Save';
+$labels['delete'] = 'Delete';
+$labels['rename'] = 'Rename';
+$labels['addphoto'] = 'Add';
+$labels['replacephoto'] = 'Replace';
+$labels['uploadphoto'] = 'Upload photo';
+
+$labels['newcontact'] = 'Create new contact card';
+$labels['deletecontact'] = 'Delete selected contacts';
+$labels['composeto'] = 'Compose mail to';
+$labels['contactsfromto'] = 'Contacts $from to $to of $count';
+$labels['print'] = 'Print';
+$labels['export'] = 'Export';
+$labels['exportvcards'] = 'Export contacts in vCard format';
+$labels['newcontactgroup'] = 'Create new contact group';
+$labels['grouprename'] = 'Rename group';
+$labels['groupdelete'] = 'Delete group';
+$labels['groupremoveselected'] = 'Remove selected contacts from group';
+
+$labels['previouspage'] = 'Show previous page';
+$labels['firstpage'] = 'Show first page';
+$labels['nextpage'] = 'Show next page';
+$labels['lastpage'] = 'Show last page';
+
+$labels['group'] = 'Group';
+$labels['groups'] = 'Groups';
+$labels['personaladrbook'] = 'Personal Addresses';
+
+$labels['searchsave'] = 'Save search';
+$labels['searchdelete'] = 'Delete search';
+
+$labels['import'] = 'Import';
+$labels['importcontacts'] = 'Import contacts';
+$labels['importfromfile'] = 'Import from file:';
+$labels['importtarget'] = 'Add new contacts to address book:';
+$labels['importreplace'] = 'Replace the entire address book';
+$labels['importdesc'] = 'You can upload contacts from an existing address book.<br/>We currently support importing addresses from the <a href="http://en.wikipedia.org/wiki/VCard">vCard</a> or CSV (comma-separated) data format.';
+$labels['done'] = 'Done';
+
+// settings
+$labels['settingsfor'] = 'Settings for';
+$labels['about'] = 'About';
+$labels['preferences'] = 'Preferences';
+$labels['userpreferences'] = 'User preferences';
+$labels['editpreferences'] = 'Edit user preferences';
+
+$labels['identities'] = 'Identities';
+$labels['manageidentities'] = 'Manage identities for this account';
+$labels['newidentity'] = 'New identity';
+
+$labels['newitem'] = 'New item';
+$labels['edititem'] = 'Edit item';
+
+$labels['preferhtml'] = 'Display HTML';
+$labels['defaultcharset'] = 'Default Character Set';
+$labels['htmlmessage'] = 'HTML Message';
+<<<<<<< HEAD
+$labels['messagepart'] = 'Part';
+$labels['digitalsig'] = 'Digital Signature';
+=======
+>>>>>>> parent of be72fb3... Unified attachments filenames handling for message parts without a filename
+$labels['dateformat'] = 'Date format';
+$labels['timeformat'] = 'Time format';
+$labels['prettydate'] = 'Pretty dates';
+$labels['setdefault'] = 'Set default';
+$labels['autodetect'] = 'Auto';
+$labels['language'] = 'Language';
+$labels['timezone'] = 'Time zone';
+$labels['pagesize'] = 'Rows per page';
+$labels['signature'] = 'Signature';
+$labels['dstactive'] = 'Daylight saving time';
+$labels['showinextwin'] = 'Open message in a new window';
+$labels['composeextwin'] = 'Compose in a new window';
+$labels['htmleditor'] = 'Compose HTML messages';
+$labels['htmlonreply'] = 'on reply to HTML message';
+$labels['htmlonreplyandforward'] = 'on forward or reply to HTML message';
+$labels['htmlsignature'] = 'HTML signature';
+$labels['previewpane'] = 'Show preview pane';
+$labels['skin'] = 'Interface skin';
+$labels['logoutclear'] = 'Clear Trash on logout';
+$labels['logoutcompact'] = 'Compact Inbox on logout';
+$labels['uisettings'] = 'User Interface';
+$labels['serversettings'] = 'Server Settings';
+$labels['mailboxview'] = 'Mailbox View';
+$labels['mdnrequests'] = 'On request for return receipt';
+$labels['askuser'] = 'ask me';
+$labels['autosend'] = 'send receipt';
+$labels['autosendknown'] = 'send receipt to my contacts, otherwise ask me';
+$labels['autosendknownignore'] = 'send receipt to my contacts, otherwise ignore';
+$labels['ignore'] = 'ignore';
+$labels['readwhendeleted'] = 'Mark the message as read on delete';
+$labels['flagfordeletion'] = 'Flag the message for deletion instead of delete';
+$labels['skipdeleted'] = 'Do not show deleted messages';
+$labels['deletealways'] = 'If moving messages to Trash fails, delete them';
+$labels['deletejunk'] = 'Directly delete messages in Junk';
+$labels['showremoteimages'] = 'Display remote inline images';
+$labels['fromknownsenders'] = 'from known senders';
+$labels['always'] = 'always';
+$labels['showinlineimages'] = 'Display attached images below the message';
+$labels['autosavedraft'] = 'Automatically save draft';
+$labels['everynminutes'] = 'every $n minute(s)';
+$labels['refreshinterval'] = 'Refresh (check for new messages, etc.)';
+$labels['never'] = 'never';
+$labels['immediately'] = 'immediately';
+$labels['messagesdisplaying'] = 'Displaying Messages';
+$labels['messagescomposition'] = 'Composing Messages';
+$labels['mimeparamfolding'] = 'Attachment names';
+$labels['2231folding'] = 'Full RFC 2231 (Thunderbird)';
+$labels['miscfolding'] = 'RFC 2047/2231 (MS Outlook)';
+$labels['2047folding'] = 'Full RFC 2047 (other)';
+$labels['force7bit'] = 'Use MIME encoding for 8-bit characters';
+$labels['advancedoptions'] = 'Advanced options';
+$labels['focusonnewmessage'] = 'Focus browser window on new message';
+$labels['checkallfolders'] = 'Check all folders for new messages';
+$labels['displaynext'] = 'After message delete/move display the next message';
+$labels['defaultfont'] = 'Default font of HTML message';
+$labels['mainoptions'] = 'Main Options';
+$labels['browseroptions'] = 'Browser Options';
+$labels['section'] = 'Section';
+$labels['maintenance'] = 'Maintenance';
+$labels['newmessage'] = 'New Message';
+$labels['signatureoptions'] = 'Signature Options';
+$labels['whenreplying'] = 'When replying';
+$labels['replyempty'] = 'do not quote the original message';
+$labels['replytopposting'] = 'start new message above the quote';
+$labels['replybottomposting'] = 'start new message below the quote';
+$labels['replyremovesignature'] = 'When replying remove original signature from message';
+$labels['autoaddsignature'] = 'Automatically add signature';
+$labels['newmessageonly'] = 'new message only';
+$labels['replyandforwardonly'] = 'replies and forwards only';
+$labels['replysignaturepos'] = 'When replying or forwarding place signature';
+$labels['belowquote'] = 'below the quote';
+$labels['abovequote'] = 'above the quote';
+$labels['insertsignature'] = 'Insert signature';
+$labels['previewpanemarkread'] = 'Mark previewed messages as read';
+$labels['afternseconds'] = 'after $n seconds';
+$labels['reqmdn'] = 'Always request a return receipt';
+$labels['reqdsn'] = 'Always request a delivery status notification';
+$labels['replysamefolder'] = 'Place replies in the folder of the message being replied to';
+$labels['defaultabook'] = 'Default address book';
+$labels['autocompletesingle'] = 'Skip alternative email addresses in autocompletion';
+$labels['listnamedisplay'] = 'List contacts as';
+$labels['spellcheckbeforesend'] = 'Check spelling before sending a message';
+$labels['spellcheckoptions'] = 'Spellcheck Options';
+$labels['spellcheckignoresyms'] = 'Ignore words with symbols';
+$labels['spellcheckignorenums'] = 'Ignore words with numbers';
+$labels['spellcheckignorecaps'] = 'Ignore words with all letters capitalized';
+$labels['addtodict'] = 'Add to dictionary';
+$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
+$labels['forwardmode'] = 'Messages forwarding';
+$labels['inline'] = 'inline';
+$labels['asattachment'] = 'as attachment';
+
+$labels['folder'] = 'Folder';
+$labels['folders'] = 'Folders';
+$labels['foldername'] = 'Folder name';
+$labels['subscribed'] = 'Subscribed';
+$labels['messagecount'] = 'Messages';
+$labels['create'] = 'Create';
+$labels['createfolder'] = 'Create new folder';
+$labels['managefolders'] = 'Manage folders';
+$labels['specialfolders'] = 'Special Folders';
+$labels['properties'] = 'Properties';
+$labels['folderproperties'] = 'Folder properties';
+$labels['parentfolder'] = 'Parent folder';
+$labels['location'] = 'Location';
+$labels['info'] = 'Information';
+$labels['getfoldersize'] = 'Click to get folder size';
+$labels['changesubscription'] = 'Click to change subscription';
+$labels['foldertype'] = 'Folder Type';
+$labels['personalfolder'] = 'Private Folder';
+$labels['otherfolder'] = 'Other User\'s Folder';
+$labels['sharedfolder'] = 'Public Folder';
+
+$labels['sortby'] = 'Sort by';
+$labels['sortasc'] = 'Sort ascending';
+$labels['sortdesc'] = 'Sort descending';
+$labels['undo'] = 'Undo';
+
+$labels['installedplugins'] = 'Installed plugins';
+$labels['plugin'] = 'Plugin';
+$labels['version'] = 'Version';
+$labels['source'] = 'Source';
+$labels['license'] = 'License';
+$labels['support'] = 'Get support';
+
+// units
+$labels['B'] = 'B';
+$labels['KB'] = 'KB';
+$labels['MB'] = 'MB';
+$labels['GB'] = 'GB';
+
+// character sets
+$labels['unicode'] = 'Unicode';
+$labels['english'] = 'English';
+$labels['westerneuropean'] = 'Western European';
+$labels['easterneuropean'] = 'Eastern European';
+$labels['southeasterneuropean'] = 'South-Eastern European';
+$labels['baltic'] = 'Baltic';
+$labels['cyrillic'] = 'Cyrillic';
+$labels['arabic'] = 'Arabic';
+$labels['greek'] = 'Greek';
+$labels['hebrew'] = 'Hebrew';
+$labels['turkish'] = 'Turkish';
+$labels['nordic'] = 'Nordic';
+$labels['thai'] = 'Thai';
+$labels['celtic'] = 'Celtic';
+$labels['vietnamese'] = 'Vietnamese';
+$labels['japanese'] = 'Japanese';
+$labels['korean'] = 'Korean';
+$labels['chinese'] = 'Chinese';
+
+?>
diff --git a/program/steps/mail/func.inc.orig b/program/steps/mail/func.inc.orig
new file mode 100644
index 000000000..5bae86c10
--- /dev/null
+++ b/program/steps/mail/func.inc.orig
@@ -0,0 +1,1964 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/steps/mail/func.inc |
+ | |
+ | This file is part of the Roundcube Webmail client |
+ | Copyright (C) 2005-2012, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ | PURPOSE: |
+ | Provide webmail functionality and GUI objects |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+*/
+
+// setup some global vars used by mail steps
+$SENT_MBOX = $RCMAIL->config->get('sent_mbox');
+$DRAFTS_MBOX = $RCMAIL->config->get('drafts_mbox');
+$SEARCH_MODS_DEFAULT = array(
+ '*' => array('subject'=>1, 'from'=>1),
+ $SENT_MBOX => array('subject'=>1, 'to'=>1),
+ $DRAFTS_MBOX => array('subject'=>1, 'to'=>1)
+);
+
+// always instantiate storage object (but not connect to server yet)
+$RCMAIL->storage_init();
+
+// set imap properties and session vars
+if (strlen(trim($mbox = get_input_value('_mbox', RCUBE_INPUT_GPC, true))))
+ $RCMAIL->storage->set_folder(($_SESSION['mbox'] = $mbox));
+else if ($RCMAIL->storage)
+ $_SESSION['mbox'] = $RCMAIL->storage->get_folder();
+
+if (!empty($_GET['_page']))
+ $RCMAIL->storage->set_page(($_SESSION['page'] = intval($_GET['_page'])));
+
+// set default sort col/order to session
+if (!isset($_SESSION['sort_col']))
+ $_SESSION['sort_col'] = !empty($CONFIG['message_sort_col']) ? $CONFIG['message_sort_col'] : '';
+if (!isset($_SESSION['sort_order']))
+ $_SESSION['sort_order'] = strtoupper($CONFIG['message_sort_order']) == 'ASC' ? 'ASC' : 'DESC';
+
+// set threads mode
+$a_threading = $RCMAIL->config->get('message_threading', array());
+if (isset($_GET['_threads'])) {
+ if ($_GET['_threads'])
+ $a_threading[$_SESSION['mbox']] = true;
+ else
+ unset($a_threading[$_SESSION['mbox']]);
+ $RCMAIL->user->save_prefs(array('message_threading' => $a_threading));
+}
+$RCMAIL->storage->set_threading($a_threading[$_SESSION['mbox']]);
+
+// set message set for search result
+if (!empty($_REQUEST['_search']) && isset($_SESSION['search'])
+ && $_SESSION['search_request'] == $_REQUEST['_search']
+) {
+ $RCMAIL->storage->set_search_set($_SESSION['search']);
+ $OUTPUT->set_env('search_request', $_REQUEST['_search']);
+ $OUTPUT->set_env('search_text', $_SESSION['last_text_search']);
+}
+
+// set main env variables, labels and page title
+if (empty($RCMAIL->action) || $RCMAIL->action == 'list') {
+ // connect to storage server and trigger error on failure
+ $RCMAIL->storage_connect();
+
+ $mbox_name = $RCMAIL->storage->get_folder();
+
+ if (empty($RCMAIL->action)) {
+ // initialize searching result if search_filter is used
+ if ($_SESSION['search_filter'] && $_SESSION['search_filter'] != 'ALL') {
+ $search_request = md5($mbox_name.$_SESSION['search_filter']);
+
+ $RCMAIL->storage->search($mbox_name, $_SESSION['search_filter'], RCMAIL_CHARSET, rcmail_sort_column());
+ $_SESSION['search'] = $RCMAIL->storage->get_search_set();
+ $_SESSION['search_request'] = $search_request;
+ $OUTPUT->set_env('search_request', $search_request);
+ }
+
+ $search_mods = $RCMAIL->config->get('search_mods', $SEARCH_MODS_DEFAULT);
+ $OUTPUT->set_env('search_mods', $search_mods);
+ }
+
+ $threading = (bool) $RCMAIL->storage->get_threading();
+
+ // set current mailbox and some other vars in client environment
+ $OUTPUT->set_env('mailbox', $mbox_name);
+ $OUTPUT->set_env('pagesize', $RCMAIL->storage->get_pagesize());
+ $OUTPUT->set_env('delimiter', $RCMAIL->storage->get_hierarchy_delimiter());
+ $OUTPUT->set_env('threading', $threading);
+ $OUTPUT->set_env('threads', $threading || $RCMAIL->storage->get_capability('THREAD'));
+ $OUTPUT->set_env('preview_pane_mark_read', $RCMAIL->config->get('preview_pane_mark_read', 0));
+ if ($RCMAIL->storage->get_capability('QUOTA')) {
+ $OUTPUT->set_env('quota', true);
+ }
+
+ foreach (array('delete_junk','flag_for_deletion','read_when_deleted','skip_deleted','display_next','message_extwin','compose_extwin','forward_attachment') as $prop) {
+ if ($CONFIG[$prop])
+ $OUTPUT->set_env($prop, true);
+ }
+
+ if ($CONFIG['trash_mbox'])
+ $OUTPUT->set_env('trash_mailbox', $CONFIG['trash_mbox']);
+ if ($CONFIG['drafts_mbox'])
+ $OUTPUT->set_env('drafts_mailbox', $CONFIG['drafts_mbox']);
+ if ($CONFIG['junk_mbox'])
+ $OUTPUT->set_env('junk_mailbox', $CONFIG['junk_mbox']);
+
+ if (!empty($_SESSION['browser_caps']))
+ $OUTPUT->set_env('browser_capabilities', $_SESSION['browser_caps']);
+
+ if (!$OUTPUT->ajax_call)
+ $OUTPUT->add_label('checkingmail', 'deletemessage', 'movemessagetotrash',
+ 'movingmessage', 'copyingmessage', 'deletingmessage', 'markingmessage',
+ 'copy', 'move', 'quota');
+
+ $OUTPUT->set_pagetitle(rcmail_localize_foldername($RCMAIL->storage->mod_folder($mbox_name)));
+}
+
+/**
+ * Returns 'to' if current folder is configured Sent or Drafts
+ * or their subfolders, otherwise returns 'from'.
+ *
+ * @return string Column name
+ */
+function rcmail_message_list_smart_column_name()
+{
+ global $RCMAIL;
+
+ $delim = $RCMAIL->storage->get_hierarchy_delimiter();
+ $mbox = $RCMAIL->storage->get_folder();
+ $sent_mbox = $RCMAIL->config->get('sent_mbox');
+ $drafts_mbox = $RCMAIL->config->get('drafts_mbox');
+
+ if (strpos($mbox.$delim, $sent_mbox.$delim) === 0 || strpos($mbox.$delim, $drafts_mbox.$delim) === 0) {
+ return 'to';
+ }
+
+ return 'from';
+}
+
+/**
+ * Returns configured messages list sorting column name
+ * The name is context-sensitive, which means if sorting is set to 'fromto'
+ * it will return 'from' or 'to' according to current folder type.
+ *
+ * @return string Column name
+ */
+function rcmail_sort_column()
+{
+ global $RCMAIL;
+
+ if (isset($_SESSION['sort_col'])) {
+ $column = $_SESSION['sort_col'];
+ }
+ else {
+ $column = $RCMAIL->config->get('message_sort_col');
+ }
+
+ // get name of smart From/To column in folder context
+ if ($column == 'fromto') {
+ $column = rcmail_message_list_smart_column_name();
+ }
+
+ return $column;
+}
+
+/**
+ * Returns configured message list sorting order
+ *
+ * @return string Sorting order (ASC|DESC)
+ */
+function rcmail_sort_order()
+{
+ global $RCMAIL;
+
+ if (isset($_SESSION['sort_order'])) {
+ return $_SESSION['sort_order'];
+ }
+
+ return $RCMAIL->config->get('message_sort_order');
+}
+
+/**
+ * return the message list as HTML table
+ */
+function rcmail_message_list($attrib)
+{
+ global $CONFIG, $OUTPUT;
+
+ // add some labels to client
+ $OUTPUT->add_label('from', 'to');
+
+ // add id to message list table if not specified
+ if (!strlen($attrib['id']))
+ $attrib['id'] = 'rcubemessagelist';
+
+ // define list of cols to be displayed based on parameter or config
+ if (empty($attrib['columns'])) {
+ $a_show_cols = is_array($CONFIG['list_cols']) ? $CONFIG['list_cols'] : array('subject');
+ $OUTPUT->set_env('col_movable', !in_array('list_cols', (array)$CONFIG['dont_override']));
+ }
+ else {
+ $a_show_cols = preg_split('/[\s,;]+/', strip_quotes($attrib['columns']));
+ $attrib['columns'] = $a_show_cols;
+ }
+
+ // save some variables for use in ajax list
+ $_SESSION['list_attrib'] = $attrib;
+ // make sure 'threads' and 'subject' columns are present
+ if (!in_array('subject', $a_show_cols))
+ array_unshift($a_show_cols, 'subject');
+ if (!in_array('threads', $a_show_cols))
+ array_unshift($a_show_cols, 'threads');
+
+ $skin_path = $_SESSION['skin_path'] = $CONFIG['skin_path'];
+
+ // set client env
+ $OUTPUT->add_gui_object('messagelist', $attrib['id']);
+ $OUTPUT->set_env('autoexpand_threads', intval($CONFIG['autoexpand_threads']));
+ $OUTPUT->set_env('sort_col', $_SESSION['sort_col']);
+ $OUTPUT->set_env('sort_order', $_SESSION['sort_order']);
+ $OUTPUT->set_env('messages', array());
+ $OUTPUT->set_env('coltypes', $a_show_cols);
+
+ $OUTPUT->include_script('list.js');
+
+ $thead = '';
+ foreach (rcmail_message_list_head($attrib, $a_show_cols) as $cell)
+ $thead .= html::tag('td', array('class' => $cell['className'], 'id' => $cell['id']), $cell['html']);
+
+ return html::tag('table',
+ $attrib,
+ html::tag('thead', null, html::tag('tr', null, $thead)) .
+ html::tag('tbody', null, ''),
+ array('style', 'class', 'id', 'cellpadding', 'cellspacing', 'border', 'summary'));
+}
+
+
+/**
+ * return javascript commands to add rows to the message list
+ */
+function rcmail_js_message_list($a_headers, $insert_top=FALSE, $a_show_cols=null)
+{
+ global $CONFIG, $RCMAIL, $OUTPUT;
+
+ if (empty($a_show_cols)) {
+ if (!empty($_SESSION['list_attrib']['columns']))
+ $a_show_cols = $_SESSION['list_attrib']['columns'];
+ else
+ $a_show_cols = is_array($CONFIG['list_cols']) ? $CONFIG['list_cols'] : array('subject');
+ }
+ else {
+ if (!is_array($a_show_cols))
+ $a_show_cols = preg_split('/[\s,;]+/', strip_quotes($a_show_cols));
+ $head_replace = true;
+ }
+
+ $mbox = $RCMAIL->storage->get_folder();
+
+ // make sure 'threads' and 'subject' columns are present
+ if (!in_array('subject', $a_show_cols))
+ array_unshift($a_show_cols, 'subject');
+ if (!in_array('threads', $a_show_cols))
+ array_unshift($a_show_cols, 'threads');
+
+ $_SESSION['list_attrib']['columns'] = $a_show_cols;
+
+ // Make sure there are no duplicated columns (#1486999)
+ $a_show_cols = array_unique($a_show_cols);
+
+ // Plugins may set header's list_cols/list_flags and other rcube_message_header variables
+ // and list columns
+ $plugin = $RCMAIL->plugins->exec_hook('messages_list',
+ array('messages' => $a_headers, 'cols' => $a_show_cols));
+
+ $a_show_cols = $plugin['cols'];
+ $a_headers = $plugin['messages'];
+
+ $thead = $head_replace ? rcmail_message_list_head($_SESSION['list_attrib'], $a_show_cols) : NULL;
+
+ // get name of smart From/To column in folder context
+ if (($f = array_search('fromto', $a_show_cols)) !== false) {
+ $smart_col = rcmail_message_list_smart_column_name();
+ }
+
+ $OUTPUT->command('set_message_coltypes', $a_show_cols, $thead, $smart_col);
+
+ if (empty($a_headers))
+ return;
+
+ // remove 'threads', 'attachment', 'flag', 'status' columns, we don't need them here
+ foreach (array('threads', 'attachment', 'flag', 'status', 'priority') as $col) {
+ if (($key = array_search($col, $a_show_cols)) !== FALSE)
+ unset($a_show_cols[$key]);
+ }
+
+ // loop through message headers
+ foreach ($a_headers as $n => $header) {
+ if (empty($header))
+ continue;
+
+ $a_msg_cols = array();
+ $a_msg_flags = array();
+
+ // format each col; similar as in rcmail_message_list()
+ foreach ($a_show_cols as $col) {
+ $col_name = $col == 'fromto' ? $smart_col : $col;
+
+ if (in_array($col_name, array('from', 'to', 'cc', 'replyto')))
+ $cont = rcmail_address_string($header->$col_name, 3, false, null, $header->charset);
+ else if ($col == 'subject') {
+ $cont = trim(rcube_mime::decode_header($header->$col, $header->charset));
+ if (!$cont) $cont = rcube_label('nosubject');
+ $cont = Q($cont);
+ }
+ else if ($col == 'size')
+ $cont = show_bytes($header->$col);
+ else if ($col == 'date')
+ $cont = format_date($header->date);
+ else
+ $cont = Q($header->$col);
+
+ $a_msg_cols[$col] = $cont;
+ }
+
+ $a_msg_flags = array_change_key_case(array_map('intval', (array) $header->flags));
+ if ($header->depth)
+ $a_msg_flags['depth'] = $header->depth;
+ else if ($header->has_children)
+ $roots[] = $header->uid;
+ if ($header->parent_uid)
+ $a_msg_flags['parent_uid'] = $header->parent_uid;
+ if ($header->has_children)
+ $a_msg_flags['has_children'] = $header->has_children;
+ if ($header->unread_children)
+ $a_msg_flags['unread_children'] = $header->unread_children;
+ if ($header->others['list-post'])
+ $a_msg_flags['ml'] = 1;
+ if ($header->priority)
+ $a_msg_flags['prio'] = (int) $header->priority;
+
+ $a_msg_flags['ctype'] = Q($header->ctype);
+ $a_msg_flags['mbox'] = $mbox;
+
+ // merge with plugin result (Deprecated, use $header->flags)
+ if (!empty($header->list_flags) && is_array($header->list_flags))
+ $a_msg_flags = array_merge($a_msg_flags, $header->list_flags);
+ if (!empty($header->list_cols) && is_array($header->list_cols))
+ $a_msg_cols = array_merge($a_msg_cols, $header->list_cols);
+
+ $OUTPUT->command('add_message_row',
+ $header->uid,
+ $a_msg_cols,
+ $a_msg_flags,
+ $insert_top);
+ }
+
+ if ($RCMAIL->storage->get_threading()) {
+ $OUTPUT->command('init_threads', (array) $roots, $mbox);
+ }
+}
+
+
+/*
+ * Creates <THEAD> for message list table
+ */
+function rcmail_message_list_head($attrib, $a_show_cols)
+{
+ global $RCMAIL;
+
+ $skin_path = $_SESSION['skin_path'];
+ $image_tag = html::img(array('src' => "%s%s", 'alt' => "%s"));
+
+ // check to see if we have some settings for sorting
+ $sort_col = $_SESSION['sort_col'];
+ $sort_order = $_SESSION['sort_order'];
+
+ $dont_override = (array)$RCMAIL->config->get('dont_override');
+ $disabled_sort = in_array('message_sort_col', $dont_override);
+ $disabled_order = in_array('message_sort_order', $dont_override);
+
+ $RCMAIL->output->set_env('disabled_sort_col', $disabled_sort);
+ $RCMAIL->output->set_env('disabled_sort_order', $disabled_order);
+
+ // define sortable columns
+ if ($disabled_sort)
+ $a_sort_cols = $sort_col && !$disabled_order ? array($sort_col) : array();
+ else
+ $a_sort_cols = array('subject', 'date', 'from', 'to', 'fromto', 'size', 'cc');
+
+ if (!empty($attrib['optionsmenuicon'])) {
+ $onclick = 'return ' . JS_OBJECT_NAME . ".command('menu-open', 'messagelistmenu')";
+ if ($attrib['optionsmenuicon'] === true || $attrib['optionsmenuicon'] == 'true')
+ $list_menu = html::div(array('onclick' => $onclick, 'class' => 'listmenu',
+ 'id' => 'listmenulink', 'title' => rcube_label('listoptions')));
+ else
+ $list_menu = html::a(array('href' => '#', 'onclick' => $onclick),
+ html::img(array('src' => $skin_path . $attrib['optionsmenuicon'],
+ 'id' => 'listmenulink', 'title' => rcube_label('listoptions')))
+ );
+ }
+ else
+ $list_menu = '';
+
+ $cells = array();
+
+ // get name of smart From/To column in folder context
+ if (($f = array_search('fromto', $a_show_cols)) !== false) {
+ $smart_col = rcmail_message_list_smart_column_name();
+ }
+
+ foreach ($a_show_cols as $col) {
+ // get column name
+ switch ($col) {
+ case 'flag':
+ $col_name = '<span class="flagged">&nbsp;</span>';
+ break;
+ case 'attachment':
+ case 'priority':
+ case 'status':
+ $col_name = '<span class="' . $col .'">&nbsp;</span>';
+ break;
+ case 'threads':
+ $col_name = $list_menu;
+ break;
+ case 'fromto':
+ $col_name = Q(rcube_label($smart_col));
+ break;
+ default:
+ $col_name = Q(rcube_label($col));
+ }
+
+ // make sort links
+ if (in_array($col, $a_sort_cols))
+ $col_name = html::a(array('href'=>"./#sort", 'onclick' => 'return '.JS_OBJECT_NAME.".command('sort','".$col."',this)", 'title' => rcube_label('sortby')), $col_name);
+ else if ($col_name[0] != '<')
+ $col_name = '<span class="' . $col .'">' . $col_name . '</span>';
+
+ $sort_class = $col == $sort_col && !$disabled_order ? " sorted$sort_order" : '';
+ $class_name = $col.$sort_class;
+
+ // put it all together
+ $cells[] = array('className' => $class_name, 'id' => "rcm$col", 'html' => $col_name);
+ }
+
+ return $cells;
+}
+
+
+/**
+ * return an HTML iframe for loading mail content
+ */
+function rcmail_messagecontent_frame($attrib)
+{
+ global $OUTPUT, $RCMAIL;
+
+ if (empty($attrib['id']))
+ $attrib['id'] = 'rcmailcontentwindow';
+
+ $attrib['name'] = $attrib['id'];
+
+ if ($RCMAIL->config->get('preview_pane'))
+ $OUTPUT->set_env('contentframe', $attrib['id']);
+ $OUTPUT->set_env('blankpage', $attrib['src'] ? $OUTPUT->abs_url($attrib['src']) : 'program/resources/blank.gif');
+
+ return $OUTPUT->frame($attrib, true);
+}
+
+
+function rcmail_messagecount_display($attrib)
+{
+ global $RCMAIL;
+
+ if (!$attrib['id'])
+ $attrib['id'] = 'rcmcountdisplay';
+
+ $RCMAIL->output->add_gui_object('countdisplay', $attrib['id']);
+
+ $content = $RCMAIL->action != 'show' ? rcmail_get_messagecount_text() : rcube_label('loading');
+
+ return html::span($attrib, $content);
+}
+
+
+function rcmail_get_messagecount_text($count=NULL, $page=NULL)
+{
+ global $RCMAIL;
+
+ if ($page === NULL) {
+ $page = $RCMAIL->storage->get_page();
+ }
+
+ $page_size = $RCMAIL->storage->get_pagesize();
+ $start_msg = ($page-1) * $page_size + 1;
+
+ if ($count!==NULL)
+ $max = $count;
+ else if ($RCMAIL->action)
+ $max = $RCMAIL->storage->count(NULL, $RCMAIL->storage->get_threading() ? 'THREADS' : 'ALL');
+
+ if ($max==0)
+ $out = rcube_label('mailboxempty');
+ else
+ $out = rcube_label(array('name' => $RCMAIL->storage->get_threading() ? 'threadsfromto' : 'messagesfromto',
+ 'vars' => array('from' => $start_msg,
+ 'to' => min($max, $start_msg + $page_size - 1),
+ 'count' => $max)));
+
+ return Q($out);
+}
+
+
+function rcmail_mailbox_name_display($attrib)
+{
+ global $RCMAIL;
+
+ if (!$attrib['id'])
+ $attrib['id'] = 'rcmmailboxname';
+
+ $RCMAIL->output->add_gui_object('mailboxname', $attrib['id']);
+
+ return html::span($attrib, rcmail_get_mailbox_name_text());
+}
+
+
+function rcmail_get_mailbox_name_text()
+{
+ global $RCMAIL;
+ return rcmail_localize_foldername($RCMAIL->storage->get_folder());
+}
+
+
+function rcmail_send_unread_count($mbox_name, $force=false, $count=null, $mark='')
+{
+ global $RCMAIL;
+
+ $old_unseen = rcmail_get_unseen_count($mbox_name);
+
+ if ($count === null)
+ $unseen = $RCMAIL->storage->count($mbox_name, 'UNSEEN', $force);
+ else
+ $unseen = $count;
+
+ if ($unseen != $old_unseen || ($mbox_name == 'INBOX'))
+ $RCMAIL->output->command('set_unread_count', $mbox_name, $unseen,
+ ($mbox_name == 'INBOX'), $unseen && $mark ? $mark : '');
+
+ rcmail_set_unseen_count($mbox_name, $unseen);
+
+ return $unseen;
+}
+
+
+function rcmail_set_unseen_count($mbox_name, $count)
+{
+ // @TODO: this data is doubled (session and cache tables) if caching is enabled
+
+ // Make sure we have an array here (#1487066)
+ if (!is_array($_SESSION['unseen_count']))
+ $_SESSION['unseen_count'] = array();
+
+ $_SESSION['unseen_count'][$mbox_name] = $count;
+}
+
+
+function rcmail_get_unseen_count($mbox_name)
+{
+ if (is_array($_SESSION['unseen_count']) && array_key_exists($mbox_name, $_SESSION['unseen_count']))
+ return $_SESSION['unseen_count'][$mbox_name];
+ else
+ return null;
+}
+
+
+/**
+ * Sets message is_safe flag according to 'show_images' option value
+ *
+ * @param object rcube_message Message
+ */
+function rcmail_check_safe(&$message)
+{
+ global $RCMAIL;
+
+ if (!$message->is_safe
+ && ($show_images = $RCMAIL->config->get('show_images'))
+ && $message->has_html_part()
+ ) {
+ switch ($show_images) {
+ case 1: // known senders only
+ // get default addressbook, like in addcontact.inc
+ $CONTACTS = $RCMAIL->get_address_book(-1, true);
+
+ if ($CONTACTS) {
+ $result = $CONTACTS->search('email', $message->sender['mailto'], 1, false);
+ if ($result->count) {
+ $message->set_safe(true);
+ }
+ }
+ break;
+
+ case 2: // always
+ $message->set_safe(true);
+ break;
+ }
+ }
+}
+
+
+/**
+ * Cleans up the given message HTML Body (for displaying)
+ *
+ * @param string HTML
+ * @param array Display parameters
+ * @param array CID map replaces (inline images)
+ * @return string Clean HTML
+ */
+function rcmail_wash_html($html, $p, $cid_replaces)
+{
+ global $REMOTE_OBJECTS;
+
+ $p += array('safe' => false, 'inline_html' => true);
+
+ // charset was converted to UTF-8 in rcube_storage::get_message_part(),
+ // change/add charset specification in HTML accordingly,
+ // washtml cannot work without that
+ $meta = '<meta http-equiv="Content-Type" content="text/html; charset='.RCMAIL_CHARSET.'" />';
+
+ // remove old meta tag and add the new one, making sure
+ // that it is placed in the head (#1488093)
+ $html = preg_replace('/<meta[^>]+charset=[a-z0-9-_]+[^>]*>/Ui', '', $html);
+ $html = preg_replace('/(<head[^>]*>)/Ui', '\\1'.$meta, $html, -1, $rcount);
+ if (!$rcount) {
+ $html = '<head>' . $meta . '</head>' . $html;
+ }
+
+ // clean HTML with washhtml by Frederic Motte
+ $wash_opts = array(
+ 'show_washed' => false,
+ 'allow_remote' => $p['safe'],
+ 'blocked_src' => "./program/resources/blocked.gif",
+ 'charset' => RCMAIL_CHARSET,
+ 'cid_map' => $cid_replaces,
+ 'html_elements' => array('body'),
+ );
+
+ if (!$p['inline_html']) {
+ $wash_opts['html_elements'] = array('html','head','title','body');
+ }
+ if ($p['safe']) {
+ $wash_opts['html_elements'][] = 'link';
+ $wash_opts['html_attribs'] = array('rel','type');
+ }
+
+ // overwrite washer options with options from plugins
+ if (isset($p['html_elements']))
+ $wash_opts['html_elements'] = $p['html_elements'];
+ if (isset($p['html_attribs']))
+ $wash_opts['html_attribs'] = $p['html_attribs'];
+
+ // initialize HTML washer
+ $washer = new rcube_washtml($wash_opts);
+
+ if (!$p['skip_washer_form_callback'])
+ $washer->add_callback('form', 'rcmail_washtml_callback');
+
+ // allow CSS styles, will be sanitized by rcmail_washtml_callback()
+ if (!$p['skip_washer_style_callback'])
+ $washer->add_callback('style', 'rcmail_washtml_callback');
+
+ // Remove non-UTF8 characters (#1487813)
+ $html = rc_utf8_clean($html);
+
+ $html = $washer->wash($html);
+ $REMOTE_OBJECTS = $washer->extlinks;
+
+ return $html;
+}
+
+
+/**
+ * Convert the given message part to proper HTML
+ * which can be displayed the message view
+ *
+ * @param object rcube_message_part Message part
+ * @param array Display parameters array
+ * @return string Formatted HTML string
+ */
+function rcmail_print_body($part, $p = array())
+{
+ global $RCMAIL;
+
+ // trigger plugin hook
+ $data = $RCMAIL->plugins->exec_hook('message_part_before',
+ array('type' => $part->ctype_secondary, 'body' => $part->body, 'id' => $part->mime_id)
+ + $p + array('safe' => false, 'plain' => false, 'inline_html' => true));
+
+ // convert html to text/plain
+ if ($data['type'] == 'html' && $data['plain']) {
+ $txt = new rcube_html2text($data['body'], false, true);
+ $body = $txt->get_text();
+ $part->ctype_secondary = 'plain';
+ }
+ // text/html
+ else if ($data['type'] == 'html') {
+ $body = rcmail_wash_html($data['body'], $data, $part->replaces);
+ $part->ctype_secondary = $data['type'];
+ }
+ // text/enriched
+ else if ($data['type'] == 'enriched') {
+ $body = rcube_enriched::to_html($data['body']);
+ $body = rcmail_wash_html($body, $data, $part->replaces);
+ $part->ctype_secondary = 'html';
+ }
+ else {
+ // assert plaintext
+ $body = $part->body;
+ $part->ctype_secondary = $data['type'] = 'plain';
+ }
+
+ // free some memory (hopefully)
+ unset($data['body']);
+
+ // plaintext postprocessing
+ if ($part->ctype_secondary == 'plain')
+ $body = rcmail_plain_body($body, $part->ctype_parameters['format'] == 'flowed');
+
+ // allow post-processing of the message body
+ $data = $RCMAIL->plugins->exec_hook('message_part_after',
+ array('type' => $part->ctype_secondary, 'body' => $body, 'id' => $part->mime_id) + $data);
+
+ return $data['type'] == 'html' ? $data['body'] : html::tag('pre', array(), $data['body']);
+}
+
+
+/**
+ * Handle links and citation marks in plain text message
+ *
+ * @param string Plain text string
+ * @param boolean Text uses format=flowed
+ *
+ * @return string Formatted HTML string
+ */
+function rcmail_plain_body($body, $flowed=false)
+{
+ global $RCMAIL;
+
+ // make links and email-addresses clickable
+ $replacer = new rcmail_string_replacer;
+
+ // search for patterns like links and e-mail addresses and replace with tokens
+ $body = $replacer->replace($body);
+
+ // split body into single lines
+ $body = preg_split('/\r?\n/', $body);
+ $quote_level = 0;
+ $last = -1;
+
+ // find/mark quoted lines...
+ for ($n=0, $cnt=count($body); $n < $cnt; $n++) {
+ if ($body[$n][0] == '>' && preg_match('/^(>+ {0,1})+/', $body[$n], $regs)) {
+ $q = substr_count($regs[0], '>');
+ $body[$n] = substr($body[$n], strlen($regs[0]));
+
+ if ($q > $quote_level) {
+ $body[$n] = $replacer->get_replacement($replacer->add(
+ str_repeat('<blockquote>', $q - $quote_level))) . $body[$n];
+ }
+ else if ($q < $quote_level) {
+ $body[$n] = $replacer->get_replacement($replacer->add(
+ str_repeat('</blockquote>', $quote_level - $q))) . $body[$n];
+ }
+ else if ($flowed) {
+ // previous line is flowed
+ if (isset($body[$last]) && $body[$n]
+ && $body[$last][strlen($body[$last])-1] == ' ') {
+ // merge lines
+ $body[$last] .= $body[$n];
+ unset($body[$n]);
+ }
+ else {
+ $last = $n;
+ }
+ }
+ }
+ else {
+ $q = 0;
+ if ($flowed) {
+ // sig separator - line is fixed
+ if ($body[$n] == '-- ') {
+ $last = $last_sig = $n;
+ }
+ else {
+ // remove space-stuffing
+ if ($body[$n][0] == ' ')
+ $body[$n] = substr($body[$n], 1);
+
+ // previous line is flowed?
+ if (isset($body[$last]) && $body[$n]
+ && $last !== $last_sig
+ && $body[$last][strlen($body[$last])-1] == ' '
+ ) {
+ $body[$last] .= $body[$n];
+ unset($body[$n]);
+ }
+ else {
+ $last = $n;
+ }
+ }
+ if ($quote_level > 0)
+ $body[$last] = $replacer->get_replacement($replacer->add(
+ str_repeat('</blockquote>', $quote_level))) . $body[$last];
+ }
+ else if ($quote_level > 0)
+ $body[$n] = $replacer->get_replacement($replacer->add(
+ str_repeat('</blockquote>', $quote_level))) . $body[$n];
+ }
+
+ $quote_level = $q;
+ }
+
+ $body = join("\n", $body);
+
+ // quote plain text (don't use Q() here, to display entities "as is")
+ $table = get_html_translation_table(HTML_SPECIALCHARS);
+ unset($table['?']);
+ $body = strtr($body, $table);
+
+ // colorize signature (up to <sig_max_lines> lines)
+ $len = strlen($body);
+ $sig_max_lines = $RCMAIL->config->get('sig_max_lines', 15);
+ while (($sp = strrpos($body, "-- \n", $sp ? -$len+$sp-1 : 0)) !== false) {
+ if ($sp == 0 || $body[$sp-1] == "\n") {
+ // do not touch blocks with more that X lines
+ if (substr_count($body, "\n", $sp) < $sig_max_lines)
+ $body = substr($body, 0, max(0, $sp))
+ .'<span class="sig">'.substr($body, $sp).'</span>';
+ break;
+ }
+ }
+
+ // insert url/mailto links and citation tags
+ $body = $replacer->resolve($body);
+
+ return $body;
+}
+
+
+/**
+ * Callback function for washtml cleaning class
+ */
+function rcmail_washtml_callback($tagname, $attrib, $content, $washtml)
+{
+ switch ($tagname) {
+ case 'form':
+ $out = html::div('form', $content);
+ break;
+
+ case 'style':
+ // decode all escaped entities and reduce to ascii strings
+ $stripped = preg_replace('/[^a-zA-Z\(:;]/', '', rcmail_xss_entity_decode($content));
+
+ // now check for evil strings like expression, behavior or url()
+ if (!preg_match('/expression|behavior|javascript:|import[^a]/i', $stripped)) {
+ if (!$washtml->get_config('allow_remote') && stripos($stripped, 'url('))
+ $washtml->extlinks = true;
+ else
+ $out = html::tag('style', array('type' => 'text/css'), $content);
+ break;
+ }
+
+ default:
+ $out = '';
+ }
+
+ return $out;
+}
+
+
+/**
+ * return table with message headers
+ */
+function rcmail_message_headers($attrib, $headers=null)
+ {
+ global $OUTPUT, $MESSAGE, $PRINT_MODE, $RCMAIL;
+ static $sa_attrib;
+
+ // keep header table attrib
+ if (is_array($attrib) && !$sa_attrib && !$attrib['valueof'])
+ $sa_attrib = $attrib;
+ else if (!is_array($attrib) && is_array($sa_attrib))
+ $attrib = $sa_attrib;
+
+ if (!isset($MESSAGE))
+ return FALSE;
+
+ // get associative array of headers object
+ if (!$headers) {
+ $headers_obj = $MESSAGE->headers;
+ $headers = get_object_vars($MESSAGE->headers);
+ }
+ else if (is_object($headers)) {
+ $headers_obj = $headers;
+ $headers = get_object_vars($headers_obj);
+ }
+ else {
+ $headers_obj = rcube_message_header::from_array($headers);
+ }
+
+ // show these headers
+ $standard_headers = array('subject', 'from', 'sender', 'to', 'cc', 'bcc', 'replyto',
+ 'mail-reply-to', 'mail-followup-to', 'date', 'priority');
+ $exclude_headers = $attrib['exclude'] ? explode(',', $attrib['exclude']) : array();
+ $output_headers = array();
+
+ foreach ($standard_headers as $hkey) {
+ $ishtml = false;
+
+ if ($headers[$hkey])
+ $value = $headers[$hkey];
+ else if ($headers['others'][$hkey])
+ $value = $headers['others'][$hkey];
+ else
+ continue;
+
+ if (in_array($hkey, $exclude_headers))
+ continue;
+
+ $header_title = rcube_label(preg_replace('/(^mail-|-)/', '', $hkey));
+
+ if ($hkey == 'date') {
+ if ($PRINT_MODE)
+ $header_value = format_date($value, $RCMAIL->config->get('date_long', 'x'));
+ else
+ $header_value = format_date($value);
+ }
+ else if ($hkey == 'priority') {
+ if ($value) {
+ $header_value = html::span('prio' . $value, rcmail_localized_priority($value));
+ }
+ else
+ continue;
+ }
+ else if ($hkey == 'replyto') {
+ if ($headers['replyto'] != $headers['from']) {
+ $header_value = rcmail_address_string($value, $attrib['max'], true, $attrib['addicon'], $headers['charset'], $header_title);
+ $ishtml = true;
+ }
+ else
+ continue;
+ }
+ else if ($hkey == 'mail-reply-to') {
+ if ($headers['mail-replyto'] != $headers['reply-to']
+ && $headers['reply-to'] != $headers['from']
+ ) {
+ $header_value = rcmail_address_string($value, $attrib['max'], true, $attrib['addicon'], $headers['charset'], $header_title);
+ $ishtml = true;
+ }
+ else
+ continue;
+ }
+ else if ($hkey == 'sender') {
+ if ($headers['sender'] != $headers['from']) {
+ $header_value = rcmail_address_string($value, $attrib['max'], true, $attrib['addicon'], $headers['charset'], $header_title);
+ $ishtml = true;
+ }
+ else
+ continue;
+ }
+ else if ($hkey == 'mail-followup-to') {
+ $header_value = rcmail_address_string($value, $attrib['max'], true, $attrib['addicon'], $headers['charset'], $header_title);
+ $ishtml = true;
+ }
+ else if (in_array($hkey, array('from', 'to', 'cc', 'bcc'))) {
+ $header_value = rcmail_address_string($value, $attrib['max'], true, $attrib['addicon'], $headers['charset'], $header_title);
+ $ishtml = true;
+ }
+ else if ($hkey == 'subject' && empty($value))
+ $header_value = rcube_label('nosubject');
+ else
+ $header_value = trim(rcube_mime::decode_header($value, $headers['charset']));
+
+ $output_headers[$hkey] = array(
+ 'title' => $header_title,
+ 'value' => $header_value,
+ 'raw' => $value,
+ 'html' => $ishtml,
+ );
+ }
+
+ $plugin = $RCMAIL->plugins->exec_hook('message_headers_output',
+ array('output' => $output_headers, 'headers' => $headers_obj, 'exclude' => $exclude_headers));
+
+ // single header value is requested
+ if (!empty($attrib['valueof']))
+ return Q($plugin['output'][$attrib['valueof']]['value'], ($attrib['valueof'] == 'subject' ? 'strict' : 'show'));
+
+ // compose html table
+ $table = new html_table(array('cols' => 2));
+
+ foreach ($plugin['output'] as $hkey => $row) {
+ $table->add(array('class' => 'header-title'), Q($row['title']));
+ $table->add(array('class' => 'header '.$hkey), $row['html'] ? $row['value'] : Q($row['value'], ($hkey == 'subject' ? 'strict' : 'show')));
+ }
+
+ return $table->show($attrib);
+}
+
+/**
+ * Convert Priority header value into a localized string
+ */
+function rcmail_localized_priority($value)
+{
+ $labels_map = array(
+ '1' => 'highest',
+ '2' => 'high',
+ '3' => 'normal',
+ '4' => 'low',
+ '5' => 'lowest',
+ );
+
+ if ($value && $labels_map[$value])
+ return rcube_label($labels_map[$value]);
+
+ return '';
+}
+
+/**
+ * return block to show full message headers
+ */
+function rcmail_message_full_headers($attrib, $headers=NULL)
+{
+ global $OUTPUT;
+
+ $html = html::div(array('id' => "all-headers", 'class' => "all", 'style' => 'display:none'), html::div(array('id' => 'headers-source'), ''));
+ $html .= html::div(array('class' => "more-headers show-headers", 'onclick' => "return ".JS_OBJECT_NAME.".command('show-headers','',this)", 'title' => rcube_label('togglefullheaders')), '');
+
+ $OUTPUT->add_gui_object('all_headers_row', 'all-headers');
+ $OUTPUT->add_gui_object('all_headers_box', 'headers-source');
+
+ return html::div($attrib, $html);
+}
+
+
+/**
+ * Handler for the 'messagebody' GUI object
+ *
+ * @param array Named parameters
+ * @return string HTML content showing the message body
+ */
+function rcmail_message_body($attrib)
+{
+ global $CONFIG, $OUTPUT, $MESSAGE, $RCMAIL, $REMOTE_OBJECTS;
+
+ if (!is_array($MESSAGE->parts) && empty($MESSAGE->body))
+ return '';
+
+ if (!$attrib['id'])
+ $attrib['id'] = 'rcmailMsgBody';
+
+ $safe_mode = $MESSAGE->is_safe || intval($_GET['_safe']);
+ $out = '';
+
+ $header_attrib = array();
+ foreach ($attrib as $attr => $value)
+ if (preg_match('/^headertable([a-z]+)$/i', $attr, $regs))
+ $header_attrib[$regs[1]] = $value;
+
+ if (!empty($MESSAGE->parts)) {
+ foreach ($MESSAGE->parts as $i => $part) {
+ if ($part->type == 'headers') {
+ $out .= html::div('message-partheaders', rcmail_message_headers(sizeof($header_attrib) ? $header_attrib : null, $part->headers));
+ }
+ else if ($part->type == 'content') {
+ // unsapported
+ if ($part->realtype) {
+ if ($part->realtype == 'multipart/encrypted') {
+ $out .= html::span('part-notice', rcube_label('encryptedmessage'));
+ }
+ continue;
+ }
+ else if (!$part->size) {
+ continue;
+ }
+ // Check if we have enough memory to handle the message in it
+ // #1487424: we need up to 10x more memory than the body
+ else if (!rcmail_mem_check($part->size * 10)) {
+ $out .= html::span('part-notice', rcube_label('messagetoobig'). ' '
+ . html::a('?_task=mail&_action=get&_download=1&_uid='.$MESSAGE->uid.'&_part='.$part->mime_id
+ .'&_mbox='. urlencode($RCMAIL->storage->get_folder()), rcube_label('download')));
+ continue;
+ }
+
+ if (empty($part->ctype_parameters) || empty($part->ctype_parameters['charset']))
+ $part->ctype_parameters['charset'] = $MESSAGE->headers->charset;
+
+ // fetch part if not available
+ if (!isset($part->body))
+ $part->body = $MESSAGE->get_part_content($part->mime_id);
+
+ // extract headers from message/rfc822 parts
+ if ($part->mimetype == 'message/rfc822') {
+ $msgpart = rcube_mime::parse_message($part->body);
+ if (!empty($msgpart->headers)) {
+ $part = $msgpart;
+ $out .= html::div('message-partheaders', rcmail_message_headers(sizeof($header_attrib) ? $header_attrib : null, $part->headers));
+ }
+ }
+
+ // message is cached but not exists (#1485443), or other error
+ if ($part->body === false) {
+ rcmail_message_error($MESSAGE->uid);
+ }
+
+ $plugin = $RCMAIL->plugins->exec_hook('message_body_prefix', array(
+ 'part' => $part, 'prefix' => ''));
+
+ $body = rcmail_print_body($part, array('safe' => $safe_mode, 'plain' => !$CONFIG['prefer_html']));
+
+ if ($part->ctype_secondary == 'html') {
+ $body = rcmail_html4inline($body, $attrib['id'], 'rcmBody', $attrs, $safe_mode);
+ $div_attr = array('class' => 'message-htmlpart');
+ $style = array();
+
+ if (!empty($attrs)) {
+ foreach ($attrs as $a_idx => $a_val)
+ $style[] = $a_idx . ': ' . $a_val;
+ if (!empty($style))
+ $div_attr['style'] = implode('; ', $style);
+ }
+
+ $out .= html::div($div_attr, $plugin['prefix'] . $body);
+ }
+ else
+ $out .= html::div('message-part', $plugin['prefix'] . $body);
+ }
+ }
+ }
+ else {
+ // Check if we have enough memory to handle the message in it
+ // #1487424: we need up to 10x more memory than the body
+ if (!rcmail_mem_check(strlen($MESSAGE->body) * 10)) {
+ $out .= html::span('part-notice', rcube_label('messagetoobig'). ' '
+ . html::a('?_task=mail&_action=get&_download=1&_uid='.$MESSAGE->uid.'&_part=0'
+ .'&_mbox='. urlencode($RCMAIL->storage->get_folder()), rcube_label('download')));
+ }
+ else {
+ $plugin = $RCMAIL->plugins->exec_hook('message_body_prefix', array(
+ 'part' => $MESSAGE, 'prefix' => ''));
+
+ $out .= html::div('message-part', $plugin['prefix'] . html::tag('pre', array(),
+ rcmail_plain_body(Q($MESSAGE->body, 'strict', false))));
+ }
+ }
+
+ // list images after mail body
+ if ($RCMAIL->config->get('inline_images', true) && !empty($MESSAGE->attachments)) {
+ $thumbnail_size = $RCMAIL->config->get('image_thumbnail_size', 240);
+ $client_mimetypes = (array)$RCMAIL->config->get('client_mimetypes');
+
+ foreach ($MESSAGE->attachments as $attach_prop) {
+ // skip inline images
+ if ($attach_prop->content_id && $attach_prop->disposition == 'inline') {
+ continue;
+ }
+
+ // Content-Type: image/*...
+ if ($mimetype = rcmail_part_image_type($attach_prop)) {
+ // display thumbnails
+ if ($thumbnail_size) {
+ $show_link = array(
+ 'href' => $MESSAGE->get_part_url($attach_prop->mime_id, false),
+ 'onclick' => sprintf(
+ 'return %s.command(\'load-attachment\',{part:\'%s\', mimetype:\'%s\'},this)',
+ JS_OBJECT_NAME,
+ $attach_prop->mime_id,
+ $mimetype)
+ );
+ $out .= html::p('image-attachment',
+ html::a($show_link + array('class' => 'image-link', 'style' => sprintf('width:%dpx', $thumbnail_size)),
+ html::img(array(
+ 'class' => 'image-thumbnail',
+ 'src' => $MESSAGE->get_part_url($attach_prop->mime_id, true) . '&_thumb=1',
+ 'title' => $attach_prop->filename,
+ 'alt' => $attach_prop->filename,
+ 'style' => sprintf('max-width:%dpx; max-height:%dpx', $thumbnail_size, $thumbnail_size),
+ ))
+ ) .
+ html::span('image-filename', Q($attach_prop->filename)) .
+ html::span('image-filesize', Q($RCMAIL->message_part_size($attach_prop))) .
+ html::span('attachment-links',
+ (in_array($mimetype, $client_mimetypes) ? html::a($show_link, rcube_label('showattachment')) . '&nbsp;' : '') .
+ html::a($show_link['href'] . '&_download=1', rcube_label('download'))
+ ) .
+ html::br(array('style' => 'clear:both'))
+ );
+ }
+ else {
+ $out .= html::tag('fieldset', 'image-attachment',
+ html::tag('legend', 'image-filename', Q($attach_prop->filename)) .
+ html::p(array('align' => "center"),
+ html::img(array(
+ 'src' => $MESSAGE->get_part_url($attach_prop->mime_id, true),
+ 'title' => $attach_prop->filename,
+ 'alt' => $attach_prop->filename,
+ )))
+ );
+ }
+ }
+ }
+ }
+
+ // tell client that there are blocked remote objects
+ if ($REMOTE_OBJECTS && !$safe_mode)
+ $OUTPUT->set_env('blockedobjects', true);
+
+ return html::div($attrib, $out);
+}
+
+function rcmail_part_image_type($part)
+{
+ $rcmail = rcmail::get_instance();
+
+ // Skip TIFF images if browser doesn't support this format...
+ $tiff_support = !empty($_SESSION['browser_caps']) && !empty($_SESSION['browser_caps']['tif']);
+ // until we can convert them to JPEG
+ $tiff_support = $tiff_support || $rcmail->config->get('im_convert_path');
+
+ // Content-type regexp
+ $mime_regex = $tiff_support ? '/^image\//i' : '/^image\/(?!tif)/i';
+
+ // Content-Type: image/*...
+ if (preg_match($mime_regex, $part->mimetype)) {
+ return rcmail_fix_mimetype($part->mimetype);
+ }
+
+ // Many clients use application/octet-stream, we'll detect mimetype
+ // by checking filename extension
+
+ // Supported image filename extensions to image type map
+ $types = array(
+ 'jpg' => 'image/jpeg',
+ 'jpeg' => 'image/jpeg',
+ 'png' => 'image/png',
+ 'gif' => 'image/gif',
+ 'bmp' => 'image/bmp',
+ );
+ if ($tiff_support) {
+ $types['tif'] = 'image/tiff';
+ $types['tiff'] = 'image/tiff';
+ }
+
+ if ($part->filename
+ && preg_match('/^application\/octet-stream$/i', $part->mimetype)
+ && preg_match('/\.([^.]+)$/i', $part->filename, $m)
+ && ($extension = strtolower($m[1]))
+ && isset($types[$extension])
+ ) {
+ return $types[$extension];
+ }
+}
+
+
+/**
+ * modify a HTML message that it can be displayed inside a HTML page
+ */
+function rcmail_html4inline($body, $container_id, $body_id='', &$attributes=null, $allow_remote=false)
+{
+ $last_style_pos = 0;
+ $cont_id = $container_id.($body_id ? ' div.'.$body_id : '');
+
+ // find STYLE tags
+ while (($pos = stripos($body, '<style', $last_style_pos)) && ($pos2 = stripos($body, '</style>', $pos)))
+ {
+ $pos = strpos($body, '>', $pos) + 1;
+ $len = $pos2 - $pos;
+
+ // replace all css definitions with #container [def]
+ $styles = substr($body, $pos, $len);
+ $styles = rcmail_mod_css_styles($styles, $cont_id, $allow_remote);
+
+ $body = substr_replace($body, $styles, $pos, $len);
+ $last_style_pos = $pos2 + strlen($styles) - $len;
+ }
+
+ // modify HTML links to open a new window if clicked
+ $GLOBALS['rcmail_html_container_id'] = $container_id;
+ $body = preg_replace_callback('/<(a|link|area)\s+([^>]+)>/Ui', 'rcmail_alter_html_link', $body);
+ unset($GLOBALS['rcmail_html_container_id']);
+
+ $body = preg_replace(array(
+ // add comments arround html and other tags
+ '/(<!DOCTYPE[^>]*>)/i',
+ '/(<\?xml[^>]*>)/i',
+ '/(<\/?html[^>]*>)/i',
+ '/(<\/?head[^>]*>)/i',
+ '/(<title[^>]*>.*<\/title>)/Ui',
+ '/(<\/?meta[^>]*>)/i',
+ // quote <? of php and xml files that are specified as text/html
+ '/<\?/',
+ '/\?>/',
+ // replace <body> with <div>
+ '/<body([^>]*)>/i',
+ '/<\/body>/i',
+ ),
+ array(
+ '<!--\\1-->',
+ '<!--\\1-->',
+ '<!--\\1-->',
+ '<!--\\1-->',
+ '<!--\\1-->',
+ '<!--\\1-->',
+ '&lt;?',
+ '?&gt;',
+ '<div class="'.$body_id.'"\\1>',
+ '</div>',
+ ),
+ $body);
+
+ $attributes = array();
+
+ // Handle body attributes that doesn't play nicely with div elements
+ $regexp = '/<div class="' . preg_quote($body_id, '/') . '"([^>]*)/';
+ if (preg_match($regexp, $body, $m)) {
+ $attrs = $m[0];
+ // Get bgcolor, we'll set it as background-color of the message container
+ if ($m[1] && preg_match('/bgcolor=["\']*([a-z0-9#]+)["\']*/', $attrs, $mb)) {
+ $attributes['background-color'] = $mb[1];
+ $attrs = preg_replace('/bgcolor=["\']*([a-z0-9#]+)["\']*/', '', $attrs);
+ }
+ // Get background, we'll set it as background-image of the message container
+ if ($m[1] && preg_match('/background=["\']*([^"\'>\s]+)["\']*/', $attrs, $mb)) {
+ $attributes['background-image'] = 'url('.$mb[1].')';
+ $attrs = preg_replace('/background=["\']*([^"\'>\s]+)["\']*/', '', $attrs);
+ }
+ if (!empty($attributes)) {
+ $body = preg_replace($regexp, rtrim($attrs), $body, 1);
+ }
+
+ // handle body styles related to background image
+ if ($attributes['background-image']) {
+ // get body style
+ if (preg_match('/#'.preg_quote($cont_id, '/').'\s+\{([^}]+)}/i', $body, $m)) {
+ // get background related style
+ if (preg_match_all('/(background-position|background-repeat)\s*:\s*([^;]+);/i', $m[1], $ma, PREG_SET_ORDER)) {
+ foreach ($ma as $style)
+ $attributes[$style[1]] = $style[2];
+ }
+ }
+ }
+ }
+ // make sure there's 'rcmBody' div, we need it for proper css modification
+ // its name is hardcoded in rcmail_message_body() also
+ else {
+ $body = '<div class="' . $body_id . '">' . $body . '</div>';
+ }
+
+ return $body;
+}
+
+
+/**
+ * parse link attributes and set correct target
+ */
+function rcmail_alter_html_link($matches)
+{
+ global $RCMAIL;
+
+ // Support unicode/punycode in top-level domain part
+ $EMAIL_PATTERN = '([a-z0-9][a-z0-9\-\.\+\_]*@[^&@"\'.][^@&"\']*\\.([^\\x00-\\x40\\x5b-\\x60\\x7b-\\x7f]{2,}|xn--[a-z0-9]{2,}))';
+
+ $tag = $matches[1];
+ $attrib = parse_attrib_string($matches[2]);
+ $end = '>';
+
+ // Remove non-printable characters in URL (#1487805)
+ if ($attrib['href'])
+ $attrib['href'] = preg_replace('/[\x00-\x1F]/', '', $attrib['href']);
+
+ if ($tag == 'link' && preg_match('/^https?:\/\//i', $attrib['href'])) {
+ $tempurl = 'tmp-' . md5($attrib['href']) . '.css';
+ $_SESSION['modcssurls'][$tempurl] = $attrib['href'];
+ $attrib['href'] = $RCMAIL->url(array('task' => 'utils', 'action' => 'modcss', 'u' => $tempurl, 'c' => $GLOBALS['rcmail_html_container_id']));
+ $end = ' />';
+ }
+ else if (preg_match('/^mailto:'.$EMAIL_PATTERN.'(\?[^"\'>]+)?/i', $attrib['href'], $mailto)) {
+ $attrib['href'] = $mailto[0];
+ $attrib['onclick'] = sprintf(
+ "return %s.command('compose','%s',this)",
+ JS_OBJECT_NAME,
+ JQ($mailto[1].$mailto[3]));
+ }
+ else if (empty($attrib['href']) && !$attrib['name']) {
+ $attrib['href'] = './#NOP';
+ $attrib['onclick'] = 'return false';
+ }
+ else if (!empty($attrib['href']) && $attrib['href'][0] != '#') {
+ $attrib['target'] = '_blank';
+ }
+
+ // allowed attributes for a|link|area tags
+ $allow = array('href','name','target','onclick','id','class','style','title',
+ 'rel','type','media','alt','coords','nohref','hreflang','shape');
+
+ return "<$tag" . html::attrib_string($attrib, $allow) . $end;
+}
+
+
+/**
+ * decode address string and re-format it as HTML links
+ */
+function rcmail_address_string($input, $max=null, $linked=false, $addicon=null, $default_charset=null, $title=null)
+{
+ global $RCMAIL, $PRINT_MODE, $CONFIG;
+
+ $a_parts = rcube_mime::decode_address_list($input, null, true, $default_charset);
+
+ if (!sizeof($a_parts))
+ return $input;
+
+ $c = count($a_parts);
+ $j = 0;
+ $out = '';
+ $allvalues = array();
+
+ if ($addicon && !isset($_SESSION['writeable_abook'])) {
+ $_SESSION['writeable_abook'] = $RCMAIL->get_address_sources(true) ? true : false;
+ }
+
+ foreach ($a_parts as $part) {
+ $j++;
+ $name = $part['name'];
+ $mailto = $part['mailto'];
+ $string = $part['string'];
+
+ // IDNA ASCII to Unicode
+ if ($name == $mailto)
+ $name = rcube_idn_to_utf8($name);
+ if ($string == $mailto)
+ $string = rcube_idn_to_utf8($string);
+ $mailto = rcube_idn_to_utf8($mailto);
+
+ if ($PRINT_MODE) {
+ $out .= ($out ? ', ' : '') . sprintf('%s &lt;%s&gt;', Q($name), $mailto);
+ // for printing we display all addresses
+ continue;
+ }
+ else if (check_email($part['mailto'], false)) {
+ if ($linked) {
+ $address = html::a(array(
+ 'href' => 'mailto:'.$mailto,
+ 'onclick' => sprintf("return %s.command('compose','%s',this)", JS_OBJECT_NAME, JQ($mailto)),
+ 'title' => $mailto,
+ 'class' => "rcmContactAddress",
+ ),
+ Q($name ? $name : $mailto));
+ }
+ else {
+ $address = html::span(array('title' => $mailto, 'class' => "rcmContactAddress"),
+ Q($name ? $name : $mailto));
+ }
+
+ if ($addicon && $_SESSION['writeable_abook']) {
+ $address .= html::a(array(
+ 'href' => "#add",
+ 'onclick' => sprintf("return %s.command('add-contact','%s',this)", JS_OBJECT_NAME, JQ($string)),
+ 'title' => rcube_label('addtoaddressbook'),
+ 'class' => 'rcmaddcontact',
+ ),
+ html::img(array(
+ 'src' => $CONFIG['skin_path'] . $addicon,
+ 'alt' => "Add contact",
+ )));
+ }
+ }
+ else {
+ $address = '';
+ if ($name)
+ $address .= Q($name);
+ if ($mailto)
+ $address .= (strlen($address) ? ' ' : '') . sprintf('&lt;%s&gt;', Q($mailto));
+ }
+
+ $address = html::span('adr', $address);
+ $allvalues[] = $address;
+
+ if (!$moreadrs)
+ $out .= ($out ? ', ' : '') . $address;
+
+ if ($max && $j == $max && $c > $j) {
+ if ($linked) {
+ $moreadrs = $c - $j;
+ }
+ else {
+ $out .= '...';
+ break;
+ }
+ }
+ }
+
+ if ($moreadrs) {
+ $out .= ' ' . html::a(array(
+ 'href' => '#more',
+ 'class' => 'morelink',
+ 'onclick' => sprintf("return %s.show_popup_dialog('%s','%s')",
+ JS_OBJECT_NAME,
+ JQ(join(', ', $allvalues)),
+ JQ($title))
+ ),
+ Q(rcube_label(array('name' => 'andnmore', 'vars' => array('nr' => $moreadrs)))));
+ }
+
+ return $out;
+}
+
+
+/**
+ * Wrap text to a given number of characters per line
+ * but respect the mail quotation of replies messages (>).
+ * Finally add another quotation level by prpending the lines
+ * with >
+ *
+ * @param string Text to wrap
+ * @param int The line width
+ * @return string The wrapped text
+ */
+function rcmail_wrap_and_quote($text, $length = 72)
+{
+ // Rebuild the message body with a maximum of $max chars, while keeping quoted message.
+ $max = max(75, $length + 8);
+ $lines = preg_split('/\r?\n/', trim($text));
+ $out = '';
+
+ foreach ($lines as $line) {
+ // don't wrap already quoted lines
+ if ($line[0] == '>')
+ $line = '>' . rtrim($line);
+ else if (mb_strlen($line) > $max) {
+ $newline = '';
+ foreach(explode("\n", rc_wordwrap($line, $length - 2)) as $l) {
+ if (strlen($l))
+ $newline .= '> ' . $l . "\n";
+ else
+ $newline .= ">\n";
+ }
+ $line = rtrim($newline);
+ }
+ else
+ $line = '> ' . $line;
+
+ // Append the line
+ $out .= $line . "\n";
+ }
+
+ return rtrim($out, "\n");
+}
+
+
+function rcmail_draftinfo_encode($p)
+{
+ $parts = array();
+ foreach ($p as $key => $val)
+ $parts[] = $key . '=' . ($key == 'folder' ? base64_encode($val) : $val);
+
+ return join('; ', $parts);
+}
+
+
+function rcmail_draftinfo_decode($str)
+{
+ $info = array();
+ foreach (preg_split('/;\s+/', $str) as $part) {
+ list($key, $val) = explode('=', $part, 2);
+ if ($key == 'folder')
+ $val = base64_decode($val);
+ $info[$key] = $val;
+ }
+
+ return $info;
+}
+
+
+function rcmail_message_part_controls($attrib)
+{
+ global $MESSAGE, $RCMAIL;
+
+ $part = asciiwords(get_input_value('_part', RCUBE_INPUT_GPC));
+ if (!is_object($MESSAGE) || !is_array($MESSAGE->parts) || !($_GET['_uid'] && $_GET['_part']) || !$MESSAGE->mime_parts[$part])
+ return '';
+
+ $part = $MESSAGE->mime_parts[$part];
+ $table = new html_table(array('cols' => 3));
+
+ $filename = $part->filename;
+ if (empty($filename) && $attach_prop->mimetype == 'text/html') {
+ $filename = rcube_label('htmlmessage');
+ }
+
+ if (!empty($filename)) {
+ $table->add('title', Q(rcube_label('filename')));
+ $table->add('header', Q($filename));
+ $table->add('download-link', html::a(array('href' => './?'.str_replace('_frame=', '_download=', $_SERVER['QUERY_STRING'])), Q(rcube_label('download'))));
+ }
+
+ $table->add('title', Q(rcube_label('filesize')));
+ $table->add('header', Q($RCMAIL->message_part_size($part)));
+
+ return $table->show($attrib);
+}
+
+
+
+function rcmail_message_part_frame($attrib)
+{
+ global $MESSAGE;
+
+ $part = $MESSAGE->mime_parts[asciiwords(get_input_value('_part', RCUBE_INPUT_GPC))];
+ $ctype_primary = strtolower($part->ctype_primary);
+
+ $attrib['src'] = './?' . str_replace('_frame=', ($ctype_primary=='text' ? '_embed=' : '_preload='), $_SERVER['QUERY_STRING']);
+
+ return html::iframe($attrib);
+}
+
+
+/**
+ * clear message composing settings
+ */
+function rcmail_compose_cleanup($id)
+{
+ if (!isset($_SESSION['compose_data_'.$id]))
+ return;
+
+ $rcmail = rcmail::get_instance();
+ $rcmail->plugins->exec_hook('attachments_cleanup', array('group' => $id));
+ $rcmail->session->remove('compose_data_'.$id);
+}
+
+
+/**
+ * Send the MDN response
+ *
+ * @param mixed $message Original message object (rcube_message) or UID
+ * @param array $smtp_error SMTP error array (reference)
+ *
+ * @return boolean Send status
+ */
+function rcmail_send_mdn($message, &$smtp_error)
+{
+ global $RCMAIL;
+
+ if (!is_object($message) || !is_a($message, 'rcube_message'))
+ $message = new rcube_message($message);
+
+ if ($message->headers->mdn_to && empty($message->headers->flags['MDNSENT']) &&
+ ($RCMAIL->storage->check_permflag('MDNSENT') || $RCMAIL->storage->check_permflag('*')))
+ {
+ $identity = rcmail_identity_select($message);
+ $sender = format_email_recipient($identity['email'], $identity['name']);
+ $recipient = array_shift(rcube_mime::decode_address_list(
+ $message->headers->mdn_to, 1, true, $message->headers->charset));
+ $mailto = $recipient['mailto'];
+
+ $compose = new Mail_mime("\r\n");
+
+ $compose->setParam('text_encoding', 'quoted-printable');
+ $compose->setParam('html_encoding', 'quoted-printable');
+ $compose->setParam('head_encoding', 'quoted-printable');
+ $compose->setParam('head_charset', RCMAIL_CHARSET);
+ $compose->setParam('html_charset', RCMAIL_CHARSET);
+ $compose->setParam('text_charset', RCMAIL_CHARSET);
+
+ // compose headers array
+ $headers = array(
+ 'Date' => rcmail_user_date(),
+ 'From' => $sender,
+ 'To' => $message->headers->mdn_to,
+ 'Subject' => rcube_label('receiptread') . ': ' . $message->subject,
+ 'Message-ID' => rcmail_gen_message_id(),
+ 'X-Sender' => $identity['email'],
+ 'References' => trim($message->headers->references . ' ' . $message->headers->messageID),
+ );
+
+ if ($agent = $RCMAIL->config->get('useragent'))
+ $headers['User-Agent'] = $agent;
+
+ $body = rcube_label("yourmessage") . "\r\n\r\n" .
+ "\t" . rcube_label("to") . ': ' . rcube_mime::decode_mime_string($message->headers->to, $message->headers->charset) . "\r\n" .
+ "\t" . rcube_label("subject") . ': ' . $message->subject . "\r\n" .
+ "\t" . rcube_label("sent") . ': ' . format_date($message->headers->date, $RCMAIL->config->get('date_long')) . "\r\n" .
+ "\r\n" . rcube_label("receiptnote") . "\r\n";
+
+ $ua = $RCMAIL->config->get('useragent', "Roundcube Webmail (Version ".RCMAIL_VERSION.")");
+ $report = "Reporting-UA: $ua\r\n";
+
+ if ($message->headers->to)
+ $report .= "Original-Recipient: {$message->headers->to}\r\n";
+
+ $report .= "Final-Recipient: rfc822; {$identity['email']}\r\n" .
+ "Original-Message-ID: {$message->headers->messageID}\r\n" .
+ "Disposition: manual-action/MDN-sent-manually; displayed\r\n";
+
+ $compose->headers($headers);
+ $compose->setContentType('multipart/report', array('report-type'=> 'disposition-notification'));
+ $compose->setTXTBody(rc_wordwrap($body, 75, "\r\n"));
+ $compose->addAttachment($report, 'message/disposition-notification', 'MDNPart2.txt', false, '7bit', 'inline');
+
+ $sent = rcmail_deliver_message($compose, $identity['email'], $mailto, $smtp_error, $body_file);
+
+ if ($sent)
+ {
+ $RCMAIL->storage->set_flag($message->uid, 'MDNSENT');
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/**
+ * Detect recipient identity from specified message
+ */
+function rcmail_identity_select($MESSAGE, $identities = null, $compose_mode = 'reply')
+{
+ $a_recipients = array();
+ $a_names = array();
+
+ if ($identities === null) {
+ $identities = rcmail::get_instance()->user->list_identities(null, true);
+ }
+
+ // extract all recipients of the reply-message
+ if (is_object($MESSAGE->headers) && in_array($compose_mode, array('reply', 'forward'))) {
+ $a_to = rcube_mime::decode_address_list($MESSAGE->headers->to, null, true, $MESSAGE->headers->charset);
+ foreach ($a_to as $addr) {
+ if (!empty($addr['mailto'])) {
+ $a_recipients[] = format_email($addr['mailto']);
+ $a_names[] = $addr['name'];
+ }
+ }
+
+ if (!empty($MESSAGE->headers->cc)) {
+ $a_cc = rcube_mime::decode_address_list($MESSAGE->headers->cc, null, true, $MESSAGE->headers->charset);
+ foreach ($a_cc as $addr) {
+ if (!empty($addr['mailto'])) {
+ $a_recipients[] = format_email($addr['mailto']);
+ $a_names[] = $addr['name'];
+ }
+ }
+ }
+ }
+
+ $from_idx = null;
+ $found_idx = null;
+ $default_identity = 0; // default identity is always first on the list
+
+ // Select identity
+ foreach ($identities as $idx => $ident) {
+ // use From header
+ if (in_array($compose_mode, array('draft', 'edit'))) {
+ if ($MESSAGE->headers->from == $ident['ident']) {
+ $from_idx = $idx;
+ break;
+ }
+ }
+ // reply to yourself
+ else if ($compose_mode == 'reply' && $MESSAGE->headers->from == $ident['ident']) {
+ $from_idx = $idx;
+ break;
+ }
+ // use replied message recipients
+ else if (($found = array_search($ident['email_ascii'], $a_recipients)) !== false) {
+ if ($found_idx === null) {
+ $found_idx = $idx;
+ }
+ // match identity name
+ if ($a_names[$found] && $ident['name'] && $a_names[$found] == $ident['name']) {
+ $from_idx = $idx;
+ break;
+ }
+ }
+ }
+
+ // If matching by name+address doesn't found any matches, get first found address (identity)
+ if ($from_idx === null) {
+ $from_idx = $found_idx;
+ }
+
+ // Try Return-Path
+ if ($from_idx === null && ($return_path = $MESSAGE->headers->others['return-path'])) {
+ foreach ($identities as $idx => $ident) {
+ if (strpos($return_path, str_replace('@', '=', $ident['email_ascii']).'@') !== false) {
+ $from_idx = $idx;
+ break;
+ }
+ }
+ }
+
+ // Fallback using Delivered-To
+ if ($from_idx === null && ($delivered_to = $MESSAGE->headers->others['delivered-to'])) {
+ foreach ($identities as $idx => $ident) {
+ if (in_array($ident['email_ascii'], (array)$delivered_to)) {
+ $from_idx = $idx;
+ break;
+ }
+ }
+ }
+
+ // Fallback using Envelope-To
+ if ($from_idx === null && ($envelope_to = $MESSAGE->headers->others['envelope-to'])) {
+ foreach ($identities as $idx => $ident) {
+ if (in_array($ident['email_ascii'], (array)$envelope_to)) {
+ $from_idx = $idx;
+ break;
+ }
+ }
+ }
+
+ return $identities[$from_idx !== null ? $from_idx : $default_identity];
+}
+
+// Fixes some content-type names
+function rcmail_fix_mimetype($name)
+{
+ // Some versions of Outlook create garbage Content-Type:
+ // application/pdf.A520491B_3BF7_494D_8855_7FAC2C6C0608
+ if (preg_match('/^application\/pdf.+/', $name))
+ $name = 'application/pdf';
+
+ // treat image/pjpeg as image/jpeg
+ else if (preg_match('/^image\/p?jpe?g$/', $name))
+ $name = 'image/jpeg';
+
+ return $name;
+}
+
+<<<<<<< HEAD
+// return attachment filename, handle empty filename case
+function rcmail_attachment_name($attachment, $display = false)
+{
+ $filename = $attachment->filename;
+
+ if ($filename === null || $filename === '') {
+ if ($attachment->mimetype == 'text/html') {
+ $filename = rcube_label('htmlmessage');
+ }
+ else {
+ $ext = rcube_mime::get_mime_extensions($attachment->mimetype);
+ $ext = array_shift($ext);
+ $filename = rcube_label('messagepart') . ' ' . $attachment->mime_id;
+ if ($ext) {
+ $filename .= '.' . $ext;
+ }
+ }
+ }
+
+ $filename = preg_replace('[\r\n]', '', $filename);
+
+ // Display smart names for some known mimetypes
+ if ($display) {
+ if (preg_match('/application\/(pgp|pkcs7)-signature/i', $attachment->mimetype)) {
+ $filename = rcube_label('digitalsig');
+ }
+ }
+
+ return $filename;
+}
+
+=======
+>>>>>>> parent of be72fb3... Unified attachments filenames handling for message parts without a filename
+function rcmail_search_filter($attrib)
+{
+ global $OUTPUT, $CONFIG;
+
+ if (!strlen($attrib['id']))
+ $attrib['id'] = 'rcmlistfilter';
+
+ $attrib['onchange'] = JS_OBJECT_NAME.'.filter_mailbox(this.value)';
+
+ /*
+ RFC3501 (6.4.4): 'ALL', 'RECENT',
+ 'ANSWERED', 'DELETED', 'FLAGGED', 'SEEN',
+ 'UNANSWERED', 'UNDELETED', 'UNFLAGGED', 'UNSEEN',
+ 'NEW', // = (RECENT UNSEEN)
+ 'OLD' // = NOT RECENT
+ */
+
+ $select_filter = new html_select($attrib);
+ $select_filter->add(rcube_label('all'), 'ALL');
+ $select_filter->add(rcube_label('unread'), 'UNSEEN');
+ $select_filter->add(rcube_label('flagged'), 'FLAGGED');
+ $select_filter->add(rcube_label('unanswered'), 'UNANSWERED');
+ if (!$CONFIG['skip_deleted']) {
+ $select_filter->add(rcube_label('deleted'), 'DELETED');
+ $select_filter->add(rcube_label('undeleted'), 'UNDELETED');
+ }
+ $select_filter->add(rcube_label('priority').': '.rcube_label('highest'), 'HEADER X-PRIORITY 1');
+ $select_filter->add(rcube_label('priority').': '.rcube_label('high'), 'HEADER X-PRIORITY 2');
+ $select_filter->add(rcube_label('priority').': '.rcube_label('normal'), 'NOT HEADER X-PRIORITY 1 NOT HEADER X-PRIORITY 2 NOT HEADER X-PRIORITY 4 NOT HEADER X-PRIORITY 5');
+ $select_filter->add(rcube_label('priority').': '.rcube_label('low'), 'HEADER X-PRIORITY 4');
+ $select_filter->add(rcube_label('priority').': '.rcube_label('lowest'), 'HEADER X-PRIORITY 5');
+
+ $out = $select_filter->show($_SESSION['search_filter']);
+
+ $OUTPUT->add_gui_object('search_filter', $attrib['id']);
+
+ return $out;
+}
+
+function rcmail_message_error($uid=null)
+{
+ global $RCMAIL;
+
+ // Set env variables for messageerror.html template
+ if ($RCMAIL->action == 'show') {
+ $mbox_name = $RCMAIL->storage->get_folder();
+ $RCMAIL->output->set_env('mailbox', $mbox_name);
+ $RCMAIL->output->set_env('uid', null);
+ }
+ // display error message
+ $RCMAIL->output->show_message('messageopenerror', 'error');
+ // ... display message error page
+ $RCMAIL->output->send('messageerror');
+}
+
+// register UI objects
+$OUTPUT->add_handlers(array(
+ 'mailboxlist' => 'rcmail_mailbox_list',
+ 'messages' => 'rcmail_message_list',
+ 'messagecountdisplay' => 'rcmail_messagecount_display',
+ 'quotadisplay' => 'rcmail_quota_display',
+ 'mailboxname' => 'rcmail_mailbox_name_display',
+ 'messageheaders' => 'rcmail_message_headers',
+ 'messagefullheaders' => 'rcmail_message_full_headers',
+ 'messagebody' => 'rcmail_message_body',
+ 'messagecontentframe' => 'rcmail_messagecontent_frame',
+ 'messagepartframe' => 'rcmail_message_part_frame',
+ 'messagepartcontrols' => 'rcmail_message_part_controls',
+ 'searchfilter' => 'rcmail_search_filter',
+ 'searchform' => array($OUTPUT, 'search_form'),
+));
+
+// register action aliases
+$RCMAIL->register_action_map(array(
+ 'refresh' => 'check_recent.inc',
+ 'preview' => 'show.inc',
+ 'print' => 'show.inc',
+ 'moveto' => 'move_del.inc',
+ 'delete' => 'move_del.inc',
+ 'send' => 'sendmail.inc',
+ 'expunge' => 'folders.inc',
+ 'purge' => 'folders.inc',
+ 'remove-attachment' => 'attachments.inc',
+ 'display-attachment' => 'attachments.inc',
+ 'upload' => 'attachments.inc',
+ 'group-expand' => 'autocomplete.inc',
+));
diff --git a/program/steps/mail/show.inc.orig b/program/steps/mail/show.inc.orig
new file mode 100644
index 000000000..5ca8f66d4
--- /dev/null
+++ b/program/steps/mail/show.inc.orig
@@ -0,0 +1,315 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/steps/mail/show.inc |
+ | |
+ | This file is part of the Roundcube Webmail client |
+ | Copyright (C) 2005-2009, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ | PURPOSE: |
+ | Display a mail message similar as a usual mail application does |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+*/
+
+$PRINT_MODE = $RCMAIL->action=='print' ? TRUE : FALSE;
+
+// Read browser capabilities and store them in session
+if ($caps = get_input_value('_caps', RCUBE_INPUT_GET)) {
+ $browser_caps = array();
+ foreach (explode(',', $caps) as $cap) {
+ $cap = explode('=', $cap);
+ $browser_caps[$cap[0]] = $cap[1];
+ }
+ $_SESSION['browser_caps'] = $browser_caps;
+}
+
+// similar code as in program/steps/mail/get.inc
+if ($uid = get_input_value('_uid', RCUBE_INPUT_GET)) {
+ $MESSAGE = new rcube_message($uid);
+
+ // if message not found (wrong UID)...
+ if (empty($MESSAGE->headers)) {
+ rcmail_message_error($uid);
+ }
+
+ $mbox_name = $RCMAIL->storage->get_folder();
+
+ // show images?
+ rcmail_check_safe($MESSAGE);
+
+ // set message charset as default
+ if (!empty($MESSAGE->headers->charset))
+ $RCMAIL->storage->set_charset($MESSAGE->headers->charset);
+
+ $OUTPUT->set_pagetitle(abbreviate_string($MESSAGE->subject, 128, '...', true));
+
+ // give message uid to the client
+ $OUTPUT->set_env('uid', $MESSAGE->uid);
+ // set environement
+ $OUTPUT->set_env('safemode', $MESSAGE->is_safe);
+ $OUTPUT->set_env('sender', $MESSAGE->sender['string']);
+ $OUTPUT->set_env('permaurl', rcmail_url('show', array('_uid' => $MESSAGE->uid, '_mbox' => $mbox_name)));
+ $OUTPUT->set_env('delimiter', $RCMAIL->storage->get_hierarchy_delimiter());
+ $OUTPUT->set_env('mailbox', $mbox_name);
+ $OUTPUT->set_env('compose_extwin', $RCMAIL->config->get('compose_extwin',false));
+
+ // mimetypes supported by the browser (default settings)
+ $mimetypes = (array)$RCMAIL->config->get('client_mimetypes');
+
+ // Remove unsupported types, which makes that attachment which cannot be
+ // displayed in a browser will be downloaded directly without displaying an overlay page
+ if (empty($_SESSION['browser_caps']['pdf']) && ($key = array_search('application/pdf', $mimetypes)) !== false) {
+ unset($mimetypes[$key]);
+ }
+ if (empty($_SESSION['browser_caps']['flash']) && ($key = array_search('application/x-shockwave-flash', $mimetypes)) !== false) {
+ unset($mimetypes[$key]);
+ }
+ if (empty($_SESSION['browser_caps']['tif']) && ($key = array_search('image/tiff', $mimetypes)) !== false) {
+ // we can convert tiff to jpeg
+ if (!$RCMAIL->config->get('im_convert_path')) {
+ unset($mimetypes[$key]);
+ }
+ }
+
+ $OUTPUT->set_env('mimetypes', $mimetypes);
+
+ if ($CONFIG['drafts_mbox'])
+ $OUTPUT->set_env('drafts_mailbox', $CONFIG['drafts_mbox']);
+ if ($CONFIG['trash_mbox'])
+ $OUTPUT->set_env('trash_mailbox', $CONFIG['trash_mbox']);
+ if ($CONFIG['junk_mbox'])
+ $OUTPUT->set_env('junk_mailbox', $CONFIG['junk_mbox']);
+ if ($CONFIG['delete_junk'])
+ $OUTPUT->set_env('delete_junk', true);
+ if ($CONFIG['flag_for_deletion'])
+ $OUTPUT->set_env('flag_for_deletion', true);
+ if ($CONFIG['read_when_deleted'])
+ $OUTPUT->set_env('read_when_deleted', true);
+ if ($CONFIG['skip_deleted'])
+ $OUTPUT->set_env('skip_deleted', true);
+ if ($CONFIG['display_next'])
+ $OUTPUT->set_env('display_next', true);
+ if ($MESSAGE->headers->others['list-post'])
+ $OUTPUT->set_env('list_post', true);
+ if ($CONFIG['forward_attachment'])
+ $OUTPUT->set_env('forward_attachment', true);
+
+ if (!$OUTPUT->ajax_call)
+ $OUTPUT->add_label('checkingmail', 'deletemessage', 'movemessagetotrash',
+ 'movingmessage', 'deletingmessage', 'markingmessage');
+
+ // check for unset disposition notification
+ if ($MESSAGE->headers->mdn_to
+ && empty($MESSAGE->headers->flags['MDNSENT'])
+ && empty($MESSAGE->headers->flags['SEEN'])
+ && ($RCMAIL->storage->check_permflag('MDNSENT') || $RCMAIL->storage->check_permflag('*'))
+ && $mbox_name != $CONFIG['drafts_mbox']
+ && $mbox_name != $CONFIG['sent_mbox']
+ ) {
+ $mdn_cfg = intval($CONFIG['mdn_requests']);
+
+ if ($mdn_cfg == 1 || (($mdn_cfg == 3 || $mdn_cfg == 4) && rcmail_contact_exists($MESSAGE->sender['mailto']))) {
+ // Send MDN
+ if (rcmail_send_mdn($MESSAGE, $smtp_error))
+ $OUTPUT->show_message('receiptsent', 'confirmation');
+ else if ($smtp_error)
+ $OUTPUT->show_message($smtp_error['label'], 'error', $smtp_error['vars']);
+ else
+ $OUTPUT->show_message('errorsendingreceipt', 'error');
+ }
+ else if ($mdn_cfg != 2 && $mdn_cfg != 4) {
+ // Ask user
+ $OUTPUT->add_label('mdnrequest');
+ $OUTPUT->set_env('mdn_request', true);
+ }
+ }
+
+ if (empty($MESSAGE->headers->flags['SEEN'])
+ && ($RCMAIL->action == 'show' || ($RCMAIL->action == 'preview' && intval($CONFIG['preview_pane_mark_read']) == 0))
+ ) {
+ $RCMAIL->plugins->exec_hook('message_read', array('uid' => $MESSAGE->uid,
+ 'mailbox' => $mbox_name, 'message' => $MESSAGE));
+ }
+}
+
+
+
+function rcmail_message_attachments($attrib)
+{
+ global $PRINT_MODE, $MESSAGE, $RCMAIL;
+
+ $out = $ol = '';
+
+ if (sizeof($MESSAGE->attachments)) {
+ foreach ($MESSAGE->attachments as $attach_prop) {
+<<<<<<< HEAD
+ $filename = rcmail_attachment_name($attach_prop, true);
+=======
+ $filename = $attach_prop->filename;
+ if (empty($filename) && $attach_prop->mimetype == 'text/html') {
+ $filename = rcube_label('htmlmessage');
+ }
+>>>>>>> parent of be72fb3... Unified attachments filenames handling for message parts without a filename
+
+ if ($PRINT_MODE) {
+ $size = $RCMAIL->message_part_size($attach_prop);
+ $ol .= html::tag('li', null, Q(sprintf("%s (%s)", $filename, $size)));
+ }
+ else {
+ if (mb_strlen($filename) > 50) {
+ $filename = abbreviate_string($filename, 50);
+ $title = $filename;
+ }
+ else {
+ $title = '';
+ }
+
+ $ol .= html::tag('li', rcmail_filetype2classname($attach_prop->mimetype, $filename),
+ html::a(array(
+ 'href' => $MESSAGE->get_part_url($attach_prop->mime_id, false),
+ 'onclick' => sprintf(
+ 'return %s.command(\'load-attachment\',{part:\'%s\', mimetype:\'%s\'},this)',
+ JS_OBJECT_NAME,
+ $attach_prop->mime_id,
+ rcmail_fix_mimetype($attach_prop->mimetype)),
+ 'title' => Q($title),
+ ),
+ Q($filename)));
+ }
+ }
+
+ $out = html::tag('ul', $attrib, $ol, html::$common_attrib);
+ }
+
+ return $out;
+}
+
+function rcmail_remote_objects_msg()
+{
+ global $MESSAGE, $RCMAIL;
+
+ $attrib['id'] = 'remote-objects-message';
+ $attrib['class'] = 'notice';
+ $attrib['style'] = 'display: none';
+
+ $msg = Q(rcube_label('blockedimages')) . '&nbsp;';
+ $msg .= html::a(array('href' => "#loadimages", 'onclick' => JS_OBJECT_NAME.".command('load-images')"), Q(rcube_label('showimages')));
+
+ // add link to save sender in addressbook and reload message
+ if ($MESSAGE->sender['mailto'] && $RCMAIL->config->get('show_images') == 1) {
+ $msg .= ' ' . html::a(array('href' => "#alwaysload", 'onclick' => JS_OBJECT_NAME.".command('always-load')", 'style' => "white-space:nowrap"),
+ Q(rcube_label(array('name' => 'alwaysshow', 'vars' => array('sender' => $MESSAGE->sender['mailto'])))));
+ }
+
+ $RCMAIL->output->add_gui_object('remoteobjectsmsg', $attrib['id']);
+ return html::div($attrib, $msg);
+}
+
+function rcmail_message_buttons()
+{
+ global $MESSAGE, $RCMAIL, $CONFIG;
+
+ $mbox = $RCMAIL->storage->get_folder();
+ $delim = $RCMAIL->storage->get_hierarchy_delimiter();
+ $dbox = $CONFIG['drafts_mbox'];
+
+ // the message is not a draft
+ if ($mbox != $dbox && strpos($mbox, $dbox.$delim) !== 0) {
+ return '';
+ }
+
+ $attrib['id'] = 'message-buttons';
+ $attrib['class'] = 'notice';
+
+ $msg = Q(rcube_label('isdraft')) . '&nbsp;';
+ $msg .= html::a(array('href' => "#edit", 'onclick' => JS_OBJECT_NAME.".command('edit')"), Q(rcube_label('edit')));
+
+ return html::div($attrib, $msg);
+}
+
+function rcmail_message_objects($attrib)
+{
+ global $RCMAIL, $MESSAGE;
+
+ if (!$attrib['id'])
+ $attrib['id'] = 'message-objects';
+
+ $content = array(
+ rcmail_message_buttons(),
+ rcmail_remote_objects_msg(),
+ );
+
+ $plugin = $RCMAIL->plugins->exec_hook('message_objects',
+ array('content' => $content, 'message' => $MESSAGE));
+
+ $content = implode("\n", $plugin['content']);
+
+ return html::div($attrib, $content);
+}
+
+function rcmail_contact_exists($email)
+{
+ global $RCMAIL;
+
+ if ($email) {
+ // @TODO: search in all address books?
+ $CONTACTS = $RCMAIL->get_address_book(-1, true);
+ $existing = $CONTACTS->search('email', $email, true, false);
+ if ($existing->count)
+ return true;
+ }
+
+ return false;
+}
+
+function rcmail_message_contactphoto($attrib)
+{
+ global $RCMAIL, $MESSAGE;
+
+ $placeholder = $attrib['placeholder'] ? $RCMAIL->config->get('skin_path') . $attrib['placeholder'] : null;
+ if ($MESSAGE->sender)
+ $photo_img = $RCMAIL->url(array('_task' => 'addressbook', '_action' => 'photo', '_email' => $MESSAGE->sender['mailto'], '_alt' => $placeholder));
+ else
+ $photo_img = $placeholder ? $placeholder : 'program/resources/blank.gif';
+
+ return html::img(array('src' => $photo_img) + $attrib);
+}
+
+
+$OUTPUT->add_handlers(array(
+ 'messageattachments' => 'rcmail_message_attachments',
+ 'mailboxname' => 'rcmail_mailbox_name_display',
+ 'messageobjects' => 'rcmail_message_objects',
+ 'contactphoto' => 'rcmail_message_contactphoto',
+));
+
+
+if ($RCMAIL->action=='print' && $OUTPUT->template_exists('messageprint'))
+ $OUTPUT->send('messageprint', false);
+else if ($RCMAIL->action=='preview' && $OUTPUT->template_exists('messagepreview'))
+ $OUTPUT->send('messagepreview', false);
+else
+ $OUTPUT->send('message', false);
+
+
+// mark message as read
+if ($MESSAGE && $MESSAGE->headers && empty($MESSAGE->headers->flags['SEEN']) &&
+ ($RCMAIL->action == 'show' || ($RCMAIL->action == 'preview' && intval($CONFIG['preview_pane_mark_read']) == 0)))
+{
+ if ($RCMAIL->storage->set_flag($MESSAGE->uid, 'SEEN')) {
+ if ($count = rcmail_get_unseen_count($mbox_name)) {
+ rcmail_set_unseen_count($mbox_name, $count - 1);
+ }
+ }
+}
+
+exit;
+